View Javadoc

1   /*
2    *  soapUI, copyright (C) 2004-2010 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.util.ArrayList;
16  import java.util.List;
17  import java.util.Map;
18  
19  import javax.swing.ImageIcon;
20  
21  import com.eviware.soapui.SoapUI;
22  import com.eviware.soapui.config.AttachmentConfig;
23  import com.eviware.soapui.config.TestAssertionConfig;
24  import com.eviware.soapui.config.WsdlRequestConfig;
25  import com.eviware.soapui.impl.settings.XmlBeansSettingsImpl;
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.submit.transports.http.HttpResponse;
30  import com.eviware.soapui.impl.wsdl.submit.transports.jms.JMSResponse;
31  import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
32  import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
33  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
34  import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
35  import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
36  import com.eviware.soapui.model.ModelItem;
37  import com.eviware.soapui.model.iface.Submit;
38  import com.eviware.soapui.model.iface.SubmitContext;
39  import com.eviware.soapui.model.testsuite.Assertable;
40  import com.eviware.soapui.model.testsuite.AssertionsListener;
41  import com.eviware.soapui.model.testsuite.TestAssertion;
42  import com.eviware.soapui.monitor.TestMonitor;
43  import com.eviware.soapui.support.UISupport;
44  import com.eviware.soapui.support.resolver.ResolveContext;
45  
46  /***
47   * WsdlRequest extension that adds WsdlAssertions
48   * 
49   * @author Ole.Matzura
50   */
51  
52  public class WsdlTestRequest extends WsdlRequest implements Assertable, TestRequest
53  {
54  	public static final String RESPONSE_PROPERTY = WsdlTestRequest.class.getName() + "@response";
55  	public static final String STATUS_PROPERTY = WsdlTestRequest.class.getName() + "@status";
56  
57  	private static ImageIcon validRequestIcon;
58  	private static ImageIcon failedRequestIcon;
59  	private static ImageIcon disabledRequestIcon;
60  	private static ImageIcon unknownRequestIcon;
61  
62  	private AssertionStatus currentStatus;
63  	private final WsdlTestRequestStep testStep;
64  
65  	private AssertionsSupport assertionsSupport;
66  	private WsdlResponseMessageExchange messageExchange;
67  	private final boolean forLoadTest;
68  	private PropertyChangeNotifier notifier;
69  
70  	public WsdlTestRequest( WsdlOperation operation, WsdlRequestConfig callConfig, WsdlTestRequestStep testStep,
71  			boolean forLoadTest )
72  	{
73  		super( operation, callConfig, forLoadTest );
74  		this.forLoadTest = forLoadTest;
75  
76  		setSettings( new XmlBeansSettingsImpl( this, testStep.getSettings(), callConfig.getSettings() ) );
77  
78  		this.testStep = testStep;
79  
80  		initAssertions();
81  
82  		if( !forLoadTest )
83  			initIcons();
84  	}
85  
86  	public WsdlTestCase getTestCase()
87  	{
88  		return testStep.getTestCase();
89  	}
90  
91  	public ModelItem getParent()
92  	{
93  		return getTestStep();
94  	}
95  
96  	protected void initIcons()
97  	{
98  		if( validRequestIcon == null )
99  			validRequestIcon = UISupport.createImageIcon( "/valid_request.gif" );
100 
101 		if( failedRequestIcon == null )
102 			failedRequestIcon = UISupport.createImageIcon( "/invalid_request.gif" );
103 
104 		if( unknownRequestIcon == null )
105 			unknownRequestIcon = UISupport.createImageIcon( "/unknown_request.gif" );
106 
107 		if( disabledRequestIcon == null )
108 			disabledRequestIcon = UISupport.createImageIcon( "/disabled_request.gif" );
109 	}
110 
111 	@Override
112 	protected RequestIconAnimator<?> initIconAnimator()
113 	{
114 		return new TestRequestIconAnimator( this );
115 	}
116 
117 	private void initAssertions()
118 	{
119 		assertionsSupport = new AssertionsSupport( testStep, new AssertableConfig()
120 		{
121 
122 			public TestAssertionConfig addNewAssertion()
123 			{
124 				return getConfig().addNewAssertion();
125 			}
126 
127 			public List<TestAssertionConfig> getAssertionList()
128 			{
129 				return getConfig().getAssertionList();
130 			}
131 
132 			public void removeAssertion( int ix )
133 			{
134 				getConfig().removeAssertion( ix );
135 			}
136 
137 			public TestAssertionConfig insertAssertion( TestAssertionConfig source, int ix )
138 			{
139 				TestAssertionConfig conf = getConfig().insertNewAssertion( ix );
140 				conf.set( source );
141 				return conf;
142 			}
143 		} );
144 	}
145 
146 	public int getAssertionCount()
147 	{
148 		return assertionsSupport.getAssertionCount();
149 	}
150 
151 	public WsdlMessageAssertion getAssertionAt( int c )
152 	{
153 		return assertionsSupport.getAssertionAt( c );
154 	}
155 
156 	public void setResponse( HttpResponse response, SubmitContext context )
157 	{
158 		super.setResponse( response, context );
159 		assertResponse( context );
160 	}
161 
162 	public void assertResponse( SubmitContext context )
163 	{
164 		if( notifier == null )
165 			notifier = new PropertyChangeNotifier();
166 
167 		if( getResponse() instanceof JMSResponse )
168 		{
169 			messageExchange = getResponse() == null ? null : new WsdlResponseMessageExchange( this )
170 			{
171 				@Override
172 				public boolean hasResponse()
173 				{// JMS tweak
174 					String responseContent = getResponseContent();
175 					return responseContent != null;
176 				}
177 			};
178 		}
179 		else
180 		{
181 			messageExchange = getResponse() == null ? null : new WsdlResponseMessageExchange( this );
182 		}
183 
184 		if( messageExchange != null )
185 		{
186 			// assert!
187 			for( WsdlMessageAssertion assertion : assertionsSupport.getAssertionList() )
188 			{
189 				assertion.assertResponse( messageExchange, context );
190 			}
191 		}
192 
193 		notifier.notifyChange();
194 	}
195 
196 	private class PropertyChangeNotifier
197 	{
198 		private AssertionStatus oldStatus;
199 		private ImageIcon oldIcon;
200 
201 		public PropertyChangeNotifier()
202 		{
203 			oldStatus = getAssertionStatus();
204 			oldIcon = getIcon();
205 		}
206 
207 		public void notifyChange()
208 		{
209 			AssertionStatus newStatus = getAssertionStatus();
210 			ImageIcon newIcon = getIcon();
211 
212 			if( oldStatus != newStatus )
213 				notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
214 
215 			if( oldIcon != newIcon )
216 				notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
217 
218 			oldStatus = newStatus;
219 			oldIcon = newIcon;
220 		}
221 	}
222 
223 	public WsdlMessageAssertion addAssertion( String assertionLabel )
224 	{
225 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
226 
227 		try
228 		{
229 			WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionLabel );
230 			if( assertion == null )
231 				return null;
232 
233 			if( getResponse() != null )
234 			{
235 				assertion.assertResponse( new WsdlResponseMessageExchange( this ), new WsdlTestRunContext( testStep ) );
236 				notifier.notifyChange();
237 			}
238 
239 			return assertion;
240 		}
241 		catch( Exception e )
242 		{
243 			SoapUI.logError( e );
244 			return null;
245 		}
246 	}
247 
248 	public void removeAssertion( TestAssertion assertion )
249 	{
250 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
251 
252 		try
253 		{
254 			assertionsSupport.removeAssertion( ( WsdlMessageAssertion )assertion );
255 
256 		}
257 		finally
258 		{
259 			( ( WsdlMessageAssertion )assertion ).release();
260 			notifier.notifyChange();
261 		}
262 	}
263 
264 	public TestAssertion moveAssertion( int ix, int offset )
265 	{
266 		WsdlMessageAssertion assertion = getAssertionAt( ix );
267 		PropertyChangeNotifier notifier = new PropertyChangeNotifier();
268 
269 		try
270 		{
271 			return assertionsSupport.moveAssertion( ix, offset );
272 		}
273 		finally
274 		{
275 			( ( WsdlMessageAssertion )assertion ).release();
276 			notifier.notifyChange();
277 		}
278 	}
279 
280 	public AssertionStatus getAssertionStatus()
281 	{
282 		currentStatus = AssertionStatus.UNKNOWN;
283 
284 		if( messageExchange != null )
285 		{
286 			/*
287 			 * if( !messageExchange.hasResponse() &&
288 			 * getOperation().isBidirectional() && !isWsaEnabled() ) {
289 			 * currentStatus = AssertionStatus.FAILED; }
290 			 */
291 		}
292 		else
293 			return currentStatus;
294 
295 		int cnt = getAssertionCount();
296 		if( cnt == 0 )
297 			return currentStatus;
298 
299 		boolean hasEnabled = false;
300 
301 		for( int c = 0; c < cnt; c++ )
302 		{
303 			if( !getAssertionAt( c ).isDisabled() )
304 				hasEnabled = true;
305 
306 			if( getAssertionAt( c ).getStatus() == AssertionStatus.FAILED )
307 			{
308 				currentStatus = AssertionStatus.FAILED;
309 				break;
310 			}
311 		}
312 
313 		if( currentStatus == AssertionStatus.UNKNOWN && hasEnabled )
314 			currentStatus = AssertionStatus.VALID;
315 
316 		return currentStatus;
317 	}
318 
319 	@Override
320 	public ImageIcon getIcon()
321 	{
322 		if( forLoadTest || UISupport.isHeadless() )
323 			return null;
324 
325 		TestMonitor testMonitor = SoapUI.getTestMonitor();
326 		if( testMonitor != null && testMonitor.hasRunningLoadTest( testStep.getTestCase() ) )
327 			return disabledRequestIcon;
328 
329 		ImageIcon icon = getIconAnimator().getIcon();
330 		if( icon == getIconAnimator().getBaseIcon() )
331 		{
332 			AssertionStatus status = getAssertionStatus();
333 			if( status == AssertionStatus.VALID )
334 				return validRequestIcon;
335 			else if( status == AssertionStatus.FAILED )
336 				return failedRequestIcon;
337 			else if( status == AssertionStatus.UNKNOWN )
338 				return unknownRequestIcon;
339 		}
340 
341 		return icon;
342 	}
343 
344 	public void addAssertionsListener( AssertionsListener listener )
345 	{
346 		assertionsSupport.addAssertionsListener( listener );
347 	}
348 
349 	public void removeAssertionsListener( AssertionsListener listener )
350 	{
351 		assertionsSupport.removeAssertionsListener( listener );
352 	}
353 
354 	/***
355 	 * Called when a testrequest is moved in a testcase
356 	 */
357 
358 	@Override
359 	public void updateConfig( WsdlRequestConfig request )
360 	{
361 		super.updateConfig( request );
362 
363 		assertionsSupport.refresh();
364 
365 		List<AttachmentConfig> attachmentConfigs = getConfig().getAttachmentList();
366 		for( int i = 0; i < attachmentConfigs.size(); i++ )
367 		{
368 			AttachmentConfig config = attachmentConfigs.get( i );
369 			getAttachmentsList().get( i ).updateConfig( config );
370 		}
371 
372 	}
373 
374 	@Override
375 	public void release()
376 	{
377 		super.release();
378 		assertionsSupport.release();
379 	}
380 
381 	public String getAssertableContent()
382 	{
383 		return getResponse() == null ? null : getResponse().getContentAsString();
384 	}
385 
386 	public WsdlTestRequestStep getTestStep()
387 	{
388 		return testStep;
389 	}
390 
391 	public WsdlInterface getInterface()
392 	{
393 		return getOperation().getInterface();
394 	}
395 
396 	protected static class TestRequestIconAnimator extends RequestIconAnimator<WsdlTestRequest>
397 	{
398 		public TestRequestIconAnimator( WsdlTestRequest modelItem )
399 		{
400 			super( modelItem, "/request.gif", "/exec_request", 4, "gif" );
401 		}
402 
403 		@Override
404 		public boolean beforeSubmit( Submit submit, SubmitContext context )
405 		{
406 			if( SoapUI.getTestMonitor() != null && SoapUI.getTestMonitor().hasRunningLoadTest( getTarget().getTestCase() ) )
407 				return true;
408 
409 			return super.beforeSubmit( submit, context );
410 		}
411 
412 		@Override
413 		public void afterSubmit( Submit submit, SubmitContext context )
414 		{
415 			if( submit.getRequest() == getTarget() )
416 				stop();
417 		}
418 	}
419 
420 	public AssertableType getAssertableType()
421 	{
422 		return AssertableType.BOTH;
423 	}
424 
425 	public String getInterfaceName()
426 	{
427 		return testStep.getInterfaceName();
428 	}
429 
430 	public String getOperationName()
431 	{
432 		return testStep.getOperationName();
433 	}
434 
435 	public TestAssertion cloneAssertion( TestAssertion source, String name )
436 	{
437 		return assertionsSupport.cloneAssertion( source, name );
438 	}
439 
440 	public WsdlMessageAssertion importAssertion( WsdlMessageAssertion source, boolean overwrite, boolean createCopy,
441 			String newName )
442 	{
443 		return assertionsSupport.importAssertion( source, overwrite, createCopy, newName );
444 	}
445 
446 	public List<TestAssertion> getAssertionList()
447 	{
448 		return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
449 	}
450 
451 	public WsdlMessageAssertion getAssertionByName( String name )
452 	{
453 		return assertionsSupport.getAssertionByName( name );
454 	}
455 
456 	public ModelItem getModelItem()
457 	{
458 		return testStep;
459 	}
460 
461 	public Map<String, TestAssertion> getAssertions()
462 	{
463 		return assertionsSupport.getAssertions();
464 	}
465 
466 	public String getDefaultAssertableContent()
467 	{
468 		return getOperation().createResponse( true );
469 	}
470 
471 	public void resolve( ResolveContext<?> context )
472 	{
473 		super.resolve( context );
474 
475 		assertionsSupport.resolve( context );
476 	}
477 
478 	public boolean isDiscardResponse()
479 	{
480 		return getSettings().getBoolean( "discardResponse" );
481 	}
482 
483 	public void setDiscardResponse( boolean discardResponse )
484 	{
485 		getSettings().setBoolean( "discardResponse", discardResponse );
486 	}
487 }