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