View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2007 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.tools;
14  
15  import java.text.SimpleDateFormat;
16  import java.util.ArrayList;
17  import java.util.Date;
18  import java.util.List;
19  
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  
23  import org.apache.commons.cli.CommandLine;
24  
25  import com.eviware.soapui.SoapUI;
26  import com.eviware.soapui.impl.wsdl.WsdlProject;
27  import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
28  import com.eviware.soapui.model.mock.MockResult;
29  import com.eviware.soapui.model.mock.MockRunListener;
30  import com.eviware.soapui.model.mock.MockRunner;
31  import com.eviware.soapui.model.mock.MockService;
32  
33  /***
34   * Standalone tool-runner used from maven-plugin, can also be used from command-line (see xdocs) or
35   * directly from other classes.
36   * <p>
37   * For standalone usage, set the project file (with setProjectFile) and other desired properties before
38   * calling run</p> 
39   * 
40   * @author Ole.Matzura
41   */
42  
43  public class SoapUIMockServiceRunner extends AbstractSoapUIRunner
44  {
45  	private String mockService;
46  	private String port;
47  	private String path;
48  	private List<MockRunner> runners = new ArrayList<MockRunner>();
49  	private boolean block;
50  	
51  	public static String TITLE = "soapUI " + SoapUI.SOAPUI_VERSION + " MockService Runner";
52  	
53  
54  	/***
55  	 * Runs the specified MockService in the specified soapUI project file, see soapUI xdocs for details.
56  	 * 
57  	 * @param args
58  	 * @throws Exception
59  	 */
60  
61  	@SuppressWarnings("static-access")
62  	public static void main( String [] args) throws Exception
63  	{
64  		new SoapUIMockServiceRunner().runFromCommandLine( args );
65  	}
66  
67  	public void setMockService(String mockService)
68  	{
69  		this.mockService = mockService;
70  	}
71  
72  	public void setPath( String path )
73  	{
74  		this.path = path;
75  	}
76  
77  	public void setPort( String port )
78  	{
79  		this.port = port;
80  	}
81  
82  	public SoapUIMockServiceRunner()
83  	{
84  		super( TITLE );
85  	}
86  	
87  	public SoapUIMockServiceRunner( String title )
88  	{
89  		super( title );
90  	}
91  	
92  	public boolean runRunner() throws Exception
93  	{
94  		initGroovyLog();
95  		
96  		String projectFile = getProjectFile();
97  		
98  		WsdlProject project = new WsdlProject( projectFile );
99  		if( project.isDisabled() )
100 			throw new Exception( "Failed to load soapUI project file [" + projectFile + "]" );
101 		
102 		if( mockService == null )
103 			log.info( "Running all MockServices in project [" + project.getName() + "]" );
104 		else
105 			log.info( "Running MockService [" + mockService + "] in project [" + project.getName() + "]" );
106 		
107 		log.info( "Press any key to terminate" );
108 		
109 		long startTime = System.nanoTime();
110 		
111 		for( int c = 0; c < project.getMockServiceCount(); c++ )
112 		{
113 			MockService ms = project.getMockServiceAt( c );
114 			if( mockService == null || ms.getName().equals( mockService ))
115 				runMockService( ( WsdlMockService ) ms );
116 		}
117 		
118 		log.info( "Started " + runners.size() + " runner" + ((runners.size() == 1) ? "" : "s" ) );
119 		
120 		if( block )
121 		{
122 			System.out.println( "Press any key to terminate..." );
123 			System.in.read();
124 			for( MockRunner runner : runners )
125 				runner.stop();
126 		}
127 		
128 		long timeTaken = (System.nanoTime()-startTime)/1000000;
129 		log.info( "time taken: " + timeTaken + "ms" );
130 		
131 		return block;
132 	}
133 	
134 	/***
135 	 * Runs the configured tool for the specified interface.. needs to be refactored to use
136 	 * some kind of registry/factory pattern for tools
137 	 * 
138 	 * @param iface
139 	 */
140 	
141 	public void runMockService( WsdlMockService mockService )
142 	{
143 		try
144 		{
145 			if( path != null )
146 				mockService.setPath( path );
147 			
148 			if( port != null )
149 				mockService.setPort( Integer.parseInt( port ));
150 			
151 			mockService.addMockRunListener( new LogListener() );
152 			runners.add( mockService.start() );
153 		}
154 		catch (Exception e)
155 		{
156 			SoapUI.logError( e );
157 		}
158 	}
159 
160    public class LogListener implements MockRunListener
161 	{
162    	private SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
163 		private int responseCount;
164    	
165 		public void onMockRunnerStart( MockRunner mockRunner )
166 		{
167 			log.info( "MockService started on port " + mockRunner.getMockService().getPort() + " at path [" + 
168 						mockRunner.getMockService().getPath() + "]" );
169 		}
170 
171 		public void onMockRunnerStop( MockRunner mockRunner )
172 		{
173 			log.info( "MockService stopped, handled " + responseCount + " requests" );
174 		}
175 
176 		public void onMockResult( MockResult result )
177 		{
178 			responseCount++;
179 			log.info( "Handled request " + responseCount + "; [" + result.getMockResponse().getMockOperation().getName() + 
180 						"] with [" + result.getMockResponse().getName() + "] in [" + result.getTimeTaken() + 
181 						"ms] at [" + dateFormat.format( new Date( result.getTimestamp())) + "]" );
182 		}
183 
184 		public void onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
185 		{
186 		}
187 	}
188 
189 	@Override
190 	protected SoapUIOptions initCommandLineOptions()
191 	{
192 		SoapUIOptions options = new SoapUIOptions( "mockservicerunner" );
193 		options.addOption( "m", true, "Specified the name of the MockService to run" );
194 		options.addOption( "p", true, "Sets the local port to listen on" );
195 		options.addOption( "a", true, "Sets the url path to listen on" );
196 		options.addOption( "s", true, "Sets the soapui-settings.xml file to use" );
197 		options.addOption( "b", false, "Turns off blocking read for termination" );
198 		
199 		return options;
200 	}
201 
202 	@Override
203 	protected boolean processCommandLine( CommandLine cmd )
204 	{
205 		if( cmd.hasOption( "m" ))
206 			setMockService( getCommandLineOptionSubstSpace( cmd, "m") );
207 		
208 		if( cmd.hasOption( "a"))
209 			setPath( getCommandLineOptionSubstSpace( cmd, "a" ) );
210 
211 		if( cmd.hasOption( "p"))
212 			setPort( cmd.getOptionValue( "p" ) );
213 		
214 		if( cmd.hasOption( "s"))
215 			setSettingsFile( getCommandLineOptionSubstSpace( cmd, "s" ));
216 		
217 		setBlock( !cmd.hasOption( 'b' ));
218 		
219 		return true;
220 	}
221 
222 	public void setBlock( boolean block )
223 	{
224 		this.block = block;
225 	}
226 }