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