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