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