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