View Javadoc

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        // init default properties
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        // init properties
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       // could be null if initialization failed..
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 //		result.addAll( testRequest.getWssContainer().getPropertyExpansions() );
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 }