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