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