1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import java.beans.PropertyChangeEvent;
16 import java.beans.PropertyChangeListener;
17 import java.util.ArrayList;
18 import java.util.Collection;
19 import java.util.HashMap;
20 import java.util.List;
21 import java.util.Map;
22
23 import javax.swing.ImageIcon;
24
25 import org.apache.log4j.Logger;
26
27 import com.eviware.soapui.SoapUI;
28 import com.eviware.soapui.config.MockOperationDispatchStyleConfig;
29 import com.eviware.soapui.config.MockResponseConfig;
30 import com.eviware.soapui.config.MockResponseStepConfig;
31 import com.eviware.soapui.config.MockServiceConfig;
32 import com.eviware.soapui.config.TestAssertionConfig;
33 import com.eviware.soapui.config.TestStepConfig;
34 import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
35 import com.eviware.soapui.impl.wsdl.WsdlInterface;
36 import com.eviware.soapui.impl.wsdl.WsdlOperation;
37 import com.eviware.soapui.impl.wsdl.WsdlProject;
38 import com.eviware.soapui.impl.wsdl.WsdlSubmitContext;
39 import com.eviware.soapui.impl.wsdl.mock.WsdlMockOperation;
40 import com.eviware.soapui.impl.wsdl.mock.WsdlMockResponse;
41 import com.eviware.soapui.impl.wsdl.mock.WsdlMockResult;
42 import com.eviware.soapui.impl.wsdl.mock.WsdlMockRunner;
43 import com.eviware.soapui.impl.wsdl.mock.WsdlMockService;
44 import com.eviware.soapui.impl.wsdl.mock.dispatch.QueryMatchMockOperationDispatcher;
45 import com.eviware.soapui.impl.wsdl.panels.mockoperation.WsdlMockResultMessageExchange;
46 import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
47 import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
48 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
49 import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
50 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
51 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
52 import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry;
53 import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
54 import com.eviware.soapui.model.ModelItem;
55 import com.eviware.soapui.model.iface.Interface;
56 import com.eviware.soapui.model.iface.Operation;
57 import com.eviware.soapui.model.iface.SubmitContext;
58 import com.eviware.soapui.model.mock.MockResult;
59 import com.eviware.soapui.model.mock.MockRunner;
60 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
61 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
62 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
63 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
64 import com.eviware.soapui.model.support.DefaultTestStepProperty;
65 import com.eviware.soapui.model.support.InterfaceListenerAdapter;
66 import com.eviware.soapui.model.support.MockRunListenerAdapter;
67 import com.eviware.soapui.model.support.ModelSupport;
68 import com.eviware.soapui.model.support.ProjectListenerAdapter;
69 import com.eviware.soapui.model.support.TestRunListenerAdapter;
70 import com.eviware.soapui.model.support.TestStepBeanProperty;
71 import com.eviware.soapui.model.testsuite.Assertable;
72 import com.eviware.soapui.model.testsuite.AssertedXPath;
73 import com.eviware.soapui.model.testsuite.AssertionError;
74 import com.eviware.soapui.model.testsuite.AssertionsListener;
75 import com.eviware.soapui.model.testsuite.LoadTestRunner;
76 import com.eviware.soapui.model.testsuite.OperationTestStep;
77 import com.eviware.soapui.model.testsuite.RequestAssertedMessageExchange;
78 import com.eviware.soapui.model.testsuite.TestAssertion;
79 import com.eviware.soapui.model.testsuite.TestCaseRunContext;
80 import com.eviware.soapui.model.testsuite.TestCaseRunner;
81 import com.eviware.soapui.model.testsuite.TestStep;
82 import com.eviware.soapui.model.testsuite.TestStepResult;
83 import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
84 import com.eviware.soapui.support.StringUtils;
85 import com.eviware.soapui.support.resolver.ChangeOperationResolver;
86 import com.eviware.soapui.support.resolver.ImportInterfaceResolver;
87 import com.eviware.soapui.support.resolver.RemoveTestStepResolver;
88 import com.eviware.soapui.support.resolver.ResolveContext;
89 import com.eviware.soapui.support.resolver.ResolveContext.PathToResolve;
90 import com.eviware.soapui.support.types.StringToStringMap;
91
92 public class WsdlMockResponseTestStep extends WsdlTestStepWithProperties implements OperationTestStep,
93 PropertyChangeListener, Assertable, PropertyExpansionContainer
94 {
95 private final static Logger log = Logger.getLogger( WsdlMockResponseTestStep.class );
96
97 public static final String STATUS_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@status";
98 public static final String TIMEOUT_PROPERTY = WsdlMockResponseTestStep.class.getName() + "@timeout";
99
100 private MockResponseStepConfig mockResponseStepConfig;
101 private MockResponseConfig mockResponseConfig;
102 private WsdlMockOperation mockOperation;
103 private WsdlTestMockService mockService;
104 private WsdlMockRunner mockRunner;
105 private WsdlMockResponse mockResponse;
106
107 private AssertionsSupport assertionsSupport;
108 private InternalMockRunListener mockRunListener;
109 private StartStepMockRunListener startStepMockRunListener;
110
111 private final InternalProjectListener projectListener = new InternalProjectListener();
112 private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
113 private final InternalTestRunListener testRunListener = new InternalTestRunListener();
114 private WsdlInterface iface;
115 private AssertionStatus oldStatus;
116
117 private ModelItemIconAnimator<WsdlMockResponseTestStep> iconAnimator;
118 private WsdlMockResponse testMockResponse;
119 private WsdlTestStep startTestStep;
120
121 public WsdlMockResponseTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
122 {
123 super( testCase, config, true, forLoadTest );
124
125 if( config.getConfig() != null )
126 {
127 mockResponseStepConfig = ( MockResponseStepConfig )config.getConfig().changeType( MockResponseStepConfig.type );
128 mockResponseConfig = mockResponseStepConfig.getResponse();
129 }
130 else
131 {
132 mockResponseStepConfig = ( MockResponseStepConfig )config.addNewConfig().changeType(
133 MockResponseStepConfig.type );
134 mockResponseConfig = mockResponseStepConfig.addNewResponse();
135 }
136
137 initAssertions();
138 initMockObjects( testCase );
139
140 if( !forLoadTest )
141 {
142 if( iface != null )
143 {
144 iface.getProject().addProjectListener( projectListener );
145 iface.addInterfaceListener( interfaceListener );
146 }
147
148 iconAnimator = new ModelItemIconAnimator<WsdlMockResponseTestStep>( this, "/mockResponseStep.gif",
149 "/exec_mockResponse", 4, "gif" );
150 }
151
152
153 initProperties();
154
155 testCase.addTestRunListener( testRunListener );
156 testCase.addPropertyChangeListener( this );
157 }
158
159 @Override
160 public void afterLoad()
161 {
162 super.afterLoad();
163
164 if( mockResponseStepConfig.isSetStartStep() )
165 {
166 startTestStep = getTestCase().getTestStepByName( mockResponseStepConfig.getStartStep() );
167 if( startTestStep != null )
168 {
169 startTestStep.addPropertyChangeListener( this );
170 }
171 }
172 }
173
174 private void initProperties()
175 {
176 if( mockResponse != null )
177 {
178 addProperty( new TestStepBeanProperty( "Response", false, mockResponse, "responseContent", this ) );
179 }
180
181 addProperty( new DefaultTestStepProperty( "Request", true, new DefaultTestStepProperty.PropertyHandlerAdapter()
182 {
183 public String getValue( DefaultTestStepProperty property )
184 {
185 WsdlMockResult mockResult = mockResponse == null ? null : mockResponse.getMockResult();
186 return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
187 }
188 }, this ) );
189 }
190
191 @Override
192 public ImageIcon getIcon()
193 {
194 return iconAnimator == null ? null : iconAnimator.getIcon();
195 }
196
197 private void initAssertions()
198 {
199 assertionsSupport = new AssertionsSupport( this, new AssertableConfig()
200 {
201
202 public TestAssertionConfig addNewAssertion()
203 {
204 return mockResponseStepConfig.addNewAssertion();
205 }
206
207 public List<TestAssertionConfig> getAssertionList()
208 {
209 return mockResponseStepConfig.getAssertionList();
210 }
211
212 public void removeAssertion( int ix )
213 {
214 mockResponseStepConfig.removeAssertion( ix );
215 }
216
217 public TestAssertionConfig insertAssertion( TestAssertionConfig source, int ix )
218 {
219 TestAssertionConfig conf = mockResponseStepConfig.insertNewAssertion( ix );
220 conf.set( source );
221 return conf;
222 }
223 } );
224 }
225
226 private void initMockObjects( WsdlTestCase testCase )
227 {
228 MockServiceConfig mockServiceConfig = MockServiceConfig.Factory.newInstance();
229 mockServiceConfig.setPath( mockResponseStepConfig.getPath() );
230 mockServiceConfig.setPort( mockResponseStepConfig.getPort() );
231 mockServiceConfig.setHost( mockResponseStepConfig.getHost() );
232
233 mockService = new WsdlTestMockService( this, mockServiceConfig );
234 mockService.setName( getName() );
235
236 iface = ( WsdlInterface )testCase.getTestSuite().getProject().getInterfaceByName(
237 mockResponseStepConfig.getInterface() );
238 if( iface == null )
239 {
240 }
241 else
242 {
243 iface.addInterfaceListener( interfaceListener );
244
245 mockOperation = mockService.addNewMockOperation( iface.getOperationByName( mockResponseStepConfig
246 .getOperation() ) );
247
248 if( mockResponseStepConfig.getHandleFault() )
249 mockService.setFaultMockOperation( mockOperation );
250
251 if( mockResponseStepConfig.getHandleResponse() )
252 mockService.setDispatchResponseMessages( true );
253
254 mockResponse = mockOperation.addNewMockResponse( "MockResponse", false );
255 mockResponse.setConfig( mockResponseConfig );
256
257 mockOperation.setDefaultResponse( mockResponse.getName() );
258
259 mockResponse.addPropertyChangeListener( this );
260 mockResponse.getWsaConfig().addPropertyChangeListener( this );
261 }
262 }
263
264 public void resetConfigOnMove( TestStepConfig config )
265 {
266 super.resetConfigOnMove( config );
267
268 mockResponseStepConfig = ( MockResponseStepConfig )config.getConfig().changeType( MockResponseStepConfig.type );
269 mockResponseConfig = mockResponseStepConfig.getResponse();
270 mockResponse.setConfig( mockResponseConfig );
271 assertionsSupport.refresh();
272 }
273
274 @Override
275 public boolean cancel()
276 {
277 if( mockRunner != null )
278 {
279 mockRunner.stop();
280 mockRunner = null;
281 }
282
283 if( mockRunListener != null )
284 {
285 mockRunListener.cancel();
286 }
287
288 return true;
289 }
290
291 @Override
292 public void prepare( TestCaseRunner testRunner, TestCaseRunContext testRunContext ) throws Exception
293 {
294 super.prepare( testRunner, testRunContext );
295
296 LoadTestRunner loadTestRunner = ( LoadTestRunner )testRunContext
297 .getProperty( TestCaseRunContext.LOAD_TEST_RUNNER );
298 mockRunListener = new InternalMockRunListener();
299
300 for( TestAssertion assertion : getAssertionList() )
301 {
302 assertion.prepare( testRunner, testRunContext );
303 }
304
305 if( loadTestRunner == null )
306 {
307 mockService.addMockRunListener( mockRunListener );
308 mockRunner = mockService.start( ( WsdlTestRunContext )testRunContext );
309 }
310 else
311 {
312 synchronized( STATUS_PROPERTY )
313 {
314 mockRunner = ( WsdlMockRunner )testRunContext.getProperty( "sharedMockServiceRunner" );
315 if( mockRunner == null )
316 {
317 mockService.addMockRunListener( mockRunListener );
318 mockRunner = mockService.start( ( WsdlTestRunContext )testRunContext );
319 }
320 else
321 {
322 mockRunner.getMockService().addMockRunListener( mockRunListener );
323 }
324 }
325 }
326
327 if( startTestStep instanceof WsdlMockResponseTestStep )
328 {
329 System.out.println( "Adding StartStepMockRunListener from [" + getName() + "] to [" + startTestStep.getName()
330 + "]" );
331 startStepMockRunListener = new StartStepMockRunListener( testRunContext,
332 ( WsdlMockResponseTestStep )startTestStep );
333 }
334 }
335
336 protected void initTestMockResponse( TestCaseRunContext testRunContext )
337 {
338 if( StringUtils.hasContent( getQuery() ) && StringUtils.hasContent( getMatch() ) )
339 {
340 String name = "MockResponse" + Math.random();
341 testMockResponse = mockOperation.addNewMockResponse( name, false );
342 testMockResponse.setConfig( ( MockResponseConfig )mockResponse.getConfig().copy() );
343 testMockResponse.setName( name );
344
345 QueryMatchMockOperationDispatcher dispatcher = ( QueryMatchMockOperationDispatcher )mockOperation
346 .setDispatchStyle( MockOperationDispatchStyleConfig.QUERY_MATCH.toString() );
347
348 for( QueryMatchMockOperationDispatcher.Query query : dispatcher.getQueries() )
349 dispatcher.deleteQuery( query );
350
351 QueryMatchMockOperationDispatcher.Query query = dispatcher.addQuery( "Match" );
352 query.setQuery( PropertyExpander.expandProperties( testRunContext, getQuery() ) );
353 query.setMatch( PropertyExpander.expandProperties( testRunContext, getMatch() ) );
354 query.setResponse( testMockResponse.getName() );
355 }
356 else
357 {
358 testMockResponse = mockResponse;
359 testMockResponse.setMockResult( null );
360 }
361 }
362
363 public TestStepResult run( TestCaseRunner testRunner, TestCaseRunContext context )
364 {
365 LoadTestRunner loadTestRunner = ( LoadTestRunner )context.getProperty( TestCaseRunContext.LOAD_TEST_RUNNER );
366 if( loadTestRunner == null )
367 {
368 return internalRun( ( WsdlTestRunContext )context );
369 }
370 else
371 {
372
373 synchronized( STATUS_PROPERTY )
374 {
375 if( loadTestRunner.getStatus() == LoadTestRunner.Status.RUNNING )
376 {
377 return internalRun( ( WsdlTestRunContext )context );
378 }
379 else
380 {
381 WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult( this );
382 result.setStatus( TestStepStatus.UNKNOWN );
383 return result;
384 }
385 }
386 }
387 }
388
389 private TestStepResult internalRun( WsdlTestRunContext context )
390 {
391 iconAnimator.start();
392 WsdlSingleMessageExchangeTestStepResult result = new WsdlSingleMessageExchangeTestStepResult( this );
393
394 try
395 {
396 result.startTimer();
397
398 if( !mockRunListener.hasResult() )
399 {
400 if( testMockResponse == null )
401 initTestMockResponse( context );
402
403 long timeout = getTimeout();
404 synchronized( mockRunListener )
405 {
406 mockRunListener.waitForRequest( timeout );
407 }
408 }
409
410 result.stopTimer();
411 if( mockRunner != null && mockRunner.isRunning() )
412 mockRunner.stop();
413
414 AssertedWsdlMockResultMessageExchange messageExchange = new AssertedWsdlMockResultMessageExchange(
415 mockRunListener.getResult() );
416 result.setMessageExchange( messageExchange );
417
418 if( mockRunListener.getResult() != null )
419 {
420 context.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, messageExchange );
421 assertResult( mockRunListener.getResult(), context );
422 }
423
424 if( mockRunListener.getResult() == null )
425 {
426 if( mockRunListener.isCanceled() )
427 {
428 result.setStatus( TestStepStatus.CANCELED );
429 }
430 else
431 {
432 result.setStatus( TestStepStatus.FAILED );
433 result.addMessage( "Timeout occured after " + getTimeout() + " milliseconds" );
434 }
435 }
436 else
437 {
438 AssertionStatus status = getAssertionStatus();
439 if( status == AssertionStatus.FAILED )
440 {
441 result.setStatus( TestStepStatus.FAILED );
442
443 if( getAssertionCount() == 0 )
444 {
445 result.addMessage( "Invalid/empty request" );
446 }
447 else
448 for( int c = 0; c < getAssertionCount(); c++ )
449 {
450 AssertionError[] errors = getAssertionAt( c ).getErrors();
451 if( errors != null )
452 {
453 for( AssertionError error : errors )
454 {
455 result.addMessage( error.getMessage() );
456 }
457 }
458 }
459 }
460 else
461 {
462 result.setStatus( TestStepStatus.OK );
463 }
464
465 mockRunListener.setResult( null );
466 }
467 }
468 catch( Exception e )
469 {
470 result.stopTimer();
471 result.setStatus( TestStepStatus.FAILED );
472 result.setError( e );
473 SoapUI.logError( e );
474 }
475 finally
476 {
477 iconAnimator.stop();
478 }
479
480 return result;
481 }
482
483 private void assertResult( WsdlMockResult result, SubmitContext context )
484 {
485 if( oldStatus == null )
486 oldStatus = getAssertionStatus();
487
488 for( int c = 0; c < getAssertionCount(); c++ )
489 {
490 WsdlMessageAssertion assertion = getAssertionAt( c );
491 if( !assertion.isDisabled() )
492 {
493 assertion.assertRequest( new WsdlMockResultMessageExchange( result, getMockResponse() ), context );
494 }
495 }
496
497 AssertionStatus newStatus = getAssertionStatus();
498 if( newStatus != oldStatus )
499 {
500 notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
501 oldStatus = newStatus;
502 }
503 }
504
505 @Override
506 public void finish( TestCaseRunner testRunner, TestCaseRunContext testRunContext )
507 {
508 if( mockRunListener != null )
509 {
510 mockService.removeMockRunListener( mockRunListener );
511 mockRunListener = null;
512 }
513
514 if( testMockResponse != null )
515 {
516 if( startStepMockRunListener != null )
517 {
518 startStepMockRunListener.release();
519 startStepMockRunListener = null;
520 }
521
522 if( testMockResponse != mockResponse )
523 {
524 mockOperation.removeMockResponse( testMockResponse );
525 }
526
527 testMockResponse = null;
528 }
529
530 if( mockRunner != null )
531 {
532 if( mockRunner.isRunning() )
533 {
534 mockRunner.stop();
535 }
536
537 mockRunner = null;
538 }
539 }
540
541 private WsdlMockResult lastResult;
542
543 public WsdlMockResult getLastResult()
544 {
545 return lastResult;
546 }
547
548 public class InternalMockRunListener extends MockRunListenerAdapter
549 {
550 private boolean canceled;
551 private boolean waiting;
552
553 public synchronized void onMockResult( MockResult result )
554 {
555
556 if( WsdlMockResponseTestStep.this.lastResult == null && waiting
557 && result.getMockResponse() == testMockResponse )
558 {
559 waiting = false;
560
561
562 this.setResult( ( WsdlMockResult )result );
563
564
565
566
567
568
569
570 System.out.println( "Got mockrequest to [" + getName() + "]" );
571 synchronized( this )
572 {
573 notifyAll();
574 }
575 }
576 }
577
578 public void cancel()
579 {
580 canceled = true;
581 if( waiting )
582 {
583 synchronized( this )
584 {
585 notifyAll();
586 }
587 }
588
589 }
590
591 private void setResult( WsdlMockResult result )
592 {
593 WsdlMockResponseTestStep.this.lastResult = result;
594 }
595
596 public WsdlMockResult getResult()
597 {
598 return lastResult;
599 }
600
601 public boolean isCanceled()
602 {
603 return canceled;
604 }
605
606 public boolean hasResult()
607 {
608 return lastResult != null;
609 }
610
611 public boolean isWaiting()
612 {
613 return waiting;
614 }
615
616 public void setWaiting( boolean waiting )
617 {
618 this.waiting = waiting;
619 }
620
621 public void waitForRequest( long timeout ) throws InterruptedException
622 {
623 waiting = true;
624 wait( timeout );
625 }
626
627 @Override
628 public void onMockRunnerStart( MockRunner mockRunner )
629 {
630 waiting = false;
631 lastResult = null;
632 canceled = false;
633 }
634 }
635
636 public WsdlMockResponse getMockResponse()
637 {
638 return mockResponse;
639 }
640
641 public void setPort( int port )
642 {
643 int old = getPort();
644 mockService.setPort( port );
645 mockResponseStepConfig.setPort( port );
646 notifyPropertyChanged( "port", old, port );
647 }
648
649 public String getPath()
650 {
651 return mockResponseStepConfig.getPath();
652 }
653
654 public String getHost()
655 {
656 return mockResponseStepConfig.getHost();
657 }
658
659 public long getContentLength()
660 {
661 return mockResponse == null ? 0 : mockResponse.getContentLength();
662 }
663
664 public int getPort()
665 {
666 return mockResponseStepConfig.getPort();
667 }
668
669 public String getEncoding()
670 {
671 return mockResponse.getEncoding();
672 }
673
674 public void setEncoding( String encoding )
675 {
676 String old = getEncoding();
677 mockResponse.setEncoding( encoding );
678 notifyPropertyChanged( "encoding", old, encoding );
679 }
680
681 public boolean isMtomEnabled()
682 {
683 return mockResponse.isMtomEnabled();
684 }
685
686 public void setMtomEnabled( boolean enabled )
687 {
688 if( isMtomEnabled() == enabled )
689 return;
690 mockResponse.setMtomEnabled( enabled );
691
692 notifyPropertyChanged( "mtomEnabled", !enabled, enabled );
693 }
694
695 public String getOutgoingWss()
696 {
697 return mockResponse.getOutgoingWss();
698 }
699
700 public void setOutgoingWss( String outgoingWss )
701 {
702 String old = getOutgoingWss();
703 mockResponse.setOutgoingWss( outgoingWss );
704 notifyPropertyChanged( "outgoingWss", old, outgoingWss );
705 }
706
707 public void setQuery( String s )
708 {
709 String old = getQuery();
710 mockResponseStepConfig.setQuery( s );
711 notifyPropertyChanged( "query", old, s );
712 }
713
714 public String getQuery()
715 {
716 return mockResponseStepConfig.getQuery();
717 }
718
719 public String getMatch()
720 {
721 return mockResponseStepConfig.getMatch();
722 }
723
724 public void setMatch( String s )
725 {
726 String old = getMatch();
727 mockResponseStepConfig.setMatch( s );
728 notifyPropertyChanged( "match", old, s );
729 }
730
731 public boolean isForceMtom()
732 {
733 return mockResponse.isForceMtom();
734 }
735
736 public void setForceMtom( boolean forceMtom )
737 {
738 mockResponse.setForceMtom( forceMtom );
739 }
740
741 public boolean isInlineFilesEnabled()
742 {
743 return mockResponse.isInlineFilesEnabled();
744 }
745
746 public void setInlineFilesEnabled( boolean inlineFilesEnabled )
747 {
748 mockResponse.setInlineFilesEnabled( inlineFilesEnabled );
749 }
750
751 public String getStartStep()
752 {
753 return startTestStep == null ? "" : startTestStep.getName();
754 }
755
756 public void setStartStep( String startStep )
757 {
758 String old = getStartStep();
759 if( startTestStep != null )
760 {
761 startTestStep.removePropertyChangeListener( this );
762 startTestStep = null;
763 }
764
765 if( startStep != null )
766 {
767 startTestStep = getTestCase().getTestStepByName( startStep );
768 if( startTestStep != null )
769 {
770 startTestStep.addPropertyChangeListener( this );
771 }
772 }
773
774 mockResponseStepConfig.setStartStep( startStep );
775 notifyPropertyChanged( "startStep", old, startStep );
776 }
777
778 public boolean isMultipartEnabled()
779 {
780 return mockResponse.isMultipartEnabled();
781 }
782
783 public void setMultipartEnabled( boolean enabled )
784 {
785 mockResponse.setMultipartEnabled( enabled );
786 }
787
788 public boolean isHandleFault()
789 {
790 return mockResponseStepConfig.getHandleFault();
791 }
792
793 public void setHandleFault( boolean handleFault )
794 {
795 mockResponseStepConfig.setHandleFault( handleFault );
796 if( mockService != null )
797 mockService.setFaultMockOperation( handleFault ? mockOperation : null );
798 }
799
800 public boolean isHandleResponse()
801 {
802 return mockResponseStepConfig.getHandleResponse();
803 }
804
805 public void setHandleResponse( boolean handleResponse )
806 {
807 mockResponseStepConfig.setHandleResponse( handleResponse );
808 if( mockService != null )
809 mockService.setDispatchResponseMessages( handleResponse );
810 }
811
812 public long getResponseDelay()
813 {
814 return mockResponse.getResponseDelay();
815 }
816
817 public void setResponseDelay( long delay )
818 {
819 mockResponse.setResponseDelay( delay );
820 }
821
822 public String getResponseHttpStatus()
823 {
824 return mockResponse.getResponseHttpStatus();
825 }
826
827 public void setResponseHttpStatus( String httpStatus )
828 {
829 mockResponse.setResponseHttpStatus( httpStatus );
830 }
831
832 public boolean isEncodeAttachments()
833 {
834 return mockResponse.isEncodeAttachments();
835 }
836
837 public boolean isRemoveEmptyContent()
838 {
839 return mockResponse.isRemoveEmptyContent();
840 }
841
842 public boolean isStripWhitespaces()
843 {
844 return mockResponse.isStripWhitespaces();
845 }
846
847 public void setEncodeAttachments( boolean encodeAttachments )
848 {
849 mockResponse.setEncodeAttachments( encodeAttachments );
850 }
851
852 public void setRemoveEmptyContent( boolean removeEmptyContent )
853 {
854 mockResponse.setRemoveEmptyContent( removeEmptyContent );
855 }
856
857 public void setStripWhitespaces( boolean stripWhitespaces )
858 {
859 mockResponse.setStripWhitespaces( stripWhitespaces );
860 }
861
862 public void setPath( String path )
863 {
864 mockService.setPath( path );
865 mockResponseStepConfig.setPath( path );
866 }
867
868 public void setHost( String host )
869 {
870 mockService.setHost( host );
871 mockResponseStepConfig.setHost( host );
872 }
873
874 public void propertyChange( PropertyChangeEvent evt )
875 {
876 if( evt.getSource() == mockResponse || evt.getSource() == mockResponse.getWsaConfig() )
877 {
878 if( !evt.getPropertyName().equals( WsdlMockResponse.ICON_PROPERTY ) )
879 {
880 mockResponse.beforeSave();
881 mockResponseConfig.set( mockResponse.getConfig() );
882 }
883
884 notifyPropertyChanged( evt.getPropertyName(), evt.getOldValue(), evt.getNewValue() );
885 }
886 else if( evt.getSource() == getTestCase() && evt.getPropertyName().equals( "testSteps" )
887 && evt.getNewValue() == null && evt.getOldValue() == startTestStep && startTestStep != null )
888 {
889 setStartStep( null );
890 }
891 else if( evt.getSource() == startTestStep && evt.getPropertyName().equals( WsdlTestStep.NAME_PROPERTY ) )
892 {
893 mockResponseStepConfig.setStartStep( String.valueOf( evt.getNewValue() ) );
894 }
895 }
896
897 public WsdlMessageAssertion addAssertion( String assertionName )
898 {
899 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
900
901 try
902 {
903 TestAssertionConfig assertionConfig = mockResponseStepConfig.addNewAssertion();
904 assertionConfig.setType( TestAssertionRegistry.getInstance().getAssertionTypeForName( assertionName ) );
905
906 WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionConfig );
907 assertionsSupport.fireAssertionAdded( assertion );
908
909 if( getMockResponse().getMockResult() != null )
910 {
911 assertion.assertRequest( new WsdlMockResultMessageExchange( getMockResponse().getMockResult(),
912 getMockResponse() ), new WsdlSubmitContext( this ) );
913 notifier.notifyChange();
914 }
915
916 return assertion;
917 }
918 catch( Exception e )
919 {
920 SoapUI.logError( e );
921 return null;
922 }
923 }
924
925 public void addAssertionsListener( AssertionsListener listener )
926 {
927 assertionsSupport.addAssertionsListener( listener );
928 }
929
930 public WsdlMessageAssertion getAssertionAt( int c )
931 {
932 return assertionsSupport.getAssertionAt( c );
933 }
934
935 public int getAssertionCount()
936 {
937 return assertionsSupport.getAssertionCount();
938 }
939
940 public void removeAssertionsListener( AssertionsListener listener )
941 {
942 assertionsSupport.removeAssertionsListener( listener );
943 }
944
945 public AssertionStatus getAssertionStatus()
946 {
947 AssertionStatus currentStatus = AssertionStatus.UNKNOWN;
948 int cnt = getAssertionCount();
949 if( cnt == 0 )
950 return currentStatus;
951
952 if( mockResponse.getMockResult() != null )
953 {
954 if( mockResponse.getMockResult().getMockRequest() == null )
955 {
956 currentStatus = AssertionStatus.FAILED;
957 }
958 }
959 else
960 return currentStatus;
961
962 for( int c = 0; c < cnt; c++ )
963 {
964 WsdlMessageAssertion assertion = getAssertionAt( c );
965 if( assertion.isDisabled() )
966 continue;
967
968 if( assertion.getStatus() == AssertionStatus.FAILED )
969 {
970 currentStatus = AssertionStatus.FAILED;
971 break;
972 }
973 }
974
975 if( currentStatus == AssertionStatus.UNKNOWN )
976 currentStatus = AssertionStatus.VALID;
977
978 return currentStatus;
979 }
980
981 public void removeAssertion( TestAssertion assertion )
982 {
983 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
984
985 try
986 {
987 assertionsSupport.removeAssertion( ( WsdlMessageAssertion )assertion );
988 }
989 finally
990 {
991 ( ( WsdlMessageAssertion )assertion ).release();
992 notifier.notifyChange();
993 }
994 }
995
996 public TestAssertion moveAssertion( int ix, int offset )
997 {
998 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
999 WsdlMessageAssertion assertion = getAssertionAt( ix );
1000 try
1001 {
1002 return assertionsSupport.moveAssertion( ix, offset );
1003 }
1004 finally
1005 {
1006 ( ( WsdlMessageAssertion )assertion ).release();
1007 notifier.notifyChange();
1008 }
1009 }
1010
1011 public String getAssertableContent()
1012 {
1013 WsdlMockResult mockResult = getMockResponse().getMockResult();
1014 return mockResult == null ? null : mockResult.getMockRequest().getRequestContent();
1015 }
1016
1017 public TestStep getTestStep()
1018 {
1019 return this;
1020 }
1021
1022 @Override
1023 public void setName( String name )
1024 {
1025 super.setName( name );
1026 if( mockService != null )
1027 mockService.setName( getName() );
1028 }
1029
1030 public WsdlInterface getInterface()
1031 {
1032 return getOperation().getInterface();
1033 }
1034
1035 public WsdlOperation getOperation()
1036 {
1037 return getMockResponse().getMockOperation().getOperation();
1038 }
1039
1040 public void setInterface( String string )
1041 {
1042 WsdlInterface iface = ( WsdlInterface )getTestCase().getTestSuite().getProject().getInterfaceByName( string );
1043 if( iface != null )
1044 {
1045 mockResponseStepConfig.setInterface( iface.getName() );
1046 WsdlOperation operation = iface.getOperationAt( 0 );
1047 mockResponseStepConfig.setOperation( operation.getName() );
1048 mockOperation.setOperation( operation );
1049 }
1050 }
1051
1052 public void setOperation( String string )
1053 {
1054 WsdlOperation operation = getInterface().getOperationByName( string );
1055 if( operation != null )
1056 {
1057 mockResponseStepConfig.setOperation( string );
1058 mockOperation.setOperation( operation );
1059 }
1060 }
1061
1062 private class PropertyChangeNotifier
1063 {
1064 private AssertionStatus oldStatus;
1065 private ImageIcon oldIcon;
1066
1067 public PropertyChangeNotifier()
1068 {
1069 oldStatus = getAssertionStatus();
1070 oldIcon = getIcon();
1071 }
1072
1073 public void notifyChange()
1074 {
1075 AssertionStatus newStatus = getAssertionStatus();
1076 ImageIcon newIcon = getIcon();
1077
1078 if( oldStatus != newStatus )
1079 notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
1080
1081 if( oldIcon != newIcon )
1082 notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
1083 }
1084 }
1085
1086 @Override
1087 public void release()
1088 {
1089 super.release();
1090 assertionsSupport.release();
1091
1092 if( mockResponse != null )
1093 {
1094 mockResponse.removePropertyChangeListener( this );
1095 mockResponse.getWsaConfig().removePropertyChangeListener( this );
1096 }
1097
1098 if( mockService != null )
1099 {
1100 mockService.release();
1101 }
1102
1103 if( iface != null )
1104 {
1105 iface.getProject().removeProjectListener( projectListener );
1106 iface.removeInterfaceListener( interfaceListener );
1107 }
1108
1109 getTestCase().removeTestRunListener( testRunListener );
1110 getTestCase().removePropertyChangeListener( this );
1111
1112 if( startTestStep != null )
1113 {
1114 startTestStep.removePropertyChangeListener( this );
1115 }
1116
1117 if( lastResult != null )
1118 {
1119 lastResult = null;
1120 }
1121 }
1122
1123 public AssertableType getAssertableType()
1124 {
1125 return AssertableType.REQUEST;
1126 }
1127
1128 @Override
1129 public Collection<Interface> getRequiredInterfaces()
1130 {
1131 ArrayList<Interface> result = new ArrayList<Interface>();
1132 result.add( getInterface() );
1133 return result;
1134 }
1135
1136 public String getDefaultSourcePropertyName()
1137 {
1138 return "Response";
1139 }
1140
1141 public String getDefaultTargetPropertyName()
1142 {
1143 return "Request";
1144 }
1145
1146 @Override
1147 public void beforeSave()
1148 {
1149 super.beforeSave();
1150
1151 if( mockResponse != null )
1152 {
1153 mockResponse.beforeSave();
1154 mockResponseConfig.set( mockResponse.getConfig() );
1155 }
1156 }
1157
1158 public long getTimeout()
1159 {
1160 return mockResponseStepConfig.getTimeout();
1161 }
1162
1163 public void setTimeout( long timeout )
1164 {
1165 long old = getTimeout();
1166 mockResponseStepConfig.setTimeout( timeout );
1167 notifyPropertyChanged( TIMEOUT_PROPERTY, old, timeout );
1168 }
1169
1170 @Override
1171 public boolean dependsOn( AbstractWsdlModelItem<?> modelItem )
1172 {
1173 return modelItem == getOperation().getInterface();
1174 }
1175
1176 public class InternalProjectListener extends ProjectListenerAdapter
1177 {
1178 public void interfaceRemoved( Interface iface )
1179 {
1180 if( getOperation() != null && getOperation().getInterface().equals( iface ) )
1181 {
1182 log.debug( "Removing test step due to removed interface" );
1183 ( getTestCase() ).removeTestStep( WsdlMockResponseTestStep.this );
1184 }
1185 }
1186 }
1187
1188 public class InternalInterfaceListener extends InterfaceListenerAdapter
1189 {
1190 public void operationRemoved( Operation operation )
1191 {
1192 if( operation == getOperation() )
1193 {
1194 log.debug( "Removing test step due to removed operation" );
1195 ( getTestCase() ).removeTestStep( WsdlMockResponseTestStep.this );
1196 }
1197 }
1198
1199 @Override
1200 public void operationUpdated( Operation operation )
1201 {
1202 if( operation == getOperation() )
1203 {
1204 setOperation( operation.getName() );
1205 }
1206 }
1207 }
1208
1209 public WsdlMessageAssertion cloneAssertion( TestAssertion source, String name )
1210 {
1211 TestAssertionConfig conf = mockResponseStepConfig.addNewAssertion();
1212 conf.set( ( ( WsdlMessageAssertion )source ).getConfig() );
1213 conf.setName( name );
1214
1215 WsdlMessageAssertion result = assertionsSupport.addWsdlAssertion( conf );
1216 assertionsSupport.fireAssertionAdded( result );
1217 return result;
1218 }
1219
1220 public List<TestAssertion> getAssertionList()
1221 {
1222 return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
1223 }
1224
1225 @Override
1226 public List<? extends ModelItem> getChildren()
1227 {
1228 return assertionsSupport.getAssertionList();
1229 }
1230
1231 public PropertyExpansion[] getPropertyExpansions()
1232 {
1233 List<PropertyExpansion> result = new ArrayList<PropertyExpansion>();
1234
1235 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, mockResponse, "responseContent" ) );
1236
1237 StringToStringMap responseHeaders = mockResponse.getResponseHeaders();
1238 for( String key : responseHeaders.keySet() )
1239 {
1240 result.addAll( PropertyExpansionUtils.extractPropertyExpansions( this, new ResponseHeaderHolder(
1241 responseHeaders, key ), "value" ) );
1242 }
1243 mockResponse.addWsaPropertyExpansions( result, mockResponse.getWsaConfig(), this );
1244
1245 return result.toArray( new PropertyExpansion[result.size()] );
1246 }
1247
1248 public class ResponseHeaderHolder
1249 {
1250 private final StringToStringMap valueMap;
1251 private final String key;
1252
1253 public ResponseHeaderHolder( StringToStringMap valueMap, String key )
1254 {
1255 this.valueMap = valueMap;
1256 this.key = key;
1257 }
1258
1259 public String getValue()
1260 {
1261 return valueMap.get( key );
1262 }
1263
1264 public void setValue( String value )
1265 {
1266 valueMap.put( key, value );
1267 mockResponse.setResponseHeaders( valueMap );
1268 }
1269 }
1270
1271 public WsdlMessageAssertion getAssertionByName( String name )
1272 {
1273 return assertionsSupport.getAssertionByName( name );
1274 }
1275
1276 public Map<String, TestAssertion> getAssertions()
1277 {
1278 Map<String, TestAssertion> result = new HashMap<String, TestAssertion>();
1279
1280 for( TestAssertion assertion : getAssertionList() )
1281 result.put( assertion.getName(), assertion );
1282
1283 return result;
1284 }
1285
1286 private class AssertedWsdlMockResultMessageExchange extends WsdlMockResultMessageExchange implements
1287 RequestAssertedMessageExchange, AssertedXPathsContainer
1288 {
1289 private List<AssertedXPath> assertedXPaths;
1290
1291 public AssertedWsdlMockResultMessageExchange( WsdlMockResult mockResult )
1292 {
1293 super( mockResult, mockResult == null ? null : mockResult.getMockResponse() );
1294 }
1295
1296 public AssertedXPath[] getAssertedXPathsForRequest()
1297 {
1298 return assertedXPaths == null ? new AssertedXPath[0] : assertedXPaths
1299 .toArray( new AssertedXPath[assertedXPaths.size()] );
1300 }
1301
1302 public void addAssertedXPath( AssertedXPath assertedXPath )
1303 {
1304 if( assertedXPaths == null )
1305 assertedXPaths = new ArrayList<AssertedXPath>();
1306
1307 assertedXPaths.add( assertedXPath );
1308 }
1309 }
1310
1311 public String getDefaultAssertableContent()
1312 {
1313 return getOperation().createRequest( true );
1314 }
1315
1316 @SuppressWarnings( "unchecked" )
1317 @Override
1318 public void resolve( ResolveContext<?> context )
1319 {
1320 super.resolve( context );
1321
1322 if( mockOperation == null )
1323 {
1324 if( context.hasThisModelItem( this, "Missing Operation in Project", mockResponseStepConfig.getInterface()
1325 + "/" + mockResponseStepConfig.getOperation() ) )
1326 return;
1327 context.addPathToResolve( this, "Missing Operation in Project",
1328 mockResponseStepConfig.getInterface() + "/" + mockResponseStepConfig.getOperation() ).addResolvers(
1329 new RemoveTestStepResolver( this ), new ImportInterfaceResolver( this )
1330 {
1331
1332 @Override
1333 protected boolean update()
1334 {
1335 initMockObjects( getTestCase() );
1336 initProperties();
1337 setDisabled( false );
1338 return true;
1339 }
1340 }, new ChangeOperationResolver( this, "Operation" )
1341 {
1342
1343 @Override
1344 public boolean update()
1345 {
1346 WsdlOperation operation = ( WsdlOperation )getSelectedOperation();
1347 setInterface( operation.getInterface().getName() );
1348 setOperation( operation.getName() );
1349 initMockObjects( getTestCase() );
1350 initProperties();
1351 setDisabled( false );
1352 return true;
1353 }
1354
1355 protected Interface[] getInterfaces( WsdlProject project )
1356 {
1357 List<WsdlInterface> interfaces = ModelSupport.getChildren( project, WsdlInterface.class );
1358 return interfaces.toArray( new Interface[interfaces.size()] );
1359
1360 }
1361
1362 } );
1363 }
1364 else
1365 {
1366 mockOperation.resolve( context );
1367 if( context.hasThisModelItem( this, "Missing Operation in Project", mockResponseStepConfig.getInterface()
1368 + "/" + mockResponseStepConfig.getOperation() ) )
1369 {
1370 PathToResolve path = context.getPath( this, "Missing Operation in Project", mockResponseStepConfig
1371 .getInterface()
1372 + "/" + mockResponseStepConfig.getOperation() );
1373 path.setSolved( true );
1374 }
1375 }
1376 }
1377
1378 private class InternalTestRunListener extends TestRunListenerAdapter
1379 {
1380 @Override
1381 public void beforeStep( TestCaseRunner testRunner, TestCaseRunContext runContext, TestStep testStep )
1382 {
1383 if( runContext.getCurrentStep() == startTestStep && testMockResponse == null )
1384 {
1385 if( startTestStep instanceof WsdlMockResponseTestStep )
1386 {
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404 }
1405 else
1406 {
1407 initTestMockResponse( runContext );
1408 mockRunListener.setWaiting( true );
1409 }
1410 }
1411 }
1412 }
1413
1414 private class StartStepMockRunListener extends MockRunListenerAdapter
1415 {
1416 private TestCaseRunContext runContext;
1417 private WsdlMockService mockService;
1418
1419 public StartStepMockRunListener( TestCaseRunContext runContext, WsdlMockResponseTestStep wsdlMockResponseTestStep )
1420 {
1421 this.runContext = runContext;
1422 mockService = wsdlMockResponseTestStep.getMockResponse().getMockOperation().getMockService();
1423 mockService.addMockRunListener( this );
1424 }
1425
1426 @Override
1427 public void onMockResult( MockResult result )
1428 {
1429 System.out.println( "Starting to listen for request to " + getName() );
1430 initTestMockResponse( runContext );
1431 mockRunListener.setWaiting( true );
1432 }
1433
1434 public void release()
1435 {
1436 mockService.removeMockRunListener( this );
1437 mockService = null;
1438 runContext = null;
1439 }
1440 }
1441
1442 }