1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import com.eviware.soapui.config.RequestStepConfig;
16 import com.eviware.soapui.config.TestStepConfig;
17 import com.eviware.soapui.impl.support.AbstractHttpRequest;
18 import com.eviware.soapui.impl.support.http.HttpRequestTestStep;
19 import com.eviware.soapui.impl.wsdl.*;
20 import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
21 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
22 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
23 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
24 import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
25 import com.eviware.soapui.model.ModelItem;
26 import com.eviware.soapui.model.iface.Interface;
27 import com.eviware.soapui.model.iface.Operation;
28 import com.eviware.soapui.model.iface.Request.SubmitException;
29 import com.eviware.soapui.model.iface.Submit;
30 import com.eviware.soapui.model.project.Project;
31 import com.eviware.soapui.model.propertyexpansion.PropertyExpansion;
32 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionContainer;
33 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
34 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionsResult;
35 import com.eviware.soapui.model.support.InterfaceListenerAdapter;
36 import com.eviware.soapui.model.support.ModelSupport;
37 import com.eviware.soapui.model.support.ProjectListenerAdapter;
38 import com.eviware.soapui.model.support.TestStepBeanProperty;
39 import com.eviware.soapui.model.testsuite.*;
40 import com.eviware.soapui.model.testsuite.AssertionError;
41 import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
42 import com.eviware.soapui.support.resolver.ChangeOperationResolver;
43 import com.eviware.soapui.support.resolver.ImportInterfaceResolver;
44 import com.eviware.soapui.support.resolver.RemoveTestStepResolver;
45 import com.eviware.soapui.support.resolver.ResolveContext;
46 import com.eviware.soapui.support.resolver.ResolveContext.PathToResolve;
47 import com.eviware.soapui.support.types.StringToStringMap;
48 import org.apache.log4j.Logger;
49
50 import javax.swing.*;
51 import java.beans.PropertyChangeEvent;
52 import java.beans.PropertyChangeListener;
53 import java.util.*;
54
55 /***
56 * WsdlTestStep that executes a WsdlTestRequest
57 *
58 * @author Ole.Matzura
59 */
60
61 public class WsdlTestRequestStep extends WsdlTestStepWithProperties implements OperationTestStep,
62 PropertyChangeListener, PropertyExpansionContainer, Assertable, HttpRequestTestStep
63 {
64 private final static Logger log = Logger.getLogger( WsdlTestRequestStep.class );
65 private RequestStepConfig requestStepConfig;
66 private WsdlTestRequest testRequest;
67 private WsdlOperation wsdlOperation;
68 private final InternalProjectListener projectListener = new InternalProjectListener();
69 private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
70 private WsdlSubmit<WsdlRequest> submit;
71
72 public WsdlTestRequestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
73 {
74 super( testCase, config, true, forLoadTest );
75
76 if( getConfig().getConfig() != null )
77 {
78 requestStepConfig = (RequestStepConfig) getConfig().getConfig().changeType( RequestStepConfig.type );
79
80 wsdlOperation = findWsdlOperation();
81 if( wsdlOperation == null )
82 {
83 log.error( "Could not find operation [" + requestStepConfig.getOperation() + "] in interface ["
84 + requestStepConfig.getInterface() + "] for test request [" + getName() + "] in TestCase ["
85 + getTestCase().getTestSuite().getName() + "/" + getTestCase().getName() + "]" );
86
87 setDisabled( true );
88 }
89 else
90 {
91 initTestRequest( config, forLoadTest );
92 }
93 }
94 else
95 {
96 requestStepConfig = (RequestStepConfig) getConfig().addNewConfig().changeType( RequestStepConfig.type );
97 }
98
99
100 if( testRequest != null )
101 {
102 initRequestProperties();
103 }
104 }
105
106 private void initRequestProperties()
107 {
108 addProperty( new TestStepBeanProperty( "Endpoint", false, testRequest, "endpoint", this ) );
109 addProperty( new TestStepBeanProperty( "Username", false, testRequest, "username", this ) );
110 addProperty( new TestStepBeanProperty( "Password", false, testRequest, "password", this ) );
111 addProperty( new TestStepBeanProperty( "Domain", false, testRequest, "domain", this ) );
112 addProperty( new TestStepBeanProperty( "Request", false, testRequest, "requestContent", this )
113 {
114 @Override
115 public String getDefaultValue()
116 {
117 return getOperation().createRequest( true );
118 }
119 } );
120 addProperty( new TestStepBeanProperty( "Response", true, testRequest, "responseContent", this )
121 {
122 @Override
123 public String getDefaultValue()
124 {
125 return getOperation().createResponse( true );
126 }
127 } );
128 }
129
130 private void initTestRequest( TestStepConfig config, boolean forLoadTest )
131 {
132 if( !forLoadTest )
133 {
134 wsdlOperation.getInterface().getProject().addProjectListener( projectListener );
135 wsdlOperation.getInterface().addInterfaceListener( interfaceListener );
136
137
138
139 wsdlOperation.getInterface().addPropertyChangeListener( this );
140 wsdlOperation.addPropertyChangeListener( this );
141 }
142
143 testRequest = new WsdlTestRequest( wsdlOperation, requestStepConfig.getRequest(), this, forLoadTest );
144 testRequest.addPropertyChangeListener( this );
145
146 if( config.isSetName() )
147 testRequest.setName( config.getName() );
148 else
149 config.setName( testRequest.getName() );
150 }
151
152 @Override
153 public WsdlTestStep clone( WsdlTestCase targetTestCase, String name )
154 {
155 beforeSave();
156
157 TestStepConfig config = (TestStepConfig) getConfig().copy();
158 RequestStepConfig stepConfig = (RequestStepConfig) config.getConfig().changeType( RequestStepConfig.type );
159
160 while( stepConfig.getRequest().sizeOfAttachmentArray() > 0 )
161 stepConfig.getRequest().removeAttachment( 0 );
162
163 config.setName( name );
164 stepConfig.getRequest().setName( name );
165
166 WsdlTestRequestStep result = (WsdlTestRequestStep) targetTestCase.addTestStep( config );
167 testRequest.copyAttachmentsTo( result.getTestRequest() );
168
169 return result;
170 }
171
172 private WsdlOperation findWsdlOperation()
173 {
174 WsdlTestCase testCase = getTestCase();
175 if( testCase == null || testCase.getTestSuite() == null )
176 return null;
177
178 Project project = testCase.getTestSuite().getProject();
179 WsdlOperation operation = null;
180 for( int c = 0; c < project.getInterfaceCount(); c++ )
181 {
182 if( project.getInterfaceAt( c ).getName().equals( requestStepConfig.getInterface() ) )
183 {
184 WsdlInterface iface = (WsdlInterface) project.getInterfaceAt( c );
185 for( int i = 0; i < iface.getOperationCount(); i++ )
186 {
187 if( iface.getOperationAt( i ).getName().equals( requestStepConfig.getOperation() ) )
188 {
189 operation = iface.getOperationAt( i );
190 break;
191 }
192 }
193
194 if( operation != null )
195 break;
196 }
197 }
198 return operation;
199 }
200
201 public String getInterfaceName()
202 {
203 return requestStepConfig.getInterface();
204 }
205
206 public String getOperationName()
207 {
208 return requestStepConfig.getOperation();
209 }
210
211 @Override
212 public void release()
213 {
214 super.release();
215
216 if( wsdlOperation == null )
217 wsdlOperation = findWsdlOperation();
218
219 if( wsdlOperation != null )
220 {
221 wsdlOperation.removePropertyChangeListener( this );
222 wsdlOperation.getInterface().getProject().removeProjectListener( projectListener );
223 wsdlOperation.getInterface().removeInterfaceListener( interfaceListener );
224 wsdlOperation.getInterface().removePropertyChangeListener( this );
225 }
226
227
228 if( testRequest != null )
229 {
230 testRequest.removePropertyChangeListener( this );
231 testRequest.release();
232 }
233 }
234
235 @Override
236 public void resetConfigOnMove( TestStepConfig config )
237 {
238 super.resetConfigOnMove( config );
239
240 requestStepConfig = (RequestStepConfig) config.getConfig().changeType( RequestStepConfig.type );
241 testRequest.updateConfig( requestStepConfig.getRequest() );
242 }
243
244 @Override
245 public ImageIcon getIcon()
246 {
247 return testRequest == null ? null : testRequest.getIcon();
248 }
249
250 public WsdlTestRequest getTestRequest()
251 {
252 return testRequest;
253 }
254
255 @Override
256 public void setName( String name )
257 {
258 super.setName( name );
259 testRequest.setName( name );
260 }
261
262 public void propertyChange( PropertyChangeEvent arg0 )
263 {
264 if( arg0.getSource() == wsdlOperation )
265 {
266 if( arg0.getPropertyName().equals( Operation.NAME_PROPERTY ) )
267 {
268 requestStepConfig.setOperation( (String) arg0.getNewValue() );
269 }
270 }
271 else if( arg0.getSource() == wsdlOperation.getInterface() )
272 {
273 if( arg0.getPropertyName().equals( Interface.NAME_PROPERTY ) )
274 {
275 requestStepConfig.setInterface( (String) arg0.getNewValue() );
276 }
277 }
278 else if( arg0.getPropertyName().equals( TestAssertion.CONFIGURATION_PROPERTY )
279 || arg0.getPropertyName().equals( TestAssertion.DISABLED_PROPERTY ) )
280 {
281 if( getTestRequest().getResponse() != null )
282 {
283 getTestRequest().assertResponse( new WsdlTestRunContext( this ) );
284 }
285 }
286 else
287 {
288 if( arg0.getSource() == testRequest && arg0.getPropertyName().equals( WsdlTestRequest.NAME_PROPERTY ) )
289 {
290 if( !super.getName().equals( (String) arg0.getNewValue() ) )
291 super.setName( (String) arg0.getNewValue() );
292 }
293
294 notifyPropertyChanged( arg0.getPropertyName(), arg0.getOldValue(), arg0.getNewValue() );
295 }
296 }
297
298 public TestStepResult run( TestRunner runner, TestRunContext runContext )
299 {
300 WsdlTestRequestStepResult testStepResult = new WsdlTestRequestStepResult( this );
301
302 try
303 {
304 submit = testRequest.submit( runContext, false );
305 WsdlResponse response = (WsdlResponse) submit.getResponse();
306
307 if( submit.getStatus() != Submit.Status.CANCELED )
308 {
309 if( submit.getStatus() == Submit.Status.ERROR )
310 {
311 testStepResult.setStatus( TestStepStatus.FAILED );
312 testStepResult.addMessage( submit.getError().toString() );
313
314 testRequest.setResponse( null, runContext );
315 }
316 else if( response == null )
317 {
318 testStepResult.setStatus( TestStepStatus.FAILED );
319 testStepResult.addMessage( "Request is missing response" );
320
321 testRequest.setResponse( null, runContext );
322 }
323 else
324 {
325 runContext.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, testStepResult );
326 testRequest.setResponse( response, runContext );
327
328 testStepResult.setTimeTaken( response.getTimeTaken() );
329 testStepResult.setSize( response.getContentLength() );
330 testStepResult.setResponse( response );
331
332 switch( testRequest.getAssertionStatus() )
333 {
334 case FAILED:
335 testStepResult.setStatus( TestStepStatus.FAILED );
336 break;
337 case VALID:
338 testStepResult.setStatus( TestStepStatus.OK );
339 break;
340 case UNKNOWN:
341 testStepResult.setStatus( TestStepStatus.UNKNOWN );
342 break;
343 }
344 }
345 }
346 else
347 {
348 testStepResult.setStatus( TestStepStatus.CANCELED );
349 testStepResult.addMessage( "Request was canceled" );
350 }
351
352 if( response != null )
353 testStepResult.setRequestContent( response.getRequestContent() );
354 else
355 testStepResult.setRequestContent( testRequest.getRequestContent() );
356 }
357 catch( SubmitException e )
358 {
359 testStepResult.setStatus( TestStepStatus.FAILED );
360 testStepResult.addMessage( "SubmitException: " + e );
361 }
362 finally
363 {
364 submit = null;
365 }
366
367 testStepResult.setDomain( PropertyExpansionUtils.expandProperties( runContext, testRequest.getDomain() ) );
368 testStepResult.setUsername( PropertyExpansionUtils.expandProperties( runContext, testRequest.getUsername() ) );
369 testStepResult.setPassword( PropertyExpansionUtils.expandProperties( runContext, testRequest.getPassword() ) );
370 testStepResult.setEndpoint( PropertyExpansionUtils.expandProperties( runContext, testRequest.getEndpoint() ) );
371 testStepResult.setEncoding( PropertyExpansionUtils.expandProperties( runContext, testRequest.getEncoding() ) );
372
373 if( testStepResult.getStatus() != TestStepStatus.CANCELED )
374 {
375 AssertionStatus assertionStatus = testRequest.getAssertionStatus();
376 switch( assertionStatus )
377 {
378 case FAILED:
379 {
380 testStepResult.setStatus( TestStepStatus.FAILED );
381 if( getAssertionCount() == 0 )
382 {
383 testStepResult.addMessage( "Invalid/empty response" );
384 }
385 else
386 for( int c = 0; c < getAssertionCount(); c++ )
387 {
388 AssertionError[] errors = getAssertionAt( c ).getErrors();
389 if( errors != null )
390 {
391 for( AssertionError error : errors )
392 {
393 testStepResult.addMessage( error.getMessage() );
394 }
395 }
396 }
397
398 break;
399 }
400
401 }
402 }
403
404 return testStepResult;
405 }
406
407 public WsdlMessageAssertion getAssertionAt( int index )
408 {
409 return testRequest.getAssertionAt( index );
410 }
411
412 public int getAssertionCount()
413 {
414 return testRequest == null ? 0 : testRequest.getAssertionCount();
415 }
416
417 public AbstractHttpRequest<?> getHttpRequest()
418 {
419 return testRequest;
420 }
421
422 public class InternalProjectListener extends ProjectListenerAdapter
423 {
424 @Override
425 public void interfaceRemoved( Interface iface )
426 {
427 if( wsdlOperation != null && wsdlOperation.getInterface().equals( iface ) )
428 {
429 log.debug( "Removing test step due to removed interface" );
430 ( getTestCase() ).removeTestStep( WsdlTestRequestStep.this );
431 }
432 }
433 }
434
435 public class InternalInterfaceListener extends InterfaceListenerAdapter
436 {
437 @Override
438 public void operationRemoved( Operation operation )
439 {
440 if( operation == wsdlOperation )
441 {
442 log.debug( "Removing test step due to removed operation" );
443 ( getTestCase() ).removeTestStep( WsdlTestRequestStep.this );
444 }
445 }
446
447 @Override
448 public void operationUpdated( Operation operation )
449 {
450 if( operation == wsdlOperation )
451 {
452 requestStepConfig.setOperation( operation.getName() );
453 }
454 }
455 }
456
457 @Override
458 public boolean cancel()
459 {
460 if( submit == null )
461 return false;
462
463 submit.cancel();
464
465 return true;
466 }
467
468 @Override
469 public Collection<WsdlInterface> getRequiredInterfaces()
470 {
471 ArrayList<WsdlInterface> result = new ArrayList<WsdlInterface>();
472 result.add( findWsdlOperation().getInterface() );
473 return result;
474 }
475
476 public String getDefaultSourcePropertyName()
477 {
478 return "Response";
479 }
480
481 public String getDefaultTargetPropertyName()
482 {
483 return "Request";
484 }
485
486 @Override
487 public boolean dependsOn( AbstractWsdlModelItem<?> modelItem )
488 {
489 if( modelItem instanceof Interface && testRequest.getOperation().getInterface() == modelItem )
490 {
491 return true;
492 }
493 else if( modelItem instanceof Operation && testRequest.getOperation() == modelItem )
494 {
495 return true;
496 }
497
498 return false;
499 }
500
501 @Override
502 public void beforeSave()
503 {
504 super.beforeSave();
505
506 if( testRequest != null )
507 testRequest.beforeSave();
508 }
509
510 @Override
511 public String getDescription()
512 {
513 return testRequest == null ? "<missing>" : testRequest.getDescription();
514 }
515
516 @Override
517 public void setDescription( String description )
518 {
519 if( testRequest != null )
520 testRequest.setDescription( description );
521 }
522
523 public void setOperation( WsdlOperation operation )
524 {
525 if( wsdlOperation == operation )
526 return;
527
528 WsdlOperation oldOperation = wsdlOperation;
529 wsdlOperation = operation;
530 requestStepConfig.setInterface( operation.getInterface().getName() );
531 requestStepConfig.setOperation( operation.getName() );
532
533 if( oldOperation != null )
534 oldOperation.removePropertyChangeListener( this );
535
536 wsdlOperation.addPropertyChangeListener( this );
537
538 testRequest.setOperation( wsdlOperation );
539 }
540
541 @SuppressWarnings( "unchecked" )
542 @Override
543 public List<? extends ModelItem> getChildren()
544 {
545 return testRequest == null ? Collections.EMPTY_LIST : testRequest.getAssertionList();
546 }
547
548 public PropertyExpansion[] getPropertyExpansions()
549 {
550 PropertyExpansionsResult result = new PropertyExpansionsResult( this, testRequest );
551
552 result.extractAndAddAll( "requestContent" );
553 result.extractAndAddAll( "endpoint" );
554 result.extractAndAddAll( "username" );
555 result.extractAndAddAll( "password" );
556 result.extractAndAddAll( "domain" );
557
558 StringToStringMap requestHeaders = testRequest.getRequestHeaders();
559 for( String key : requestHeaders.keySet() )
560 {
561 result.extractAndAddAll( new RequestHeaderHolder( requestHeaders, key ), "value" );
562 }
563
564
565
566 return result.toArray( new PropertyExpansion[result.size()] );
567 }
568
569 public class RequestHeaderHolder
570 {
571 private final StringToStringMap valueMap;
572 private final String key;
573
574 public RequestHeaderHolder( StringToStringMap valueMap, String key )
575 {
576 this.valueMap = valueMap;
577 this.key = key;
578 }
579
580 public String getValue()
581 {
582 return valueMap.get( key );
583 }
584
585 public void setValue( String value )
586 {
587 valueMap.put( key, value );
588 testRequest.setRequestHeaders( valueMap );
589 }
590 }
591
592 public TestAssertion addAssertion( String type )
593 {
594 WsdlMessageAssertion result = testRequest.addAssertion( type );
595 return result;
596 }
597
598 public void addAssertionsListener( AssertionsListener listener )
599 {
600 testRequest.addAssertionsListener( listener );
601 }
602
603 public TestAssertion cloneAssertion( TestAssertion source, String name )
604 {
605 return testRequest.cloneAssertion( source, name );
606 }
607
608 public String getAssertableContent()
609 {
610 return testRequest.getAssertableContent();
611 }
612
613 public AssertableType getAssertableType()
614 {
615 return testRequest.getAssertableType();
616 }
617
618 public TestAssertion getAssertionByName( String name )
619 {
620 return testRequest.getAssertionByName( name );
621 }
622
623 public List<TestAssertion> getAssertionList()
624 {
625 return testRequest.getAssertionList();
626 }
627
628 public AssertionStatus getAssertionStatus()
629 {
630 return testRequest.getAssertionStatus();
631 }
632
633 public Interface getInterface()
634 {
635 return getOperation().getInterface();
636 }
637
638 public WsdlOperation getOperation()
639 {
640 return wsdlOperation;
641 }
642
643 public TestStep getTestStep()
644 {
645 return this;
646 }
647
648 public void removeAssertion( TestAssertion assertion )
649 {
650 testRequest.removeAssertion( assertion );
651 }
652
653 public void removeAssertionsListener( AssertionsListener listener )
654 {
655 testRequest.removeAssertionsListener( listener );
656 }
657
658 public Map<String, TestAssertion> getAssertions()
659 {
660 return testRequest.getAssertions();
661 }
662
663 @Override
664 public void prepare( TestRunner testRunner, TestRunContext testRunContext ) throws Exception
665 {
666 super.prepare( testRunner, testRunContext );
667
668 for( TestAssertion assertion : testRequest.getAssertionList() )
669 {
670 assertion.prepare( testRunner, testRunContext );
671 }
672 }
673
674 public String getDefaultAssertableContent()
675 {
676 return testRequest.getDefaultAssertableContent();
677 }
678
679 @SuppressWarnings( "unchecked" )
680 public void resolve( ResolveContext context )
681 {
682 super.resolve( context );
683
684 if( wsdlOperation == null )
685 {
686
687 if( context.hasThisModelItem( this, "Missing SOAP Operation in Project", requestStepConfig.getInterface() + "/"
688 + requestStepConfig.getOperation() ) )
689 return;
690
691 context.addPathToResolve( this, "Missing SOAP Operation in Project",
692 requestStepConfig.getInterface() + "/" + requestStepConfig.getOperation() ).addResolvers(
693 new RemoveTestStepResolver( this ), new ImportInterfaceResolver( this )
694 {
695
696 @Override
697 protected boolean update()
698 {
699 wsdlOperation = findWsdlOperation();
700 if( wsdlOperation == null )
701 return false;
702
703 initTestRequest( getConfig(), false );
704 initRequestProperties();
705 setDisabled( false );
706 return true;
707 }
708 }, new ChangeOperationResolver( this, "Operation" )
709 {
710
711 @Override
712 public boolean update()
713 {
714 wsdlOperation = (WsdlOperation) getSelectedOperation();
715 if( wsdlOperation == null )
716 return false;
717
718 initTestRequest( getConfig(), false );
719 initRequestProperties();
720 setDisabled( false );
721 return true;
722 }
723
724 protected Interface[] getInterfaces( WsdlProject project )
725 {
726 List<WsdlInterface> interfaces = ModelSupport.getChildren( project, WsdlInterface.class );
727 return interfaces.toArray( new Interface[interfaces.size()] );
728
729 }
730
731 } );
732 }
733 else
734 {
735 testRequest.resolve( context );
736 if( context.hasThisModelItem( this, "Missing SOAP Operation in Project", requestStepConfig.getInterface() + "/"
737 + requestStepConfig.getOperation() ) )
738 {
739 PathToResolve path = context.getPath( this, "Missing SOAP Operation in Project", requestStepConfig
740 .getInterface()
741 + "/" + requestStepConfig.getOperation() );
742 path.setSolved( true );
743 }
744 }
745 }
746 }