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 getConfig().unsetFaultMockOperation();
356 else
357 getConfig().setFaultMockOperation( faultMockOperation.getName() );
358 }
359
360 private class MockServiceIconAnimator extends ModelItemIconAnimator<WsdlMockService> implements MockRunListener
361 {
362 public MockServiceIconAnimator()
363 {
364 super( WsdlMockService.this, "/mockService.gif", "/mockService", 4, "gif" );
365 }
366
367 public void onMockRequest( MockRunner runner, HttpServletRequest request, HttpServletResponse response )
368 {
369 }
370
371 public void onMockResult( MockResult result )
372 {
373 }
374
375 public void onMockRunnerStart( MockRunner mockRunner )
376 {
377 start();
378 }
379
380 public void onMockRunnerStop( MockRunner mockRunner )
381 {
382 stop();
383 WsdlMockService.this.mockRunner = null;
384 }
385 }
386
387 public String getLocalEndpoint()
388 {
389 String host = getHost();
390 if( StringUtils.isNullOrEmpty( host ) )
391 host = "127.0.0.1";
392
393 return "http://" + host + ":" + getPort() + getPath();
394 }
395
396 public boolean isRequireSoapVersion()
397 {
398 return getSettings().getBoolean( REQUIRE_SOAP_VERSION );
399 }
400
401 public void setRequireSoapVersion( boolean requireSoapVersion )
402 {
403 getSettings().setBoolean( REQUIRE_SOAP_VERSION, requireSoapVersion );
404 }
405
406 public boolean isRequireSoapAction()
407 {
408 return getSettings().getBoolean( REQUIRE_SOAP_ACTION );
409 }
410
411 public void setRequireSoapAction( boolean requireSoapAction )
412 {
413 getSettings().setBoolean( REQUIRE_SOAP_ACTION, requireSoapAction );
414 }
415
416 public WsdlMockRunner start() throws Exception
417 {
418 return start( null );
419 }
420
421 public boolean hasMockOperation( Operation operation )
422 {
423 return getMockOperation( operation ) != null;
424 }
425
426 public void setStartScript( String script )
427 {
428 String oldScript = getStartScript();
429
430 if( !getConfig().isSetStartScript() )
431 getConfig().addNewStartScript();
432
433 getConfig().getStartScript().setStringValue( script );
434
435 if( startScriptEngine != null )
436 startScriptEngine.setScript( script );
437
438 notifyPropertyChanged( START_SCRIPT_PROPERTY, oldScript, script );
439 }
440
441 public String getStartScript()
442 {
443 return getConfig().isSetStartScript() ? getConfig().getStartScript().getStringValue() : null;
444 }
445
446 public void setStopScript( String script )
447 {
448 String oldScript = getStopScript();
449
450 if( !getConfig().isSetStopScript() )
451 getConfig().addNewStopScript();
452
453 getConfig().getStopScript().setStringValue( script );
454 if( stopScriptEngine != null )
455 stopScriptEngine.setScript( script );
456
457 notifyPropertyChanged( STOP_SCRIPT_PROPERTY, oldScript, script );
458 }
459
460 public String getStopScript()
461 {
462 return getConfig().isSetStopScript() ? getConfig().getStopScript().getStringValue() : null;
463 }
464
465 public Object runStartScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
466 {
467 String script = getStartScript();
468 if( StringUtils.isNullOrEmpty( script ) )
469 return null;
470
471 if( startScriptEngine == null )
472 {
473 startScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
474 startScriptEngine.setScript( script );
475 }
476
477 startScriptEngine.setVariable( "context", runContext );
478 startScriptEngine.setVariable( "mockRunner", runner );
479 startScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
480 return startScriptEngine.run();
481 }
482
483 public Object runStopScript( WsdlMockRunContext runContext, WsdlMockRunner runner ) throws Exception
484 {
485 String script = getStopScript();
486 if( StringUtils.isNullOrEmpty( script ) )
487 return null;
488
489 if( stopScriptEngine == null )
490 {
491 stopScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
492 stopScriptEngine.setScript( script );
493 }
494
495 stopScriptEngine.setVariable( "context", runContext );
496 stopScriptEngine.setVariable( "mockRunner", runner );
497 stopScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
498 return stopScriptEngine.run();
499 }
500
501 public void setOnRequestScript( String script )
502 {
503 String oldScript = getOnRequestScript();
504
505 if( !getConfig().isSetOnRequestScript() )
506 getConfig().addNewOnRequestScript();
507
508 getConfig().getOnRequestScript().setStringValue( script );
509
510 if( onRequestScriptEngine != null )
511 onRequestScriptEngine.setScript( script );
512
513 notifyPropertyChanged( "onRequestScript", oldScript, script );
514 }
515
516 public String getOnRequestScript()
517 {
518 return getConfig().isSetOnRequestScript() ? getConfig().getOnRequestScript().getStringValue() : null;
519 }
520
521 public void setAfterRequestScript( String script )
522 {
523 String oldScript = getAfterRequestScript();
524
525 if( !getConfig().isSetAfterRequestScript() )
526 getConfig().addNewAfterRequestScript();
527
528 getConfig().getAfterRequestScript().setStringValue( script );
529 if( afterRequestScriptEngine != null )
530 afterRequestScriptEngine.setScript( script );
531
532 notifyPropertyChanged( "afterRequestScript", oldScript, script );
533 }
534
535 public String getAfterRequestScript()
536 {
537 return getConfig().isSetAfterRequestScript() ? getConfig().getAfterRequestScript().getStringValue() : null;
538 }
539
540 public Object runOnRequestScript( WsdlMockRunContext runContext, WsdlMockRunner runner, WsdlMockRequest mockRequest ) throws Exception
541 {
542 String script = getOnRequestScript();
543 if( StringUtils.isNullOrEmpty( script ) )
544 return null;
545
546 if( onRequestScriptEngine == null )
547 {
548 onRequestScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
549 onRequestScriptEngine.setScript( script );
550 }
551
552 onRequestScriptEngine.setVariable( "context", runContext );
553 onRequestScriptEngine.setVariable( "mockRequest", mockRequest );
554 onRequestScriptEngine.setVariable( "mockRunner", runner );
555 onRequestScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
556 return onRequestScriptEngine.run();
557 }
558
559 public Object runAfterRequestScript( WsdlMockRunContext runContext, WsdlMockRunner runner, MockResult mockResult ) throws Exception
560 {
561 String script = getAfterRequestScript();
562 if( StringUtils.isNullOrEmpty( script ) )
563 return null;
564
565 if( afterRequestScriptEngine == null )
566 {
567 afterRequestScriptEngine = SoapUIScriptEngineRegistry.create( SoapUIScriptEngineRegistry.GROOVY_ID, this );
568 afterRequestScriptEngine.setScript( script );
569 }
570
571 afterRequestScriptEngine.setVariable( "context", runContext );
572 afterRequestScriptEngine.setVariable( "mockResult", mockResult );
573 afterRequestScriptEngine.setVariable( "mockRunner", runner );
574 afterRequestScriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
575 return afterRequestScriptEngine.run();
576 }
577
578 public List<? extends ModelItem> getChildren()
579 {
580 return mockOperations;
581 }
582
583 public List<MockOperation> getMockOperationList()
584 {
585 return Collections.unmodifiableList( new ArrayList<MockOperation>( mockOperations ) );
586 }
587
588 public String getIncomingWss()
589 {
590 return getConfig().getIncomingWss();
591 }
592
593 public void setIncomingWss( String incomingWss )
594 {
595 String old = getIncomingWss();
596 getConfig().setIncomingWss( incomingWss );
597 notifyPropertyChanged( INCOMING_WSS, old, incomingWss );
598 }
599
600 public String getOutgoingWss()
601 {
602 return getConfig().getOutgoingWss();
603 }
604
605 public void setOutgoingWss( String outgoingWss )
606 {
607 String old = getOutgoingWss();
608 getConfig().setOutgoingWss( outgoingWss );
609 notifyPropertyChanged( OUGOING_WSS, old, outgoingWss );
610 }
611
612 public boolean isDispatchResponseMessages()
613 {
614 return getConfig().getDispatchResponseMessages();
615 }
616
617 public void setDispatchResponseMessages( boolean dispatchResponseMessages )
618 {
619 boolean old = isDispatchResponseMessages();
620 getConfig().setDispatchResponseMessages( dispatchResponseMessages );
621 notifyPropertyChanged( "dispatchResponseMessages", old, dispatchResponseMessages );
622 }
623
624 public List<WsdlOperation> getMockedOperations()
625 {
626 List<WsdlOperation> result = new ArrayList<WsdlOperation>();
627
628 for( WsdlMockOperation mockOperation : mockOperations )
629 result.add( mockOperation.getOperation() );
630
631 return result;
632 }
633
634 public void setDocroot( String docroot )
635 {
636 docrootProperty.set( docroot, true );
637 }
638
639 public String getDocroot()
640 {
641 return docrootProperty.get();
642 }
643
644 @Override
645 public void resolve( ResolveContext context )
646 {
647 super.resolve( context );
648 docrootProperty.resolveFile( context, "Missing MockService docroot" );
649 }
650
651 public void replace( WsdlMockOperation mockOperation, MockOperationConfig reloadedMockOperation )
652 {
653 int ix = mockOperations.indexOf( mockOperation );
654 if( ix == -1 )
655 throw new RuntimeException( "Unkonws MockOperation specified to removeMockOperation" );
656
657 mockOperations.remove( ix );
658 fireMockOperationRemoved( mockOperation );
659 mockOperation.release();
660 getConfig().removeMockOperation( ix );
661
662 MockOperationConfig newConfig = (MockOperationConfig) getConfig().insertNewMockOperation( ix )
663 .set( reloadedMockOperation ).changeType( MockOperationConfig.type );
664 WsdlMockOperation newOperation = new WsdlMockOperation( this, newConfig );
665 mockOperations.add( ix, newOperation );
666 newOperation.afterLoad();
667 fireMockOperationAdded( newOperation );
668 }
669
670 }