1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.mock;
14
15 import java.util.ArrayList;
16 import java.util.Arrays;
17 import java.util.Collections;
18 import java.util.HashSet;
19 import java.util.List;
20 import java.util.Set;
21
22 import javax.servlet.http.HttpServletRequest;
23 import javax.servlet.http.HttpServletResponse;
24 import javax.swing.ImageIcon;
25
26 import com.eviware.soapui.SoapUI;
27 import com.eviware.soapui.config.MockOperationConfig;
28 import com.eviware.soapui.config.MockServiceConfig;
29 import com.eviware.soapui.impl.wsdl.AbstractTestPropertyHolderWsdlModelItem;
30 import com.eviware.soapui.impl.wsdl.WsdlInterface;
31 import com.eviware.soapui.impl.wsdl.WsdlOperation;
32 import com.eviware.soapui.impl.wsdl.WsdlProject;
33 import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
34 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
35 import com.eviware.soapui.model.ModelItem;
36 import com.eviware.soapui.model.iface.Operation;
37 import com.eviware.soapui.model.mock.MockOperation;
38 import com.eviware.soapui.model.mock.MockResult;
39 import com.eviware.soapui.model.mock.MockRunListener;
40 import com.eviware.soapui.model.mock.MockRunner;
41 import com.eviware.soapui.model.mock.MockService;
42 import com.eviware.soapui.model.mock.MockServiceListener;
43 import com.eviware.soapui.model.project.Project;
44 import com.eviware.soapui.support.StringUtils;
45 import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
46 import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
47
48 /***
49 * A MockService for simulation WsdlInterfaces and their operations
50 *
51 * @author ole.matzura
52 */
53
54 public class WsdlMockService extends AbstractTestPropertyHolderWsdlModelItem<MockServiceConfig> implements MockService
55 {
56 private static final String REQUIRE_SOAP_VERSION = WsdlMockService.class.getName() + "@require-soap-version";
57 private static final String REQUIRE_SOAP_ACTION = WsdlMockService.class.getName() + "@require-soap-action";
58
59 public final static String START_SCRIPT_PROPERTY = WsdlMockService.class.getName() + "@startScript";
60 public final static String STOP_SCRIPT_PROPERTY = WsdlMockService.class.getName() + "@stopScript";
61 public static final String INCOMING_WSS = WsdlMockService.class.getName() + "@incoming-wss";
62 public static final String OUGOING_WSS = WsdlMockService.class.getName() + "@outgoing-wss";
63
64 private List<WsdlMockOperation> mockOperations = new ArrayList<WsdlMockOperation>();
65 private Set<MockRunListener> mockRunListeners = new HashSet<MockRunListener>();
66 private Set<MockServiceListener> mockServiceListeners = new HashSet<MockServiceListener>();
67 private MockServiceIconAnimator iconAnimator;
68 private WsdlMockRunner mockRunner;
69 private SoapUIScriptEngine startScriptEngine;
70 private SoapUIScriptEngine stopScriptEngine;
71
72 public WsdlMockService( Project project, MockServiceConfig config)
73 {
74 super( config, project, "/mockService.gif" );
75
76 List<MockOperationConfig> testStepConfigs = config.getMockOperationList();
77 for (MockOperationConfig tsc : testStepConfigs )
78 {
79 WsdlMockOperation testStep = new WsdlMockOperation( this, tsc );
80 mockOperations.add( testStep );
81 }
82
83 if( !config.isSetPort() || config.getPort() < 1 )
84 config.setPort( 8080 );
85
86 if( !config.isSetPath() )
87 config.setPath( "/" );
88
89 iconAnimator = new MockServiceIconAnimator();
90 addMockRunListener( iconAnimator );
91
92 for (MockRunListener listener : SoapUI.getListenerRegistry().getListeners( MockRunListener.class ))
93 {
94 addMockRunListener(listener);
95 }
96
97 if( !getConfig().isSetProperties() )
98 getConfig().addNewProperties();
99
100 setPropertiesConfig( getConfig().getProperties() );
101 }
102
103 public void addMockRunListener( MockRunListener listener )
104 {
105 mockRunListeners.add( listener );
106 }
107
108 public String getPath()
109 {
110 return getConfig().getPath();
111 }
112
113 public WsdlMockOperation getMockOperationAt( int index )
114 {
115 return mockOperations.get( index );
116 }
117
118 public WsdlMockOperation getMockOperationByName( String name )
119 {
120 return ( WsdlMockOperation ) getWsdlModelItemByName( mockOperations, name );
121 }
122
123 public int getMockOperationCount()
124 {
125 return mockOperations.size();
126 }
127
128 public WsdlProject getProject()
129 {
130 return ( WsdlProject ) getParent();
131 }
132
133 public int getPort()
134 {
135 return getConfig().getPort();
136 }
137
138 public String getHost()
139 {
140 return getConfig().getHost();
141 }
142
143 public void setHost( String host )
144 {
145 getConfig().setHost( host );
146 }
147
148 public boolean getBindToHostOnly()
149 {
150 return getConfig().getBindToHostOnly();
151 }
152
153 public void setBindToHostOnly( boolean bindToHostOnly )
154 {
155 getConfig().setBindToHostOnly( bindToHostOnly );
156 }
157
158 public void removeMockRunListener( MockRunListener listener )
159 {
160 mockRunListeners.remove( listener );
161 }
162
163 public WsdlMockRunner start( WsdlTestRunContext context ) throws Exception
164 {
165 String path = getPath();
166 if( path == null || path.trim().length() == 0 || path.trim().charAt( 0 ) != '/' )
167 throw new Exception( "Invalid path; must start with '/'");
168
169 for( WsdlMockOperation operation : mockOperations )
170 operation.onStart();
171
172 mockRunner = new WsdlMockRunner( this, context );
173 return mockRunner;
174 }
175
176 public WsdlMockRunner getMockRunner()
177 {
178 return mockRunner;
179 }
180
181 public WsdlMockOperation getMockOperation( Operation operation )
182 {
183 for( int c = 0; c < getMockOperationCount(); c++ )
184 {
185 WsdlMockOperation mockOperation = mockOperations.get( c );
186 if( mockOperation.getOperation() == operation )
187 return mockOperation;
188 }
189
190 return null;
191 }
192
193 public WsdlMockOperation addNewMockOperation( WsdlOperation operation )
194 {
195 if( getMockOperation( operation ) != null )
196 return null;
197
198 MockOperationConfig config = getConfig().addNewMockOperation();
199 config.setName( operation.getName() );
200 WsdlMockOperation mockOperation = new WsdlMockOperation( this, config, operation );
201
202 mockOperations.add( mockOperation );
203 fireMockOperationAdded( mockOperation );
204
205 return mockOperation;
206 }
207
208 public void setPort( int port )
209 {
210 String oldEndpoint = getLocalEndpoint();
211
212 int oldPort = getPort();
213 if( port != oldPort )
214 {
215 getConfig().setPort( port );
216 notifyPropertyChanged( PORT_PROPERTY, oldPort, port );
217
218 for( WsdlInterface iface : getMockedInterfaces())
219 {
220 if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ))
221 iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
222 }
223 }
224 }
225
226 public WsdlInterface [] getMockedInterfaces()
227 {
228 Set<WsdlInterface> result = new HashSet<WsdlInterface>();
229
230 for( WsdlMockOperation mockOperation : mockOperations )
231 {
232 WsdlOperation operation = mockOperation.getOperation();
233 if( operation != null )
234 result.add( operation.getInterface() );
235 }
236
237 return result.toArray( new WsdlInterface[result.size()] );
238 }
239
240 @Override
241 public void release()
242 {
243 super.release();
244
245 for( WsdlMockOperation operation : mockOperations )
246 operation.release();
247
248 mockServiceListeners.clear();
249
250 if( startScriptEngine != null )
251 startScriptEngine.release();
252
253 if( stopScriptEngine != null )
254 stopScriptEngine.release();
255 }
256
257 public void setPath( String path )
258 {
259 String oldEndpoint = getLocalEndpoint();
260
261 String oldPath = getPath();
262 if( !path.equals( oldPath ))
263 {
264 getConfig().setPath( path );
265 notifyPropertyChanged( PATH_PROPERTY, oldPath, path );
266
267 for( WsdlInterface iface : getMockedInterfaces())
268 {
269 if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ))
270 iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
271 }
272 }
273 }
274
275 public MockRunListener [] getMockRunListeners()
276 {
277 return mockRunListeners.toArray( new MockRunListener[mockRunListeners.size()] );
278 }
279
280 public void removeMockOperation( WsdlMockOperation mockOperation )
281 {
282 int ix = mockOperations.indexOf( mockOperation );
283 if( ix == -1 )
284 throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
285
286 mockOperations.remove( ix );
287 fireMockOperationRemoved( mockOperation );
288 mockOperation.release();
289 getConfig().removeMockOperation( ix );
290 }
291
292 public void addMockServiceListener( MockServiceListener listener )
293 {
294 mockServiceListeners.add( listener );
295 }
296
297 public void removeMockServiceListener( MockServiceListener listener )
298 {
299 mockServiceListeners.remove( listener );
300 }
301
302 protected void fireMockOperationAdded( WsdlMockOperation mockOperation )
303 {
304 MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
305 for( MockServiceListener listener : listeners )
306 {
307 listener.mockOperationAdded( mockOperation );
308 }
309 }
310
311 protected void fireMockOperationRemoved( WsdlMockOperation mockOperation )
312 {
313 MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
314 for( MockServiceListener listener : listeners )
315 {
316 listener.mockOperationRemoved( mockOperation );
317 }
318 }
319
320 protected void fireMockResponseAdded( WsdlMockResponse mockResponse )
321 {
322 MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
323 for( MockServiceListener listener : listeners )
324 {
325 listener.mockResponseAdded( mockResponse );
326 }
327 }
328
329 protected void fireMockResponseRemoved( WsdlMockResponse mockResponse )
330 {
331 MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners.size()] );
332 for( MockServiceListener listener : listeners )
333 {
334 listener.mockResponseRemoved( mockResponse );
335 }
336 }
337
338 @Override
339 public ImageIcon getIcon()
340 {
341 return iconAnimator.getIcon();
342 }
343
344 private class MockServiceIconAnimator extends ModelItemIconAnimator implements MockRunListener
345 {
346 public MockServiceIconAnimator()
347 {
348 super( WsdlMockService.this, "/mockService.gif",
349 new String[] {"/mockService_1.gif", "/mockService_2.gif",
350 "/mockService_3.gif", "/mockService_4.gif"} );
351 }
352
353 public void onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
354 {
355 }
356
357 public void onMockResult( MockResult result )
358 {
359 }
360
361 public void onMockRunnerStart( MockRunner mockRunner )
362 {
363 start();
364 }
365
366 public void onMockRunnerStop( MockRunner mockRunner )
367 {
368 stop();
369 WsdlMockService.this.mockRunner = null;
370 }
371 }
372
373 public String getLocalEndpoint()
374 {
375 String host = getHost();
376 if( StringUtils.isNullOrEmpty( host ))
377 host = "127.0.0.1";
378
379 return "http://" + host + ":" + getPort() + getPath();
380 }
381
382 public boolean isRequireSoapVersion()
383 {
384 return getSettings().getBoolean( REQUIRE_SOAP_VERSION );
385 }
386
387 public void setRequireSoapVersion( boolean requireSoapVersion )
388 {
389 getSettings().setBoolean( REQUIRE_SOAP_VERSION, requireSoapVersion );
390 }
391
392 public boolean isRequireSoapAction()
393 {
394 return getSettings().getBoolean( REQUIRE_SOAP_ACTION );
395 }
396
397 public void setRequireSoapAction( boolean requireSoapAction )
398 {
399 getSettings().setBoolean( REQUIRE_SOAP_ACTION, requireSoapAction );
400 }
401
402
403 public WsdlMockRunner start() throws Exception
404 {
405 return start( null );
406 }
407
408 public boolean hasMockOperation( Operation operation )
409 {
410 return getMockOperation( operation ) != null;
411 }
412
413 @Override
414 public void beforeSave()
415 {
416 for( WsdlMockOperation mockOperation : mockOperations )
417 mockOperation.beforeSave();
418 }
419
420 public void setStartScript( String script )
421 {
422 String oldScript = getStartScript();
423
424 if( !getConfig().isSetStartScript() )
425 getConfig().addNewStartScript();
426
427 getConfig().getStartScript().setStringValue( script );
428
429 if( startScriptEngine != null )
430 startScriptEngine.setScript( script );
431
432 notifyPropertyChanged( START_SCRIPT_PROPERTY, oldScript, script );
433 }
434
435 public String getStartScript()
436 {
437 return getConfig().isSetStartScript() ? getConfig().getStartScript().getStringValue() : null;
438 }
439
440 public void setStopScript( String script )
441 {
442 String oldScript = getStopScript();
443
444 if( !getConfig().isSetStopScript() )
445 getConfig().addNewStopScript();
446
447 getConfig().getStopScript().setStringValue( script );
448 if( stopScriptEngine != null )
449 stopScriptEngine.setScript( script );
450
451 notifyPropertyChanged( STOP_SCRIPT_PROPERTY, oldScript, script );
452 }
453
454 public String getStopScript()
455 {
456 return getConfig().isSetStopScript() ? getConfig().getStopScript().getStringValue() : null;
457 }
458
459 public Object runStartScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
460 {
461 String script = getStartScript();
462 if( StringUtils.isNullOrEmpty( script ))
463 return null;
464
465 if( startScriptEngine == null )
466 {
467 startScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
468 startScriptEngine.setScript( script );
469 }
470
471 startScriptEngine.setVariable( "context", runContext );
472 startScriptEngine.setVariable( "mockRunner", runner );
473 startScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
474 return startScriptEngine.run();
475 }
476
477 public Object runStopScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
478 {
479 String script = getStopScript();
480 if( StringUtils.isNullOrEmpty( script ))
481 return null;
482
483 if( stopScriptEngine == null )
484 {
485 stopScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
486 stopScriptEngine.setScript( script );
487 }
488
489 stopScriptEngine.setVariable( "context", runContext );
490 stopScriptEngine.setVariable( "mockRunner", runner );
491 stopScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
492 return stopScriptEngine.run();
493 }
494
495 public List<? extends ModelItem> getChildren()
496 {
497 return mockOperations;
498 }
499
500 public List<MockOperation> getMockOperationList()
501 {
502 return Collections.unmodifiableList( new ArrayList<MockOperation>( mockOperations ));
503 }
504
505 public String getIncomingWss()
506 {
507 return getConfig().getIncomingWss();
508 }
509
510 public void setIncomingWss( String incomingWss )
511 {
512 String old = getIncomingWss();
513 getConfig().setIncomingWss( incomingWss );
514 notifyPropertyChanged( INCOMING_WSS, old, incomingWss );
515 }
516
517 public String getOutgoingWss()
518 {
519 return getConfig().getOutgoingWss();
520 }
521
522 public void setOutgoingWss( String outgoingWss )
523 {
524 String old = getOutgoingWss();
525 getConfig().setOutgoingWss( outgoingWss );
526 notifyPropertyChanged( OUGOING_WSS, old, outgoingWss );
527 }
528 }