View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2008 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of version 2.1 of the GNU Lesser General Public License as published by 
6    *  the Free Software Foundation.
7    *
8    *  soapUI is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 
9    *  even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
10   *  See the GNU Lesser General Public License for more details at gnu.org.
11   */
12  
13  package com.eviware.soapui.impl.wsdl.teststeps;
14  
15  import com.eviware.soapui.SoapUI;
16  import com.eviware.soapui.config.RestMethodConfig;
17  import com.eviware.soapui.config.TestAssertionConfig;
18  import com.eviware.soapui.impl.rest.RestRequest;
19  import com.eviware.soapui.impl.rest.RestResource;
20  import com.eviware.soapui.impl.rest.RestService;
21  import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
22  import com.eviware.soapui.impl.wsdl.submit.transports.http.HttpResponse;
23  import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
24  import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
25  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
26  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
27  import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
28  import com.eviware.soapui.model.ModelItem;
29  import com.eviware.soapui.model.iface.Submit;
30  import com.eviware.soapui.model.iface.SubmitContext;
31  import com.eviware.soapui.model.testsuite.Assertable;
32  import com.eviware.soapui.model.testsuite.AssertionsListener;
33  import com.eviware.soapui.model.testsuite.TestAssertion;
34  import com.eviware.soapui.monitor.TestMonitor;
35  import com.eviware.soapui.support.UISupport;
36  import com.eviware.soapui.support.resolver.ResolveContext;
37  
38  import javax.swing.*;
39  import java.util.ArrayList;
40  import java.util.List;
41  import java.util.Map;
42  
43  public class RestTestRequest extends RestRequest implements Assertable, TestRequest
44  {
45     public static final String RESPONSE_PROPERTY = RestTestRequest.class.getName() + "@response";
46     public static final String STATUS_PROPERTY = RestTestRequest.class.getName() + "@status";
47  
48     private ImageIcon validRequestIcon;
49     private ImageIcon failedRequestIcon;
50     private ImageIcon disabledRequestIcon;
51     private ImageIcon unknownRequestIcon;
52  
53     private AssertionStatus currentStatus;
54     private HttpTestRequestStep testStep;
55  
56     private AssertionsSupport assertionsSupport;
57     private RestResponseMessageExchange messageExchange;
58     private final boolean forLoadTest;
59     private PropertyChangeNotifier notifier;
60     private RestResource restResource;
61  
62     public RestTestRequest(
63             RestResource resource, RestMethodConfig callConfig, HttpTestRequestStep testStep,
64             boolean forLoadTest
65     )
66     {
67        super( resource, callConfig, forLoadTest );
68        this.forLoadTest = forLoadTest;
69  
70        setSettings( new XmlBeansSettingsImpl( this, testStep.getSettings(), callConfig.getSettings() ) );
71  
72        this.testStep = testStep;
73  
74        initAssertions();
75        initIcons();
76     }
77  
78     public ModelItem getParent()
79     {
80        return getTestStep();
81     }
82  
83     public WsdlTestCase getTestCase()
84     {
85        return testStep.getTestCase();
86     }
87  
88     protected void initIcons()
89     {
90        boolean isRest = getTestStep() instanceof RestTestRequestStep;
91  
92        validRequestIcon = !isRest ? UISupport.createImageIcon( "/valid_http_request.gif" ) :
93                UISupport.createImageIcon( "/valid_rest_request.gif" );
94  
95        failedRequestIcon = !isRest ? UISupport.createImageIcon( "/invalid_http_request.gif" ) :
96                UISupport.createImageIcon( "/invalid_rest_request.gif" );
97  
98        unknownRequestIcon = !isRest ? UISupport.createImageIcon( "/unknown_http_request.gif" ) :
99                UISupport.createImageIcon( "/unknown_rest_request.gif" );
100 
101       disabledRequestIcon = !isRest ? UISupport.createImageIcon( "/disabled_http_request.gif" ) :
102               UISupport.createImageIcon( "/disabled_rest_request.gif" );
103 
104       setIconAnimator( new TestRequestIconAnimator( this ) );
105    }
106 
107    private void initAssertions()
108    {
109       assertionsSupport = new AssertionsSupport( testStep, new AssertableConfig()
110       {
111          public TestAssertionConfig addNewAssertion()
112          {
113             return getConfig().addNewAssertion();
114          }
115 
116          public List<TestAssertionConfig> getAssertionList()
117          {
118             return getConfig().getAssertionList();
119          }
120 
121          public void removeAssertion( int ix )
122          {
123             getConfig().removeAssertion( ix );
124          }
125       } );
126    }
127 
128    public int getAssertionCount()
129    {
130       return assertionsSupport.getAssertionCount();
131    }
132 
133    public WsdlMessageAssertion getAssertionAt( int c )
134    {
135       return assertionsSupport.getAssertionAt( c );
136    }
137 
138    public void setResponse( HttpResponse response, SubmitContext context )
139    {
140       HttpResponse oldResponse = getResponse();
141       super.setResponse( response, context );
142 
143       if( response != oldResponse )
144          assertResponse( context );
145    }
146 
147    public void assertResponse( SubmitContext context )
148    {
149       if( notifier == null )
150          notifier = new PropertyChangeNotifier();
151 
152       messageExchange = new RestResponseMessageExchange( this );
153 
154       // assert!
155       for( WsdlMessageAssertion assertion : assertionsSupport.getAssertionList() )
156       {
157          assertion.assertResponse( messageExchange, context );
158       }
159 
160       notifier.notifyChange();
161    }
162 
163    private class PropertyChangeNotifier
164    {
165       private AssertionStatus oldStatus;
166       private ImageIcon oldIcon;
167 
168       public PropertyChangeNotifier()
169       {
170          oldStatus = getAssertionStatus();
171          oldIcon = getIcon();
172       }
173 
174       public void notifyChange()
175       {
176          AssertionStatus newStatus = getAssertionStatus();
177          ImageIcon newIcon = getIcon();
178 
179          if( oldStatus != newStatus )
180             notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
181 
182          if( oldIcon != newIcon )
183             notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
184 
185          oldStatus = newStatus;
186          oldIcon = newIcon;
187       }
188    }
189 
190    public WsdlMessageAssertion addAssertion( String assertionLabel )
191    {
192       PropertyChangeNotifier notifier = new PropertyChangeNotifier();
193 
194       try
195       {
196          WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionLabel );
197          if( assertion == null )
198             return null;
199 
200          if( getResponse() != null )
201          {
202             assertion.assertResponse( new RestResponseMessageExchange( this ), new WsdlTestRunContext( testStep ) );
203             notifier.notifyChange();
204          }
205 
206          return assertion;
207       }
208       catch( Exception e )
209       {
210          SoapUI.logError( e );
211          return null;
212       }
213    }
214 
215    public void removeAssertion( TestAssertion assertion )
216    {
217       PropertyChangeNotifier notifier = new PropertyChangeNotifier();
218 
219       try
220       {
221          assertionsSupport.removeAssertion( (WsdlMessageAssertion) assertion );
222 
223       }
224       finally
225       {
226          ( (WsdlMessageAssertion) assertion ).release();
227          notifier.notifyChange();
228       }
229    }
230 
231    public AssertionStatus getAssertionStatus()
232    {
233       currentStatus = AssertionStatus.UNKNOWN;
234 
235       if( messageExchange != null )
236       {
237          if( !messageExchange.hasResponse() &&
238                  getOperation().isBidirectional() )
239          {
240             currentStatus = AssertionStatus.FAILED;
241          }
242       }
243       else
244          return currentStatus;
245 
246       int cnt = getAssertionCount();
247       if( cnt == 0 )
248          return currentStatus;
249 
250       for( int c = 0; c < cnt; c++ )
251       {
252          if( getAssertionAt( c ).getStatus() == AssertionStatus.FAILED )
253          {
254             currentStatus = AssertionStatus.FAILED;
255             break;
256          }
257       }
258 
259       if( currentStatus == AssertionStatus.UNKNOWN )
260          currentStatus = AssertionStatus.VALID;
261 
262       return currentStatus;
263    }
264 
265    @Override
266    public ImageIcon getIcon()
267    {
268       if( forLoadTest || UISupport.isHeadless() )
269          return null;
270 
271       TestMonitor testMonitor = SoapUI.getTestMonitor();
272       if( testMonitor != null && testMonitor.hasRunningLoadTest( testStep.getTestCase() ) )
273          return disabledRequestIcon;
274 
275       ImageIcon icon = getIconAnimator().getIcon();
276       if( icon == getIconAnimator().getBaseIcon() )
277       {
278          AssertionStatus status = getAssertionStatus();
279          if( status == AssertionStatus.VALID )
280             return validRequestIcon;
281          else if( status == AssertionStatus.FAILED )
282             return failedRequestIcon;
283          else if( status == AssertionStatus.UNKNOWN )
284             return unknownRequestIcon;
285       }
286 
287       return icon;
288    }
289 
290    public void addAssertionsListener( AssertionsListener listener )
291    {
292       assertionsSupport.addAssertionsListener( listener );
293    }
294 
295    public void removeAssertionsListener( AssertionsListener listener )
296    {
297       assertionsSupport.removeAssertionsListener( listener );
298    }
299 
300    /***
301     * Called when a testrequest is moved in a testcase
302     */
303 
304    public void updateConfig( RestMethodConfig request )
305    {
306       super.updateConfig( request );
307 
308       assertionsSupport.refresh();
309    }
310 
311    @Override
312    public void release()
313    {
314       super.release();
315       assertionsSupport.release();
316    }
317 
318    public String getAssertableContent()
319    {
320       return getResponseContentAsXml();
321    }
322 
323    public HttpTestRequestStep getTestStep()
324    {
325       return testStep;
326    }
327 
328    public RestService getInterface()
329    {
330       return getOperation() == null ? null : getOperation().getInterface();
331    }
332 
333    @Override
334    public RestResource getOperation()
335    {
336       return testStep instanceof RestTestRequestStep ? ( (RestTestRequestStep) testStep ).getResource() : null;
337    }
338 
339    protected static class TestRequestIconAnimator extends RequestIconAnimator<RestTestRequest>
340    {
341       public TestRequestIconAnimator( RestTestRequest modelItem )
342       {
343          super( modelItem,
344                  modelItem.getTestStep() instanceof RestTestRequestStep ? "/rest_request.gif" : "/http_request.gif",
345                  modelItem.getTestStep() instanceof RestTestRequestStep ? "/exec_rest_request" : "/exec_http_request", 4, "gif" );
346       }
347 
348       @Override
349       public boolean beforeSubmit( Submit submit, SubmitContext context )
350       {
351          if( SoapUI.getTestMonitor() != null && SoapUI.getTestMonitor().hasRunningLoadTest( getTarget().getTestCase() ) )
352             return true;
353 
354          return super.beforeSubmit( submit, context );
355       }
356 
357       @Override
358       public void afterSubmit( Submit submit, SubmitContext context )
359       {
360          if( submit.getRequest() == getTarget() )
361             stop();
362       }
363    }
364 
365    public AssertableType getAssertableType()
366    {
367       return AssertableType.RESPONSE;
368    }
369 
370    public TestAssertion cloneAssertion( TestAssertion source, String name )
371    {
372       return assertionsSupport.cloneAssertion( source, name );
373    }
374 
375    public WsdlMessageAssertion importAssertion( WsdlMessageAssertion source, boolean overwrite, boolean createCopy )
376    {
377       return assertionsSupport.importAssertion( source, overwrite, createCopy );
378    }
379 
380    public List<TestAssertion> getAssertionList()
381    {
382       return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
383    }
384 
385    public WsdlMessageAssertion getAssertionByName( String name )
386    {
387       return assertionsSupport.getAssertionByName( name );
388    }
389 
390    public ModelItem getModelItem()
391    {
392       return testStep;
393    }
394 
395    public Map<String, TestAssertion> getAssertions()
396    {
397       return assertionsSupport.getAssertions();
398    }
399 
400    public String getDefaultAssertableContent()
401    {
402       return "";
403    }
404 
405    public String getResponseContentAsString()
406    {
407       return getResponse() == null ? null : getResponse().getContentAsString();
408    }
409 
410    public void setPath( String fullPath )
411    {
412       super.setPath( fullPath );
413 
414       if( getOperation() == null )
415       {
416          setEndpoint( fullPath );
417       }
418    }
419 
420    public void setResource( RestResource restResource )
421    {
422       if( this.restResource != null )
423          this.restResource.removePropertyChangeListener( this );
424 
425       this.restResource = restResource;
426 
427       restResource.addPropertyChangeListener( this );
428    }
429 
430    public RestResource getResource()
431    {
432       return restResource;
433    }
434 
435    public void resolve( ResolveContext context )
436    {
437       super.resolve( context );
438       assertionsSupport.resolve( context );
439    }
440 
441    public String getServiceName()
442    {
443       return testStep instanceof RestTestRequestStep ? ( (RestTestRequestStep) testStep ).getService() : null;
444    }
445 }