1
2
3
4
5
6
7
8
9
10
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 org.apache.commons.cli.CommandLine;
21
22 import com.eviware.soapui.SoapUI;
23 import com.eviware.soapui.impl.wsdl.WsdlProject;
24 import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
25 import com.eviware.soapui.model.mock.MockResult;
26 import com.eviware.soapui.model.mock.MockRunner;
27 import com.eviware.soapui.model.mock.MockService;
28 import com.eviware.soapui.model.project.ProjectFactoryRegistry;
29 import com.eviware.soapui.model.support.MockRunListenerAdapter;
30
31 /***
32 * Standalone tool-runner used from maven-plugin, can also be used from
33 * command-line (see xdocs) or directly from other classes.
34 * <p>
35 * For standalone usage, set the project file (with setProjectFile) and other
36 * desired properties before calling run
37 * </p>
38 *
39 * @author Ole.Matzura
40 */
41
42 public class SoapUIMockServiceRunner extends AbstractSoapUIRunner
43 {
44 private String mockService;
45 private String port;
46 private String path;
47 private List<MockRunner> runners = new ArrayList<MockRunner>();
48 private boolean block;
49 private String projectPassword;
50 private WsdlProject project;
51 private boolean saveAfterRun;
52
53 public static String TITLE = "soapUI " + SoapUI.SOAPUI_VERSION + " MockService Runner";
54
55 /***
56 * Runs the specified MockService in the specified soapUI project file, see
57 * soapUI xdocs for details.
58 *
59 * @param args
60 * @throws Exception
61 */
62
63 public static void main( String[] args ) throws Exception
64 {
65 System.exit( new SoapUIMockServiceRunner().runFromCommandLine( args ));
66 }
67
68 public void setMockService( String mockService )
69 {
70 this.mockService = mockService;
71 }
72
73 public void setPath( String path )
74 {
75 this.path = path;
76 }
77
78 public void setPort( String port )
79 {
80 this.port = port;
81 }
82
83 public SoapUIMockServiceRunner()
84 {
85 super( TITLE );
86 }
87
88 public SoapUIMockServiceRunner( String title )
89 {
90 super( title );
91 }
92
93 public boolean runRunner() throws Exception
94 {
95 initGroovyLog();
96
97 String projectFile = getProjectFile();
98
99
100
101 project = ( WsdlProject )ProjectFactoryRegistry.getProjectFactory( "wsdl" ).createNew( projectFile,
102 getProjectPassword() );
103 if( project.isDisabled() )
104 throw new Exception( "Failed to load soapUI project file [" + projectFile + "]" );
105
106 initProject();
107
108 if( mockService == null )
109 log.info( "Running all MockServices in project [" + project.getName() + "]" );
110 else
111 log.info( "Running MockService [" + mockService + "] in project [" + project.getName() + "]" );
112
113 log.info( "Press any key to terminate" );
114
115 long startTime = System.nanoTime();
116
117 for( int c = 0; c < project.getMockServiceCount(); c++ )
118 {
119 MockService ms = project.getMockServiceAt( c );
120 if( mockService == null || ms.getName().equals( mockService ) )
121 runMockService( ( WsdlMockService )ms );
122 }
123
124 log.info( "Started " + runners.size() + " runner" + ( ( runners.size() == 1 ) ? "" : "s" ) );
125
126 if( block )
127 {
128 System.out.println( "Press any key to terminate..." );
129 while( System.in.available() == 0 )
130 {
131 Thread.sleep( 1000 );
132
133
134 for( int c = 0; c < runners.size(); c++ )
135 {
136 if( !runners.get( c ).isRunning() )
137 {
138 runners.remove( c );
139 c-- ;
140 }
141 }
142
143 if( runners.isEmpty() )
144 break;
145 }
146
147 if( System.in.available() > 0 )
148 System.in.read();
149
150 for( MockRunner runner : runners )
151 runner.stop();
152
153 if( saveAfterRun && !project.isRemote() )
154 {
155 try
156 {
157 project.save();
158 }
159 catch( Throwable t )
160 {
161 log.error( "Failed to save project", t );
162 }
163 }
164 }
165
166 long timeTaken = ( System.nanoTime() - startTime ) / 1000000;
167 log.info( "time taken: " + timeTaken + "ms" );
168
169 exportReports();
170
171 return block;
172 }
173
174 protected void initProject() throws Exception
175 {
176 initProjectProperties( project );
177 }
178
179 protected void exportReports() throws Exception
180 {
181 }
182
183 /***
184 * Runs the specified MockService
185 *
186 * @param mockService
187 */
188
189 public void runMockService( WsdlMockService mockService )
190 {
191 try
192 {
193 if( path != null )
194 mockService.setPath( path );
195
196 if( port != null )
197 mockService.setPort( Integer.parseInt( port ) );
198
199 mockService.addMockRunListener( new LogListener() );
200 runners.add( mockService.start() );
201 }
202 catch( Exception e )
203 {
204 SoapUI.logError( e );
205 }
206 }
207
208 public class LogListener extends MockRunListenerAdapter
209 {
210 private SimpleDateFormat dateFormat = new SimpleDateFormat( "yyyy-MM-dd HH:mm:ss.SSS" );
211 private int responseCount;
212
213 public void onMockRunnerStart( MockRunner mockRunner )
214 {
215 log.info( "MockService started on port " + mockRunner.getMockService().getPort() + " at path ["
216 + mockRunner.getMockService().getPath() + "]" );
217 }
218
219 public void onMockRunnerStop( MockRunner mockRunner )
220 {
221 log.info( "MockService stopped, handled " + responseCount + " requests" );
222 }
223
224 public void onMockResult( MockResult result )
225 {
226 responseCount++ ;
227 log.info( "Handled request " + responseCount + "; [" + result.getMockResponse().getMockOperation().getName()
228 + "] with [" + result.getMockResponse().getName() + "] in [" + result.getTimeTaken() + "ms] at ["
229 + dateFormat.format( new Date( result.getTimestamp() ) ) + "]" );
230 }
231 }
232
233 @Override
234 protected SoapUIOptions initCommandLineOptions()
235 {
236 SoapUIOptions options = new SoapUIOptions( "mockservicerunner" );
237 options.addOption( "m", true, "Specified the name of the MockService to run" );
238 options.addOption( "p", true, "Sets the local port to listen on" );
239 options.addOption( "a", true, "Sets the url path to listen on" );
240 options.addOption( "s", true, "Sets the soapui-settings.xml file to use" );
241 options.addOption( "b", false, "Turns off blocking read for termination" );
242 options.addOption( "x", true, "Sets project password for decryption if project is encrypted" );
243 options.addOption( "v", true, "Sets password for soapui-settings.xml file" );
244 options.addOption( "D", true, "Sets system property with name=value" );
245 options.addOption( "G", true, "Sets global property with name=value" );
246 options.addOption( "P", true, "Sets or overrides project property with name=value" );
247 options.addOption( "S", false, "Saves the project after running the mockService(s)" );
248
249 return options;
250 }
251
252 @Override
253 protected boolean processCommandLine( CommandLine cmd )
254 {
255 if( cmd.hasOption( "m" ) )
256 setMockService( getCommandLineOptionSubstSpace( cmd, "m" ) );
257
258 if( cmd.hasOption( "a" ) )
259 setPath( getCommandLineOptionSubstSpace( cmd, "a" ) );
260
261 if( cmd.hasOption( "p" ) )
262 setPort( cmd.getOptionValue( "p" ) );
263
264 if( cmd.hasOption( "s" ) )
265 setSettingsFile( getCommandLineOptionSubstSpace( cmd, "s" ) );
266
267 setBlock( !cmd.hasOption( 'b' ) );
268 setSaveAfterRun( cmd.hasOption( 'S' ) );
269
270 if( cmd.hasOption( "x" ) )
271 {
272 setProjectPassword( cmd.getOptionValue( "x" ) );
273 }
274
275 if( cmd.hasOption( "v" ) )
276 {
277 setSoapUISettingsPassword( cmd.getOptionValue( "v" ) );
278 }
279
280 if( cmd.hasOption( "D" ) )
281 {
282 setSystemProperties( cmd.getOptionValues( "D" ) );
283 }
284
285 if( cmd.hasOption( "G" ) )
286 {
287 setGlobalProperties( cmd.getOptionValues( "G" ) );
288 }
289
290 if( cmd.hasOption( "P" ) )
291 {
292 setProjectProperties( cmd.getOptionValues( "P" ) );
293 }
294
295 return true;
296 }
297
298 public void setProjectPassword( String projectPassword )
299 {
300 this.projectPassword = projectPassword;
301 }
302
303 public String getProjectPassword()
304 {
305 return projectPassword;
306 }
307
308 public void setBlock( boolean block )
309 {
310 this.block = block;
311 }
312
313 public void setSaveAfterRun( boolean saveAfterRun )
314 {
315 this.saveAfterRun = saveAfterRun;
316 }
317
318 public WsdlProject getProject()
319 {
320 return project;
321 }
322 }