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