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