1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.mock;
14
15 import com.eviware.soapui.SoapUI;
16 import com.eviware.soapui.config.MockOperationConfig;
17 import com.eviware.soapui.config.MockServiceConfig;
18 import com.eviware.soapui.impl.wsdl.AbstractTestPropertyHolderWsdlModelItem;
19 import com.eviware.soapui.impl.wsdl.WsdlInterface;
20 import com.eviware.soapui.impl.wsdl.WsdlOperation;
21 import com.eviware.soapui.impl.wsdl.WsdlProject;
22 import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
23 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
24 import com.eviware.soapui.impl.wsdl.teststeps.BeanPathPropertySupport;
25 import com.eviware.soapui.model.ModelItem;
26 import com.eviware.soapui.model.iface.Operation;
27 import com.eviware.soapui.model.mock.*;
28 import com.eviware.soapui.model.project.Project;
29 import com.eviware.soapui.support.StringUtils;
30 import com.eviware.soapui.support.resolver.ResolveContext;
31 import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
32 import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
33
34 import javax.servlet.http.HttpServletRequest;
35 import javax.servlet.http.HttpServletResponse;
36 import javax.swing.*;
37 import java.util.*;
38
39 /***
40 * A MockService for simulation WsdlInterfaces and their operations
41 *
42 * @author ole.matzura
43 */
44
45 public class WsdlMockService extends AbstractTestPropertyHolderWsdlModelItem<MockServiceConfig> implements MockService
46 {
47 private static final String REQUIRE_SOAP_VERSION = WsdlMockService.class.getName() + "@require-soap-version";
48 private static final String REQUIRE_SOAP_ACTION = WsdlMockService.class.getName() + "@require-soap-action";
49
50 public final static String START_SCRIPT_PROPERTY = WsdlMockService.class.getName() + "@startScript";
51 public final static String STOP_SCRIPT_PROPERTY = WsdlMockService.class.getName() + "@stopScript";
52 public static final String INCOMING_WSS = WsdlMockService.class.getName() + "@incoming-wss";
53 public static final String OUGOING_WSS = WsdlMockService.class.getName() + "@outgoing-wss";
54
55 private List<WsdlMockOperation> mockOperations = new ArrayList<WsdlMockOperation>();
56 private Set<MockRunListener> mockRunListeners = new HashSet<MockRunListener>();
57 private Set<MockServiceListener> mockServiceListeners = new HashSet<MockServiceListener>();
58 private MockServiceIconAnimator iconAnimator;
59 private WsdlMockRunner mockRunner;
60 private SoapUIScriptEngine startScriptEngine;
61 private SoapUIScriptEngine stopScriptEngine;
62 private BeanPathPropertySupport docrootProperty;
63 private SoapUIScriptEngine onRequestScriptEngine;
64 private SoapUIScriptEngine afterRequestScriptEngine;
65 private WsdlMockOperation faultMockOperation;
66
67 public WsdlMockService( Project project, MockServiceConfig config )
68 {
69 super( config, project, "/mockService.gif" );
70
71 List<MockOperationConfig> testStepConfigs = config.getMockOperationList();
72 for( MockOperationConfig tsc : testStepConfigs )
73 {
74 WsdlMockOperation testStep = new WsdlMockOperation( this, tsc );
75 mockOperations.add( testStep );
76 }
77
78 if( !config.isSetPort() || config.getPort() < 1 )
79 config.setPort( 8080 );
80
81 if( !config.isSetPath() )
82 config.setPath( "/" );
83
84 iconAnimator = new MockServiceIconAnimator();
85 addMockRunListener( iconAnimator );
86
87 for( MockRunListener listener : SoapUI.getListenerRegistry().getListeners( MockRunListener.class ) )
88 {
89 addMockRunListener( listener );
90 }
91
92 if( !getConfig().isSetProperties() )
93 getConfig().addNewProperties();
94
95 setPropertiesConfig( getConfig().getProperties() );
96 docrootProperty = new BeanPathPropertySupport( this, "docroot" );
97
98 if( getConfig().isSetFaultMockOperation() )
99 {
100 faultMockOperation = getMockOperationByName( getConfig().getFaultMockOperation() );
101 }
102 }
103
104 public void addMockRunListener( MockRunListener listener )
105 {
106 mockRunListeners.add( listener );
107 }
108
109 public String getPath()
110 {
111 return getConfig().getPath();
112 }
113
114 public WsdlMockOperation getMockOperationAt( int index )
115 {
116 return mockOperations.get( index );
117 }
118
119 public WsdlMockOperation getMockOperationByName( String name )
120 {
121 return (WsdlMockOperation) getWsdlModelItemByName( mockOperations, name );
122 }
123
124 public int getMockOperationCount()
125 {
126 return mockOperations.size();
127 }
128
129 public WsdlProject getProject()
130 {
131 return (WsdlProject) getParent();
132 }
133
134 public int getPort()
135 {
136 return getConfig().getPort();
137 }
138
139 public String getHost()
140 {
141 return getConfig().getHost();
142 }
143
144 public void setHost( String host )
145 {
146 getConfig().setHost( host );
147 }
148
149 public boolean getBindToHostOnly()
150 {
151 return getConfig().getBindToHostOnly();
152 }
153
154 public void setBindToHostOnly( boolean bindToHostOnly )
155 {
156 getConfig().setBindToHostOnly( bindToHostOnly );
157 }
158
159 public void removeMockRunListener( MockRunListener listener )
160 {
161 mockRunListeners.remove( listener );
162 }
163
164 public WsdlMockRunner start( WsdlTestRunContext context ) throws Exception
165 {
166 String path = getPath();
167 if( path == null || path.trim().length() == 0 || path.trim().charAt( 0 ) != '/' )
168 throw new Exception( "Invalid path; must start with '/'" );
169
170 mockRunner = new WsdlMockRunner( this, context );
171 return mockRunner;
172 }
173
174 public WsdlMockRunner getMockRunner()
175 {
176 return mockRunner;
177 }
178
179 public WsdlMockOperation getMockOperation( Operation operation )
180 {
181 for( int c = 0; c < getMockOperationCount(); c++ )
182 {
183 WsdlMockOperation mockOperation = mockOperations.get( c );
184 if( mockOperation.getOperation() == operation )
185 return mockOperation;
186 }
187
188 return null;
189 }
190
191 public WsdlMockOperation addNewMockOperation( WsdlOperation operation )
192 {
193 if( getMockOperation( operation ) != null )
194 return null;
195
196 MockOperationConfig config = getConfig().addNewMockOperation();
197 config.setName( operation.getName() );
198 WsdlMockOperation mockOperation = new WsdlMockOperation( this, config, operation );
199
200 mockOperations.add( mockOperation );
201 fireMockOperationAdded( mockOperation );
202
203 return mockOperation;
204 }
205
206 public void setPort( int port )
207 {
208 String oldEndpoint = getLocalEndpoint();
209
210 int oldPort = getPort();
211 if( port != oldPort )
212 {
213 getConfig().setPort( port );
214 notifyPropertyChanged( PORT_PROPERTY, oldPort, port );
215
216 for( WsdlInterface iface : getMockedInterfaces() )
217 {
218 if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ) )
219 iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
220 }
221 }
222 }
223
224 public WsdlInterface[] getMockedInterfaces()
225 {
226 Set<WsdlInterface> result = new HashSet<WsdlInterface>();
227
228 for( WsdlMockOperation mockOperation : mockOperations )
229 {
230 WsdlOperation operation = mockOperation.getOperation();
231 if( operation != null )
232 result.add( operation.getInterface() );
233 }
234
235 return result.toArray( new WsdlInterface[result.size()] );
236 }
237
238 @Override
239 public void release()
240 {
241 super.release();
242
243 for( WsdlMockOperation operation : mockOperations )
244 operation.release();
245
246 mockServiceListeners.clear();
247
248 if( startScriptEngine != null )
249 startScriptEngine.release();
250
251 if( stopScriptEngine != null )
252 stopScriptEngine.release();
253 }
254
255 public void setPath( String path )
256 {
257 String oldEndpoint = getLocalEndpoint();
258
259 String oldPath = getPath();
260 if( !path.equals( oldPath ) )
261 {
262 getConfig().setPath( path );
263 notifyPropertyChanged( PATH_PROPERTY, oldPath, path );
264
265 for( WsdlInterface iface : getMockedInterfaces() )
266 {
267 if( Arrays.asList( iface.getEndpoints() ).contains( oldEndpoint ) )
268 iface.changeEndpoint( oldEndpoint, getLocalEndpoint() );
269 }
270 }
271 }
272
273 public MockRunListener[] getMockRunListeners()
274 {
275 return mockRunListeners.toArray( new MockRunListener[mockRunListeners.size()] );
276 }
277
278 public void removeMockOperation( WsdlMockOperation mockOperation )
279 {
280 int ix = mockOperations.indexOf( mockOperation );
281 if( ix == -1 )
282 throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
283
284 mockOperations.remove( ix );
285 fireMockOperationRemoved( mockOperation );
286 mockOperation.release();
287 getConfig().removeMockOperation( ix );
288 }
289
290 public void addMockServiceListener( MockServiceListener listener )
291 {
292 mockServiceListeners.add( listener );
293 }
294
295 public void removeMockServiceListener( MockServiceListener listener )
296 {
297 mockServiceListeners.remove( listener );
298 }
299
300 protected void fireMockOperationAdded( WsdlMockOperation mockOperation )
301 {
302 MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners
303 .size()] );
304 for( MockServiceListener listener : listeners )
305 {
306 listener.mockOperationAdded( mockOperation );
307 }
308 }
309
310 protected void fireMockOperationRemoved( WsdlMockOperation mockOperation )
311 {
312 MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners
313 .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
323 .size()] );
324 for( MockServiceListener listener : listeners )
325 {
326 listener.mockResponseAdded( mockResponse );
327 }
328 }
329
330 protected void fireMockResponseRemoved( WsdlMockResponse mockResponse )
331 {
332 MockServiceListener[] listeners = mockServiceListeners.toArray( new MockServiceListener[mockServiceListeners
333 .size()] );
334 for( MockServiceListener listener : listeners )
335 {
336 listener.mockResponseRemoved( mockResponse );
337 }
338 }
339
340 @Override
341 public ImageIcon getIcon()
342 {
343 return iconAnimator.getIcon();
344 }
345
346 public WsdlMockOperation getFaultMockOperation()
347 {
348 return faultMockOperation;
349 }
350
351 public void setFaultMockOperation( WsdlMockOperation mockOperation )
352 {
353 faultMockOperation = mockOperation;
354 if( faultMockOperation == null )
355 {
356 if( getConfig().isSetFaultMockOperation() )
357 {
358 getConfig().unsetFaultMockOperation();
359 }
360 }
361 else
362 {
363 getConfig().setFaultMockOperation( faultMockOperation.getName() );
364 }
365 }
366
367 private class MockServiceIconAnimator extends ModelItemIconAnimator<WsdlMockService> implements MockRunListener
368 {
369 public MockServiceIconAnimator()
370 {
371 super( WsdlMockService.this, "/mockService.gif", "/mockService", 4, "gif" );
372 }
373
374 public MockResult onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
375 {
376 return null;
377 }
378
379 public void onMockResult( MockResult result )
380 {
381 }
382
383 public void onMockRunnerStart( MockRunner mockRunner )
384 {
385 start();
386 }
387
388 public void onMockRunnerStop( MockRunner mockRunner )
389 {
390 stop();
391 WsdlMockService.this.mockRunner = null;
392 }
393 }
394
395 public String getLocalEndpoint()
396 {
397 String host = getHost();
398 if( StringUtils.isNullOrEmpty( host ) )
399 host = "127.0.0.1";
400
401 return "http://" + host + ":" + getPort() + getPath();
402 }
403
404 public boolean isRequireSoapVersion()
405 {
406 return getSettings().getBoolean( REQUIRE_SOAP_VERSION );
407 }
408
409 public void setRequireSoapVersion( boolean requireSoapVersion )
410 {
411 getSettings().setBoolean( REQUIRE_SOAP_VERSION, requireSoapVersion );
412 }
413
414 public boolean isRequireSoapAction()
415 {
416 return getSettings().getBoolean( REQUIRE_SOAP_ACTION );
417 }
418
419 public void setRequireSoapAction( boolean requireSoapAction )
420 {
421 getSettings().setBoolean( REQUIRE_SOAP_ACTION, requireSoapAction );
422 }
423
424 public WsdlMockRunner start() throws Exception
425 {
426 return start( null );
427 }
428
429 public boolean hasMockOperation( Operation operation )
430 {
431 return getMockOperation( operation ) != null;
432 }
433
434 public void setStartScript( String script )
435 {
436 String oldScript = getStartScript();
437
438 if( !getConfig().isSetStartScript() )
439 getConfig().addNewStartScript();
440
441 getConfig().getStartScript().setStringValue( script );
442
443 if( startScriptEngine != null )
444 startScriptEngine.setScript( script );
445
446 notifyPropertyChanged( START_SCRIPT_PROPERTY, oldScript, script );
447 }
448
449 public String getStartScript()
450 {
451 return getConfig().isSetStartScript() ? getConfig().getStartScript().getStringValue() : null;
452 }
453
454 public void setStopScript( String script )
455 {
456 String oldScript = getStopScript();
457
458 if( !getConfig().isSetStopScript() )
459 getConfig().addNewStopScript();
460
461 getConfig().getStopScript().setStringValue( script );
462 if( stopScriptEngine != null )
463 stopScriptEngine.setScript( script );
464
465 notifyPropertyChanged( STOP_SCRIPT_PROPERTY, oldScript, script );
466 }
467
468 public String getStopScript()
469 {
470 return getConfig().isSetStopScript() ? getConfig().getStopScript().getStringValue() : null;
471 }
472
473 public Object runStartScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
474 {
475 String script = getStartScript();
476 if( StringUtils.isNullOrEmpty( script ) )
477 return null;
478
479 if( startScriptEngine == null )
480 {
481 startScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
482 startScriptEngine.setScript( script );
483 }
484
485 startScriptEngine.setVariable( "context", runContext );
486 startScriptEngine.setVariable( "mockRunner", runner );
487 startScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
488 return startScriptEngine.run();
489 }
490
491 public Object runStopScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
492 {
493 String script = getStopScript();
494 if( StringUtils.isNullOrEmpty( script ) )
495 return null;
496
497 if( stopScriptEngine == null )
498 {
499 stopScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
500 stopScriptEngine.setScript( script );
501 }
502
503 stopScriptEngine.setVariable( "context", runContext );
504 stopScriptEngine.setVariable( "mockRunner", runner );
505 stopScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
506 return stopScriptEngine.run();
507 }
508
509 public void setOnRequestScript( String script )
510 {
511 String oldScript = getOnRequestScript();
512
513 if( !getConfig().isSetOnRequestScript() )
514 getConfig().addNewOnRequestScript();
515
516 getConfig().getOnRequestScript().setStringValue( script );
517
518 if( onRequestScriptEngine != null )
519 onRequestScriptEngine.setScript( script );
520
521 notifyPropertyChanged( "onRequestScript", oldScript, script );
522 }
523
524 public String getOnRequestScript()
525 {
526 return getConfig().isSetOnRequestScript() ? getConfig().getOnRequestScript().getStringValue() : null;
527 }
528
529 public void setAfterRequestScript( String script )
530 {
531 String oldScript = getAfterRequestScript();
532
533 if( !getConfig().isSetAfterRequestScript() )
534 getConfig().addNewAfterRequestScript();
535
536 getConfig().getAfterRequestScript().setStringValue( script );
537 if( afterRequestScriptEngine != null )
538 afterRequestScriptEngine.setScript( script );
539
540 notifyPropertyChanged( "afterRequestScript", oldScript, script );
541 }
542
543 public String getAfterRequestScript()
544 {
545 return getConfig().isSetAfterRequestScript() ? getConfig().getAfterRequestScript().getStringValue() : null;
546 }
547
548 public Object runOnRequestScript( WsdlMockRunContext runContext, WsdlMockRunner runner, WsdlMockRequest mockRequest ) throws Exception
549 {
550 String script = getOnRequestScript();
551 if( StringUtils.isNullOrEmpty( script ) )
552 return null;
553
554 if( onRequestScriptEngine == null )
555 {
556 onRequestScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
557 onRequestScriptEngine.setScript( script );
558 }
559
560 onRequestScriptEngine.setVariable( "context", runContext );
561 onRequestScriptEngine.setVariable( "mockRequest", mockRequest );
562 onRequestScriptEngine.setVariable( "mockRunner", runner );
563 onRequestScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
564 return onRequestScriptEngine.run();
565 }
566
567 public Object runAfterRequestScript( WsdlMockRunContext runContext, WsdlMockRunner runner, MockResult mockResult ) throws Exception
568 {
569 String script = getAfterRequestScript();
570 if( StringUtils.isNullOrEmpty( script ) )
571 return null;
572
573 if( afterRequestScriptEngine == null )
574 {
575 afterRequestScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
576 afterRequestScriptEngine.setScript( script );
577 }
578
579 afterRequestScriptEngine.setVariable( "context", runContext );
580 afterRequestScriptEngine.setVariable( "mockResult", mockResult );
581 afterRequestScriptEngine.setVariable( "mockRunner", runner );
582 afterRequestScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
583 return afterRequestScriptEngine.run();
584 }
585
586 public List<? extends ModelItem> getChildren()
587 {
588 return mockOperations;
589 }
590
591 public List<MockOperation> getMockOperationList()
592 {
593 return Collections.unmodifiableList( new ArrayList<MockOperation>( mockOperations ) );
594 }
595
596 public String getIncomingWss()
597 {
598 return getConfig().getIncomingWss();
599 }
600
601 public void setIncomingWss( String incomingWss )
602 {
603 String old = getIncomingWss();
604 getConfig().setIncomingWss( incomingWss );
605 notifyPropertyChanged( INCOMING_WSS, old, incomingWss );
606 }
607
608 public String getOutgoingWss()
609 {
610 return getConfig().getOutgoingWss();
611 }
612
613 public void setOutgoingWss( String outgoingWss )
614 {
615 String old = getOutgoingWss();
616 getConfig().setOutgoingWss( outgoingWss );
617 notifyPropertyChanged( OUGOING_WSS, old, outgoingWss );
618 }
619
620 public boolean isDispatchResponseMessages()
621 {
622 return getConfig().getDispatchResponseMessages();
623 }
624
625 public void setDispatchResponseMessages( boolean dispatchResponseMessages )
626 {
627 boolean old = isDispatchResponseMessages();
628 getConfig().setDispatchResponseMessages( dispatchResponseMessages );
629 notifyPropertyChanged( "dispatchResponseMessages", old, dispatchResponseMessages );
630 }
631
632 public List<WsdlOperation> getMockedOperations()
633 {
634 List<WsdlOperation> result = new ArrayList<WsdlOperation>();
635
636 for( WsdlMockOperation mockOperation : mockOperations )
637 result.add( mockOperation.getOperation() );
638
639 return result;
640 }
641
642 public void setDocroot( String docroot )
643 {
644 docrootProperty.set( docroot, true );
645 }
646
647 public String getDocroot()
648 {
649 return docrootProperty.get();
650 }
651
652 @Override
653 public void resolve( ResolveContext context )
654 {
655 super.resolve( context );
656 docrootProperty.resolveFile( context, "Missing MockService docroot" );
657 }
658
659 public void replace( WsdlMockOperation mockOperation, MockOperationConfig reloadedMockOperation )
660 {
661 int ix = mockOperations.indexOf( mockOperation );
662 if( ix == -1 )
663 throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
664
665 mockOperations.remove( ix );
666 fireMockOperationRemoved( mockOperation );
667 mockOperation.release();
668 getConfig().removeMockOperation( ix );
669
670 MockOperationConfig newConfig = (MockOperationConfig) getConfig().insertNewMockOperation( ix )
671 .set( reloadedMockOperation ).changeType( MockOperationConfig.type );
672 WsdlMockOperation newOperation = new WsdlMockOperation( this, newConfig );
673 mockOperations.add( ix, newOperation );
674 newOperation.afterLoad();
675 fireMockOperationAdded( newOperation );
676 }
677
678 }