View Javadoc

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