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