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