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