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