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