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.panels.teststeps.amf;
14  
15  import java.util.ArrayList;
16  import java.util.HashMap;
17  import java.util.HashSet;
18  import java.util.List;
19  import java.util.Map;
20  import java.util.Set;
21  
22  import javax.swing.ImageIcon;
23  
24  import com.eviware.soapui.SoapUI;
25  import com.eviware.soapui.config.ModelItemConfig;
26  import com.eviware.soapui.impl.wsdl.support.ModelItemIconAnimator;
27  import com.eviware.soapui.impl.wsdl.teststeps.AMFRequestTestStep;
28  import com.eviware.soapui.impl.wsdl.teststeps.TestRequest;
29  import com.eviware.soapui.impl.wsdl.teststeps.WsdlMessageAssertion;
30  import com.eviware.soapui.impl.wsdl.teststeps.WsdlTestStepWithProperties;
31  import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
32  import com.eviware.soapui.model.ModelItem;
33  import com.eviware.soapui.model.iface.Attachment;
34  import com.eviware.soapui.model.iface.Interface;
35  import com.eviware.soapui.model.iface.MessagePart;
36  import com.eviware.soapui.model.iface.Operation;
37  import com.eviware.soapui.model.iface.Submit;
38  import com.eviware.soapui.model.iface.SubmitContext;
39  import com.eviware.soapui.model.iface.SubmitListener;
40  import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
41  import com.eviware.soapui.model.settings.Settings;
42  import com.eviware.soapui.model.support.AbstractAnimatableModelItem;
43  import com.eviware.soapui.model.support.ModelSupport;
44  import com.eviware.soapui.model.testsuite.Assertable;
45  import com.eviware.soapui.model.testsuite.AssertionsListener;
46  import com.eviware.soapui.model.testsuite.TestAssertion;
47  import com.eviware.soapui.model.testsuite.TestProperty;
48  import com.eviware.soapui.monitor.TestMonitor;
49  import com.eviware.soapui.support.UISupport;
50  import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
51  import com.eviware.soapui.support.types.StringToObjectMap;
52  import com.eviware.soapui.support.types.StringToStringMap;
53  import com.eviware.soapui.support.types.StringToStringsMap;
54  
55  public class AMFRequest extends AbstractAnimatableModelItem<ModelItemConfig> implements Assertable, TestRequest
56  {
57  	public static final String AMF_SCRIPT_HEADERS = "AMF_SCRIPT_HEADERS";
58  	public static final String AMF_SCRIPT_PARAMETERS = "AMF_SCRIPT_PARAMETERS";
59  	public static final String AMF_SCRIPT_ERROR = "AMF_SCRIPT_ERROR";
60  	public static final String AMF_RESPONSE_CONTENT = "AMF_RESPONSE_CONTENT";
61  	public static final String AMF_REQUEST = "AMF_REQUEST";
62  	public static final String RAW_AMF_REQUEST = "RAW_AMF_REQUEST";
63  	public static final String AMF_RESPONSE_PROPERTY = "response";
64  
65  	private final AMFRequestTestStep testStep;
66  	private Set<SubmitListener> submitListeners = new HashSet<SubmitListener>();
67  	private AMFResponse response;
68  	private SoapUIScriptEngine scriptEngine;
69  	private String endpoint;
70  	private String amfCall;
71  	private String script;
72  	private HashMap<String, TestProperty> propertyMap;
73  	private String[] propertyNames;
74  	private List<Object> arguments = new ArrayList<Object>();
75  	private StringToStringsMap httpHeaders;
76  	private StringToObjectMap amfHeaders;
77  	private StringToStringMap amfHeadersString;
78  
79  	private boolean forLoadTest;
80  	private AssertionStatus currentStatus;
81  
82  	// icon related
83  	private RequestIconAnimator<?> iconAnimator;
84  	private ImageIcon validRequestIcon;
85  	private ImageIcon failedRequestIcon;
86  	private ImageIcon disabledRequestIcon;
87  	private ImageIcon unknownRequestIcon;
88  
89  	public AMFRequest( AMFRequestTestStep testStep, boolean forLoadTest )
90  	{
91  		this.testStep = testStep;
92  
93  		if( !forLoadTest )
94  			initIcons();
95  	}
96  
97  	public AMFSubmit submit( SubmitContext submitContext, boolean async ) throws SubmitException
98  	{
99  
100 		return new AMFSubmit( this, submitContext, async );
101 	}
102 
103 	public boolean executeAmfScript( SubmitContext context )
104 	{
105 		boolean scriptOK = true;
106 		HashMap<String, Object> parameters = new HashMap<String, Object>();
107 		HashMap<String, Object> amfHeadersTemp = new HashMap<String, Object>();
108 		try
109 		{
110 			scriptEngine.setScript( script );
111 			scriptEngine.setVariable( "parameters", parameters );
112 			scriptEngine.setVariable( "amfHeaders", amfHeadersTemp );
113 			scriptEngine.setVariable( "log", SoapUI.ensureGroovyLog() );
114 			scriptEngine.setVariable( "context", context );
115 
116 			scriptEngine.run();
117 
118 			context.setProperty( AMF_SCRIPT_PARAMETERS, parameters );
119 			context.setProperty( AMF_SCRIPT_HEADERS, amfHeadersTemp );
120 
121 			for( String name : propertyNames )
122 			{
123 				if( name.equals( WsdlTestStepWithProperties.RESPONSE_AS_XML ) )
124 					continue; // skip ResponseAsXML
125 
126 				TestProperty propertyValue = propertyMap.get( name );
127 				if( parameters.containsKey( name ) )
128 				{
129 					addArgument( parameters.get( name ) );
130 				}
131 				else
132 				{
133 					addArgument( PropertyExpander.expandProperties( context, propertyValue.getValue() ) );
134 				}
135 			}
136 
137 			StringToObjectMap stringToObjectMap = new StringToObjectMap();
138 			for( String key : getAmfHeadersString().getKeys() )
139 			{
140 				if( amfHeadersTemp.containsKey( key ) )
141 				{
142 					stringToObjectMap.put( key, amfHeadersTemp.get( key ) );
143 				}
144 				else
145 				{
146 					stringToObjectMap.put( key, PropertyExpander
147 							.expandProperties( context, getAmfHeadersString().get( key ) ) );
148 				}
149 			}
150 			setAmfHeaders( stringToObjectMap );
151 
152 		}
153 		catch( Throwable e )
154 		{
155 			SoapUI.logError( e );
156 			scriptOK = false;
157 			context.setProperty( AMF_SCRIPT_ERROR, e );
158 		}
159 		finally
160 		{
161 			scriptEngine.clearVariables();
162 		}
163 		return scriptOK;
164 	}
165 
166 	public AssertionStatus getAssertionStatus()
167 	{
168 		currentStatus = AssertionStatus.UNKNOWN;
169 
170 		if( getResponse() == null )
171 			return currentStatus;
172 
173 		int cnt = getAssertionCount();
174 		if( cnt == 0 )
175 			return currentStatus;
176 
177 		boolean hasEnabled = false;
178 
179 		for( int c = 0; c < cnt; c++ )
180 		{
181 			if( !getAssertionAt( c ).isDisabled() )
182 				hasEnabled = true;
183 
184 			if( getAssertionAt( c ).getStatus() == AssertionStatus.FAILED )
185 			{
186 				currentStatus = AssertionStatus.FAILED;
187 				break;
188 			}
189 		}
190 
191 		if( currentStatus == AssertionStatus.UNKNOWN && hasEnabled )
192 			currentStatus = AssertionStatus.VALID;
193 
194 		return currentStatus;
195 	}
196 
197 	public Map<String, TestAssertion> getAssertions()
198 	{
199 		return testStep.getAssertions();
200 	}
201 
202 	public String getDefaultAssertableContent()
203 	{
204 		return testStep.getDefaultAssertableContent();
205 	}
206 
207 	public Interface getInterface()
208 	{
209 		return testStep.getInterface();
210 	}
211 
212 	public ModelItem getModelItem()
213 	{
214 		return testStep.getModelItem();
215 	}
216 
217 	public TestAssertion moveAssertion( int ix, int offset )
218 	{
219 		return testStep.moveAssertion( ix, offset );
220 	}
221 
222 	public void removeAssertion( TestAssertion assertion )
223 	{
224 		testStep.removeAssertion( assertion );
225 	}
226 
227 	public void removeAssertionsListener( AssertionsListener listener )
228 	{
229 		testStep.removeAssertionsListener( listener );
230 	}
231 
232 	public void setResponse( AMFResponse response )
233 	{
234 		AMFResponse old = this.response;
235 		this.response = response;
236 		notifyPropertyChanged( AMF_RESPONSE_PROPERTY, old, response );
237 	}
238 
239 	public AMFResponse getResponse()
240 	{
241 		return response;
242 	}
243 
244 	public String getResponseContent()
245 	{
246 		if( response != null )
247 		{
248 			return response.getResponseContentXML();
249 		}
250 		else
251 		{
252 			return "";
253 		}
254 	}
255 
256 	public void initIcons()
257 	{
258 		if( validRequestIcon == null )
259 			validRequestIcon = UISupport.createImageIcon( "/valid_amf_request.gif" );
260 
261 		if( failedRequestIcon == null )
262 			failedRequestIcon = UISupport.createImageIcon( "/invalid_amf_request.gif" );
263 
264 		if( unknownRequestIcon == null )
265 			unknownRequestIcon = UISupport.createImageIcon( "/unknown_amf_request.gif" );
266 
267 		if( disabledRequestIcon == null )
268 			disabledRequestIcon = UISupport.createImageIcon( "/disabled_amf_request.gif" );
269 
270 		setIconAnimator( new RequestIconAnimator<AMFRequest>( this, "/amf_request.gif", "/exec_amf_request", 3, "gif" ) );
271 	}
272 
273 	protected RequestIconAnimator<?> initIconAnimator()
274 	{
275 		return new RequestIconAnimator<AMFRequest>( this, "/amf_request.gif", "/exec_amf_request", 3, "gif" );
276 	}
277 
278 	public static class RequestIconAnimator<T extends AMFRequest> extends ModelItemIconAnimator<T> implements
279 			SubmitListener
280 	{
281 		public RequestIconAnimator( T modelItem, String baseIcon, String animIconRoot, int iconCount, String iconExtension )
282 		{
283 			super( modelItem, baseIcon, animIconRoot, iconCount, iconExtension );
284 		}
285 
286 		public boolean beforeSubmit( Submit submit, SubmitContext context )
287 		{
288 			if( isEnabled() && submit.getRequest() == getTarget() )
289 				start();
290 			return true;
291 		}
292 
293 		public void afterSubmit( Submit submit, SubmitContext context )
294 		{
295 			if( submit.getRequest() == getTarget() )
296 				stop();
297 		}
298 	}
299 
300 	public RequestIconAnimator<?> getIconAnimator()
301 	{
302 		return iconAnimator;
303 	}
304 
305 	public void setIconAnimator( RequestIconAnimator<?> iconAnimator )
306 	{
307 		if( this.iconAnimator != null )
308 			removeSubmitListener( this.iconAnimator );
309 
310 		this.iconAnimator = iconAnimator;
311 		addSubmitListener( this.iconAnimator );
312 	}
313 
314 	public ImageIcon getIcon()
315 	{
316 		if( forLoadTest || UISupport.isHeadless() || getIconAnimator() == null )
317 			return null;
318 
319 		TestMonitor testMonitor = SoapUI.getTestMonitor();
320 		if( testMonitor != null && testMonitor.hasRunningLoadTest( getTestStep().getTestCase() ) )
321 			return disabledRequestIcon;
322 
323 		ImageIcon icon = getIconAnimator().getIcon();
324 		if( icon == getIconAnimator().getBaseIcon() )
325 		{
326 			AssertionStatus status = getAssertionStatus();
327 			if( status == AssertionStatus.VALID )
328 				return validRequestIcon;
329 			else if( status == AssertionStatus.FAILED )
330 				return failedRequestIcon;
331 			else if( status == AssertionStatus.UNKNOWN )
332 				return unknownRequestIcon;
333 		}
334 
335 		return icon;
336 	}
337 
338 	@Override
339 	public void setIcon( ImageIcon icon )
340 	{
341 		getTestStep().setIcon( icon );
342 	}
343 
344 	public void setPropertyNames( String[] propertyNames )
345 	{
346 		this.propertyNames = propertyNames;
347 	}
348 
349 	public String[] getPropertyNames()
350 	{
351 		return propertyNames;
352 	}
353 
354 	public void setScriptEngine( SoapUIScriptEngine scriptEngine )
355 	{
356 		this.scriptEngine = scriptEngine;
357 	}
358 
359 	public SoapUIScriptEngine getScriptEngine()
360 	{
361 		return scriptEngine;
362 	}
363 
364 	public String getEndpoint()
365 	{
366 		return endpoint;
367 	}
368 
369 	public void setEndpoint( String endpoint )
370 	{
371 		this.endpoint = endpoint;
372 	}
373 
374 	public String getAmfCall()
375 	{
376 		return amfCall;
377 	}
378 
379 	public void setScript( String script )
380 	{
381 		this.script = script;
382 	}
383 
384 	public String getScript()
385 	{
386 		return script;
387 	}
388 
389 	public void setAmfCall( String amfCall )
390 	{
391 		this.amfCall = amfCall;
392 	}
393 
394 	public HashMap<String, TestProperty> getPropertyMap()
395 	{
396 		return propertyMap;
397 	}
398 
399 	public void setPropertyMap( HashMap<String, TestProperty> map )
400 	{
401 		this.propertyMap = map;
402 	}
403 
404 	public void setArguments( List<Object> arguments )
405 	{
406 		this.arguments = arguments;
407 	}
408 
409 	public void clearArguments()
410 	{
411 		this.arguments.clear();
412 	}
413 
414 	public List<Object> getArguments()
415 	{
416 		return arguments;
417 	}
418 
419 	public List<Object> addArgument( Object obj )
420 	{
421 		arguments.add( obj );
422 		return arguments;
423 	}
424 
425 	public Object[] argumentsToArray()
426 	{
427 		return arguments.toArray();
428 	}
429 
430 	public void addSubmitListener( SubmitListener listener )
431 	{
432 		submitListeners.add( listener );
433 	}
434 
435 	public boolean dependsOn( ModelItem modelItem )
436 	{
437 		return ModelSupport.dependsOn( testStep, modelItem );
438 	}
439 
440 	public Attachment[] getAttachments()
441 	{
442 		return null;
443 	}
444 
445 	public String getEncoding()
446 	{
447 		return null;
448 	}
449 
450 	public Operation getOperation()
451 	{
452 		return null;
453 	}
454 
455 	public String getRequestContent()
456 	{
457 		return requestAsXML();
458 	}
459 
460 	public MessagePart[] getRequestParts()
461 	{
462 		return null;
463 	}
464 
465 	public MessagePart[] getResponseParts()
466 	{
467 		return null;
468 	}
469 
470 	public String getTimeout()
471 	{
472 		return null;// testStep.getQueryTimeout();
473 	}
474 
475 	public void removeSubmitListener( SubmitListener listener )
476 	{
477 		submitListeners.remove( listener );
478 	}
479 
480 	public void setEncoding( String string )
481 	{
482 	}
483 
484 	public List<? extends ModelItem> getChildren()
485 	{
486 		return null;
487 	}
488 
489 	public String getDescription()
490 	{
491 		return testStep.getDescription();
492 	}
493 
494 	public String getId()
495 	{
496 		return testStep.getId();
497 	}
498 
499 	public String getName()
500 	{
501 		return testStep.getName();
502 	}
503 
504 	public ModelItem getParent()
505 	{
506 		return testStep.getParent();
507 	}
508 
509 	public Settings getSettings()
510 	{
511 		return testStep.getSettings();
512 	}
513 
514 	public SubmitListener[] getSubmitListeners()
515 	{
516 		return submitListeners.toArray( new SubmitListener[submitListeners.size()] );
517 	}
518 
519 	public AMFRequestTestStep getTestStep()
520 	{
521 		return testStep;
522 	}
523 
524 	public WsdlMessageAssertion importAssertion( WsdlMessageAssertion source, boolean overwrite, boolean createCopy,
525 			String newName )
526 	{
527 		return testStep.importAssertion( source, overwrite, createCopy, newName );
528 	}
529 
530 	public TestAssertion addAssertion( String selection )
531 	{
532 		return testStep.addAssertion( selection );
533 	}
534 
535 	public void addAssertionsListener( AssertionsListener listener )
536 	{
537 		testStep.addAssertionsListener( listener );
538 	}
539 
540 	public TestAssertion cloneAssertion( TestAssertion source, String name )
541 	{
542 		return testStep.cloneAssertion( source, name );
543 	}
544 
545 	public String getAssertableContent()
546 	{
547 		return testStep.getAssertableContent();
548 	}
549 
550 	public AssertableType getAssertableType()
551 	{
552 		return testStep.getAssertableType();
553 	}
554 
555 	public TestAssertion getAssertionAt( int c )
556 	{
557 		return testStep.getAssertionAt( c );
558 	}
559 
560 	public TestAssertion getAssertionByName( String name )
561 	{
562 		return testStep.getAssertionByName( name );
563 	}
564 
565 	public int getAssertionCount()
566 	{
567 		return testStep.getAssertionCount();
568 	}
569 
570 	public List<TestAssertion> getAssertionList()
571 	{
572 		return testStep.getAssertionList();
573 	}
574 
575 	public String requestAsXML()
576 	{
577 		StringBuffer sb = new StringBuffer();
578 		sb.append( "<AMFRequest>\n" );
579 		sb.append( " <endpoint>" + getEndpoint() + "</endpoint>\n" );
580 		sb.append( " <amfcall>" + getAmfCall() + "</amfcall>\n" );
581 
582 		if( getPropertyNames() != null )
583 		{
584 			sb.append( " <parameters>\n" );
585 			for( String name : getPropertyNames() )
586 			{
587 				if( name.equals( WsdlTestStepWithProperties.RESPONSE_AS_XML ) )
588 					continue;
589 				sb.append( "  <parameter>\n" );
590 				sb.append( "   <name>" + name + "</name>\n" );
591 				sb.append( "   <value>" + getPropertyMap().get( name ).getValue() + "</value>\n" );
592 				sb.append( "  </parameter>\n" );
593 			}
594 			sb.append( " </parameters>\n" );
595 		}
596 
597 		sb.append( " <script>" + getScript() + "</script>\n" );
598 		sb.append( "</AMFRequest>" );
599 		return sb.toString();
600 	}
601 
602 	public void setHttpHeaders( StringToStringsMap httpHeaders )
603 	{
604 		this.httpHeaders = httpHeaders;
605 	}
606 
607 	public StringToStringsMap getHttpHeaders()
608 	{
609 		return httpHeaders;
610 	}
611 
612 	public void setAmfHeaders( StringToObjectMap amfHeaders )
613 	{
614 		this.amfHeaders = amfHeaders;
615 	}
616 
617 	public StringToObjectMap getAmfHeaders()
618 	{
619 		return amfHeaders;
620 	}
621 
622 	public void setAmfHeadersString( StringToStringMap amfHeadersString )
623 	{
624 		this.amfHeadersString = amfHeadersString;
625 	}
626 
627 	public StringToStringMap getAmfHeadersString()
628 	{
629 		return amfHeadersString;
630 	}
631 
632 	public String getPassword()
633 	{
634 		return null;
635 	}
636 
637 	public String getUsername()
638 	{
639 		return null;
640 	}
641 
642 	public boolean isDiscardResponse()
643 	{
644 		return getSettings().getBoolean( "discardResponse" );
645 	}
646 
647 	public void setDiscardResponse( boolean discardResponse )
648 	{
649 		getSettings().setBoolean( "discardResponse", discardResponse );
650 	}
651 }