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