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