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