View Javadoc

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