View Javadoc

1   /*
2    *  soapUI, copyright (C) 2006 eviware.com 
3    *
4    *  soapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
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 java.beans.PropertyChangeEvent;
16  import java.beans.PropertyChangeListener;
17  
18  import javax.swing.ImageIcon;
19  
20  import org.apache.commons.logging.Log;
21  import org.apache.commons.logging.LogFactory;
22  
23  import com.eviware.soapui.config.CallConfig;
24  import com.eviware.soapui.config.RequestStepConfig;
25  import com.eviware.soapui.config.TestStepConfig;
26  import com.eviware.soapui.impl.wsdl.AbstractWsdlModelItem;
27  import com.eviware.soapui.impl.wsdl.WsdlInterface;
28  import com.eviware.soapui.impl.wsdl.WsdlOperation;
29  import com.eviware.soapui.impl.wsdl.WsdlRequest;
30  import com.eviware.soapui.impl.wsdl.actions.support.ShowOnlineHelpAction;
31  import com.eviware.soapui.impl.wsdl.panels.support.assertions.Assertable.AssertionStatus;
32  import com.eviware.soapui.impl.wsdl.submit.filters.PropertyExpansionRequestFilter;
33  import com.eviware.soapui.impl.wsdl.submit.transports.http.WsdlResponse;
34  import com.eviware.soapui.impl.wsdl.support.HelpUrls;
35  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
36  import com.eviware.soapui.impl.wsdl.teststeps.actions.CloneTestStepAction;
37  import com.eviware.soapui.impl.wsdl.teststeps.actions.SelectOperationAction;
38  import com.eviware.soapui.impl.wsdl.teststeps.assertions.AssertionError;
39  import com.eviware.soapui.model.iface.Interface;
40  import com.eviware.soapui.model.iface.Operation;
41  import com.eviware.soapui.model.iface.Submit;
42  import com.eviware.soapui.model.iface.Request.SubmitException;
43  import com.eviware.soapui.model.project.Project;
44  import com.eviware.soapui.model.support.InterfaceListenerAdapter;
45  import com.eviware.soapui.model.support.ProjectListenerAdapter;
46  import com.eviware.soapui.model.support.TestStepBeanProperty;
47  import com.eviware.soapui.model.support.TestSuiteListenerAdapter;
48  import com.eviware.soapui.model.testsuite.LoadTestRunner;
49  import com.eviware.soapui.model.testsuite.TestRunContext;
50  import com.eviware.soapui.model.testsuite.TestRunner;
51  import com.eviware.soapui.model.testsuite.TestStep;
52  import com.eviware.soapui.model.testsuite.TestStepResult;
53  import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
54  import com.eviware.soapui.support.action.ActionSupport;
55  
56  /***
57   * WsdlTestStep that executes a WsdlTestRequest
58   * 
59   * @author Ole.Matzura
60   */
61  
62  public class WsdlTestRequestStep extends WsdlTestStep implements PropertyChangeListener 
63  {
64  	private final static Log log = LogFactory.getLog( WsdlTestRequestStep.class );
65     private RequestStepConfig requestStepConfig;
66     private WsdlTestRequest testRequest;
67  	private WsdlOperation wsdlOperation;
68  	private final InternalProjectListener projectListener = new InternalProjectListener();
69  	private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();
70  	private final InternalTestSuiteListener testSuiteListener = new InternalTestSuiteListener();
71  
72     public WsdlTestRequestStep(WsdlTestCase testCase, TestStepConfig config)
73     {
74        super( testCase, config, true );
75        
76        //  testCase.addTestRunListener( testRunListener );
77        if( testCase != null && testCase.getTestSuite() != null )
78        	testCase.getTestSuite().addTestSuiteListener( testSuiteListener );
79        
80        if( getConfig().getConfig() != null )
81        {
82  			requestStepConfig = (RequestStepConfig) getConfig().getConfig().changeType(RequestStepConfig.type);
83           
84           wsdlOperation = findWsdlOperation();
85  			if( wsdlOperation == null )
86           {   
87              log.error( "Could not find operation [" + requestStepConfig.getOperation() + "] in interface [" + 
88              		requestStepConfig.getInterface() + "] for test request" );
89              requestStepConfig.setRequest(null);
90           }
91           else
92           {
93           	wsdlOperation.getInterface().getProject().addProjectListener( projectListener );
94           	wsdlOperation.getInterface().addInterfaceListener( interfaceListener );
95           	
96           	// we need to listen for name changes which happen when interfaces are updated..
97           	wsdlOperation.getInterface().addPropertyChangeListener( this );
98           	wsdlOperation.addPropertyChangeListener( this );
99           	
100             testRequest = new WsdlTestRequest( wsdlOperation, requestStepConfig.getRequest(), this );
101             testRequest.addPropertyChangeListener( this );
102             
103             config.setName( testRequest.getName() );
104          }
105       }
106       else
107       {
108          requestStepConfig = (RequestStepConfig) getConfig().addNewConfig().changeType( RequestStepConfig.type );
109       }
110       
111       addAction( ActionSupport.SEPARATOR_ACTION );
112       addAction( new SelectOperationAction( this ));
113       addAction( new CloneTestStepAction( this, "TestRequest" ) );
114       addAction( ActionSupport.SEPARATOR_ACTION );
115       addAction( new ShowOnlineHelpAction( HelpUrls.TESTREQUEST_HELP_URL ));
116       
117       // init properties
118       addProperty( new TestStepBeanProperty( "Endpoint", false, testRequest, "endpoint", this ));
119       addProperty( new TestStepBeanProperty( "Username", false, testRequest, "username", this ));
120       addProperty( new TestStepBeanProperty( "Password", false, testRequest, "password", this ));
121       addProperty( new TestStepBeanProperty( "Domain", false, testRequest, "domain", this ));
122       addProperty( new TestStepBeanProperty( "Request", false, testRequest, "requestContent", this ));
123       addProperty( new TestStepBeanProperty( "Response", true, testRequest, "responseContent", this ));
124    }
125    
126 	public WsdlTestRequestStep(WsdlTestCase testCase, TestStepConfig testStep, WsdlRequest request)
127 	{
128 		this( testCase, testStep );
129 
130       requestStepConfig.setInterface( request.getOperation().getInterface().getName() );
131       requestStepConfig.setOperation( request.getOperation().getName() );
132 
133       CallConfig testRequestConfig = requestStepConfig.getRequest();
134       if( testRequestConfig == null ) testRequestConfig = requestStepConfig.addNewRequest();
135       
136       testRequestConfig.setName( request.getName() );
137       testRequestConfig.setEncoding( request.getEncoding() );
138       testRequestConfig.setEndpoint( request.getEndpoint() );
139       testRequestConfig.setRequest( request.getRequestContent() );
140       if( request.getConfig().getCredentials() != null )
141       	testRequestConfig.setCredentials( request.getConfig().getCredentials() );
142 
143       testRequest = new WsdlTestRequest( request.getOperation(), testRequestConfig, this );
144       request.copyAttachmentsTo( testRequest );
145 
146       testRequest.addPropertyChangeListener( this );
147       
148       wsdlOperation = findWsdlOperation();
149       if( wsdlOperation == null )
150       	throw new RuntimeException( "Failed to find operation [" + requestStepConfig.getOperation() + "] for test request" );
151       
152       wsdlOperation.getInterface().addInterfaceListener( interfaceListener );
153       wsdlOperation.getInterface().getProject().addProjectListener( projectListener );
154 	}
155 
156 	public WsdlTestRequestStep(WsdlTestCase testCase, WsdlTestRequest sourceRequest)
157 	{
158 		this( testCase, TestStepConfig.Factory.newInstance(), sourceRequest );
159 	}
160 	
161 	public WsdlTestStep clone( WsdlTestCase targetTestCase, String name)
162 	{
163 		TestStepConfig config = (TestStepConfig) getConfig().copy();
164 		RequestStepConfig stepConfig = (RequestStepConfig) config.getConfig().changeType(RequestStepConfig.type);
165 		
166 		while( stepConfig.getRequest().sizeOfAttachmentArray() > 0 )
167 			stepConfig.getRequest().removeAttachment( 0 );
168 		
169 		config.setName( name );
170 		stepConfig.getRequest().setName( name );
171 		
172 		WsdlTestRequestStep result = (WsdlTestRequestStep) targetTestCase.addTestStep( config );
173 		testRequest.copyAttachmentsTo( result.getTestRequest() );
174 		
175 		return result;
176 	}
177 	
178 	private WsdlOperation findWsdlOperation()
179    {
180    	WsdlTestCase testCase = (WsdlTestCase) getTestCase();
181    	if( testCase == null || testCase.getTestSuite() == null )
182    		return null;
183    	
184       Project project = testCase.getTestSuite().getProject();
185       WsdlOperation operation = null;
186       for( int c = 0; c < project.getInterfaceCount(); c++ )
187       {
188          if( project.getInterfaceAt( c ).getName().equals( requestStepConfig.getInterface()))
189          {
190             WsdlInterface iface = (WsdlInterface) project.getInterfaceAt( c );
191             for( int i = 0; i < iface.getOperationCount(); i++ )
192             {
193                if( iface.getOperationAt( i ).getName().equals( requestStepConfig.getOperation() ))
194                {
195                   operation = (WsdlOperation) iface.getOperationAt( i );
196                   break;
197                }
198             }
199             
200             if( operation != null )
201             	break;
202          }
203       }
204       return operation;
205    }
206 
207 	public void release()
208 	{
209 		super.release();
210 		
211       wsdlOperation = findWsdlOperation();
212       if( wsdlOperation != null )
213       {
214 	      wsdlOperation.removePropertyChangeListener( this );
215 	     	wsdlOperation.getInterface().getProject().removeProjectListener( projectListener );
216 	     	wsdlOperation.getInterface().removeInterfaceListener( interfaceListener );
217 	     	wsdlOperation.getInterface().removePropertyChangeListener( this );
218       }
219       
220       testRequest.removePropertyChangeListener( this );
221       testRequest.release();
222 	}
223 
224 	public void resetConfigOnMove(TestStepConfig config)
225 	{
226 		super.resetConfigOnMove(config);
227 
228 		requestStepConfig = (RequestStepConfig) config.getConfig().changeType(RequestStepConfig.type);
229 		testRequest.updateConfig( requestStepConfig.getRequest() );
230 	}
231 
232 	public ImageIcon getIcon()
233    {
234       return testRequest.getIcon();
235    }
236 
237    public String getName()
238    {
239       return testRequest == null ? super.getName() : testRequest.getName();
240    }
241    
242    public WsdlTestRequest getTestRequest()
243    {
244       return testRequest;
245    }
246    
247 	public void setName(String name)
248 	{
249 		testRequest.setName( name );
250 	}
251 
252    public void propertyChange(PropertyChangeEvent arg0) 
253    {
254    	if( arg0.getSource() == wsdlOperation )
255    	{
256    		if( arg0.getPropertyName().equals( Operation.NAME_PROPERTY ))
257    		{
258    			requestStepConfig.setOperation( (String) arg0.getNewValue() );
259    		}
260    	}
261    	else if( arg0.getSource() == wsdlOperation.getInterface() )
262    	{
263    		if( arg0.getPropertyName().equals( Interface.NAME_PROPERTY ))
264    		{
265    			requestStepConfig.setInterface( (String) arg0.getNewValue() );
266    		}
267    	}
268    	else
269    	{
270    	   notifyPropertyChanged( arg0.getPropertyName(), arg0.getOldValue(), arg0.getNewValue());
271    	}
272    }
273 
274 	public TestStepResult run( TestRunner runner, TestRunContext runContext ) 
275 	{
276 		LoadTestRunner loadTestRunner = (LoadTestRunner) runContext.getProperty( TestRunContext.LOAD_TEST_RUNNER );
277 		if( loadTestRunner != null )
278 		{
279 			testRequest.getIconAnimator().setEnabled( false );
280 		}
281 		
282 		WsdlTestRequestStepResult testStepResult = new WsdlTestRequestStepResult(this);
283 		
284    	try
285 		{
286 			Submit submit = testRequest.submit( runContext, false );
287 			WsdlResponse response = (WsdlResponse) submit.getResponse();
288 			
289 			if( submit.getStatus() != Submit.Status.CANCELED )
290 			{
291 				if( submit.getStatus() == Submit.Status.ERROR )
292 				{
293 					testStepResult.setStatus( TestStepStatus.FAILED );
294 					testStepResult.addMessage( submit.getError().toString() );
295 					
296 					testRequest.setResponse( null, runContext );
297 				}
298 				else if( response == null )
299 				{
300 					testStepResult.setStatus( TestStepStatus.FAILED );
301 					testStepResult.addMessage( "Request is missing response" );
302 					
303 					testRequest.setResponse( null, runContext );
304 				}
305 				else
306 				{
307 					testRequest.setResponse( response, runContext );
308 					
309 					testStepResult.setTimeTaken( response.getTimeTaken() );
310 			   	testStepResult.setSize( response.getContentLength() );
311 			   	testStepResult.setResponse( response );
312 			   	
313 			   	switch( testRequest.getAssertionStatus() )
314 			   	{
315 			   		case FAILED : testStepResult.setStatus( TestStepStatus.FAILED); break; 
316 			   		case VALID : testStepResult.setStatus( TestStepStatus.OK); break; 
317 			   		case UNKNOWN : testStepResult.setStatus( TestStepStatus.UNKNOWN); break; 
318 			   	}
319 				}
320 			}
321 			else
322 			{
323 				testStepResult.setStatus( TestStepStatus.CANCELED );
324 				testStepResult.addMessage( "Request was canceled" );
325 			}
326 			
327 			if( response != null )
328 				testStepResult.setRequestContent( response.getRequestContent() );
329 		}
330 		catch (SubmitException e)
331 		{
332 			testStepResult.setStatus( TestStepStatus.FAILED );
333 			testStepResult.addMessage( "SubmitException: " + e );
334 		}
335 		
336 		testStepResult.setDomain( testRequest.getDomain() );
337 		testStepResult.setUsername( testRequest.getUsername() );
338 		testStepResult.setPassword( testRequest.getPassword() );
339 		testStepResult.setEndpoint( PropertyExpansionRequestFilter.expandProperties( runContext, 
340 					testRequest.getEndpoint() ));
341 		testStepResult.setEncoding( testRequest.getEncoding() );
342    	
343 		if( testStepResult.getStatus() != TestStepStatus.CANCELED )
344 		{
345 	   	AssertionStatus assertionStatus = testRequest.getAssertionStatus();
346 			switch( assertionStatus )
347 	   	{
348 	   		case FAILED : 
349 				{
350 					testStepResult.setStatus( TestStepStatus.FAILED );
351 					if( getAssertionCount() == 0 )
352 					{
353 						testStepResult.addMessage( "Invalid/empty response" );
354 					}
355 					else for( int c = 0; c < getAssertionCount(); c++ )
356 					{
357 						AssertionError[] errors = getAssertionAt( c ).getErrors();
358 						if( errors != null )
359 						{
360 							for( AssertionError error : errors )
361 							{
362 								testStepResult.addMessage( error.getMessage() );
363 							}
364 						}
365 					}
366 					
367 					break;
368 				}
369 	   	//	default : testStepResult.setStatus( TestStepStatus.OK ); break;
370 	   	}
371 		}
372    	
373 		testRequest.getIconAnimator().setEnabled( true );
374 		return testStepResult;
375 	}
376 	
377 	public WsdlMessageAssertion getAssertionAt(int index)
378 	{
379 		return testRequest.getAssertionAt( index );
380 	}
381 
382 	public int getAssertionCount()
383 	{
384 		return testRequest.getAssertionCount();
385 	}
386 	
387 	public class InternalProjectListener extends ProjectListenerAdapter 
388 	{
389 		public void interfaceRemoved(Interface iface)
390 		{
391 			if( wsdlOperation != null && wsdlOperation.getInterface().equals( iface ))
392 			{
393 				log.debug( "Removing test step due to removed interface" );
394 				
395 				((WsdlTestCase)getTestCase()).removeTestStep( WsdlTestRequestStep.this );
396 			}
397 		}
398 	}
399 
400 	public class InternalInterfaceListener extends InterfaceListenerAdapter
401 	{
402 		public void operationRemoved(Operation operation)
403 		{
404 			if( operation.equals( wsdlOperation ))
405 			{
406 				((WsdlTestCase)getTestCase()).removeTestStep( WsdlTestRequestStep.this );
407 			}
408 		}
409 	}
410 	
411 	private class InternalTestSuiteListener extends TestSuiteListenerAdapter
412 	{
413 		public void testStepRemoved(TestStep testStep, int index)
414 		{
415 			if( testStep == WsdlTestRequestStep.this )
416 			{
417 				log.debug( "Releasing WsdlTestRequestStep" );
418 		      wsdlOperation.getInterface().removeInterfaceListener( interfaceListener );
419 		      wsdlOperation.getInterface().getProject().removeProjectListener( projectListener );
420 		      getTestCase().getTestSuite().removeTestSuiteListener( testSuiteListener );
421 			}
422 		}
423 	}
424 
425 	public boolean cancel()
426 	{
427 		return false;
428 	}
429 
430 	
431 	public boolean dependsOn( AbstractWsdlModelItem modelItem )
432 	{
433 		if( modelItem instanceof Interface && testRequest.getOperation().getInterface() == modelItem )
434 		{
435 			return true;
436 		}
437 		else if( modelItem instanceof Operation && testRequest.getOperation() == modelItem )
438 		{
439 			return true;
440 		}
441 		
442 		return false;
443 	}
444 }