1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.teststeps;
14
15 import java.beans.PropertyChangeEvent;
16 import java.beans.PropertyChangeListener;
17 import java.util.ArrayList;
18 import java.util.HashMap;
19 import java.util.List;
20 import java.util.Map;
21
22 import javax.swing.ImageIcon;
23
24 import org.apache.log4j.Logger;
25
26 import com.eviware.soapui.SoapUI;
27 import com.eviware.soapui.config.AMFRequestTestStepConfig;
28 import com.eviware.soapui.config.PropertiesTypeConfig;
29 import com.eviware.soapui.config.PropertyConfig;
30 import com.eviware.soapui.config.TestAssertionConfig;
31 import com.eviware.soapui.config.TestStepConfig;
32 import com.eviware.soapui.impl.rest.support.RestParamProperty;
33 import com.eviware.soapui.impl.wsdl.MutableTestPropertyHolder;
34 import com.eviware.soapui.impl.wsdl.panels.teststeps.amf.AMFRequest;
35 import com.eviware.soapui.impl.wsdl.panels.teststeps.amf.AMFResponse;
36 import com.eviware.soapui.impl.wsdl.panels.teststeps.amf.AMFSubmit;
37 import com.eviware.soapui.impl.wsdl.support.AMFMessageExchange;
38 import com.eviware.soapui.impl.wsdl.support.XmlBeansPropertiesTestPropertyHolder;
39 import com.eviware.soapui.impl.wsdl.support.assertions.AssertableConfig;
40 import com.eviware.soapui.impl.wsdl.support.assertions.AssertedXPathsContainer;
41 import com.eviware.soapui.impl.wsdl.support.assertions.AssertionsSupport;
42 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
43 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestRunContext;
44 import com.eviware.soapui.impl.wsdl.teststeps.assertions.TestAssertionRegistry.AssertableType;
45 import com.eviware.soapui.model.iface.Interface;
46 import com.eviware.soapui.model.iface.Submit;
47 import com.eviware.soapui.model.iface.SubmitContext;
48 import com.eviware.soapui.model.iface.Request.SubmitException;
49 import com.eviware.soapui.model.propertyexpansion.PropertyExpander;
50 import com.eviware.soapui.model.propertyexpansion.PropertyExpansionUtils;
51 import com.eviware.soapui.model.support.TestStepBeanProperty;
52 import com.eviware.soapui.model.testsuite.Assertable;
53 import com.eviware.soapui.model.testsuite.AssertionError;
54 import com.eviware.soapui.model.testsuite.AssertionsListener;
55 import com.eviware.soapui.model.testsuite.TestAssertion;
56 import com.eviware.soapui.model.testsuite.TestCaseRunContext;
57 import com.eviware.soapui.model.testsuite.TestCaseRunner;
58 import com.eviware.soapui.model.testsuite.TestProperty;
59 import com.eviware.soapui.model.testsuite.TestPropertyListener;
60 import com.eviware.soapui.model.testsuite.TestRunContext;
61 import com.eviware.soapui.model.testsuite.TestStepResult;
62 import com.eviware.soapui.model.testsuite.TestStepResult.TestStepStatus;
63 import com.eviware.soapui.support.scripting.SoapUIScriptEngine;
64 import com.eviware.soapui.support.scripting.SoapUIScriptEngineRegistry;
65 import com.eviware.soapui.support.types.StringToStringMap;
66
67 /***
68 *
69 * @author nebojsa.tasic
70 */
71
72 public class AMFRequestTestStep extends WsdlTestStepWithProperties implements Assertable, MutableTestPropertyHolder,
73 PropertyChangeListener
74 {
75 @SuppressWarnings( "unused" )
76 private final static Logger log = Logger.getLogger( WsdlTestRequestStep.class );
77 protected AMFRequestTestStepConfig amfRequestTestStepConfig;
78 public final static String amfREQUEST = AMFRequestTestStep.class.getName() + "@amfrequest";
79 public static final String STATUS_PROPERTY = WsdlTestRequest.class.getName() + "@status";
80 public static final String RESPONSE_PROPERTY = "response";
81 public static final String REQUEST_PROPERTY = "request";
82 public static final String HTTP_HEADERS_PROPERTY = AMFRequest.class.getName() + "@request-headers";
83 public static final String AMF_HEADERS_PROPERTY = AMFRequest.class.getName() + "@amfrequest-amfheaders";
84 private AMFSubmit submit;
85
86 private SoapUIScriptEngine scriptEngine;
87 private AssertionsSupport assertionsSupport;
88 private PropertyChangeNotifier notifier;
89 private XmlBeansPropertiesTestPropertyHolder propertyHolderSupport;
90
91 private AMFRequest amfRequest;
92
93 public AMFRequestTestStep( WsdlTestCase testCase, TestStepConfig config, boolean forLoadTest )
94 {
95 super( testCase, config, true, forLoadTest );
96
97 if( getConfig().getConfig() != null )
98 {
99 amfRequestTestStepConfig = ( AMFRequestTestStepConfig )getConfig().getConfig().changeType(
100 AMFRequestTestStepConfig.type );
101
102 }
103 else
104 {
105 amfRequestTestStepConfig = ( AMFRequestTestStepConfig )getConfig().addNewConfig().changeType(
106 AMFRequestTestStepConfig.type );
107 }
108
109 if( amfRequestTestStepConfig.getProperties() == null )
110 amfRequestTestStepConfig.addNewProperties();
111
112 amfRequest = new AMFRequest( this );
113
114
115 propertyHolderSupport = new XmlBeansPropertiesTestPropertyHolder( this, amfRequestTestStepConfig.getProperties() );
116 addResponseAsXMLVirtualProperty();
117
118 initAssertions();
119 amfRequest.initIcons();
120
121 scriptEngine = SoapUIScriptEngineRegistry.create( this );
122 scriptEngine.setScript( getScript() );
123 if( forLoadTest && !isDisabled() )
124 try
125 {
126 scriptEngine.compile();
127 }
128 catch( Exception e )
129 {
130 SoapUI.logError( e );
131 }
132 }
133
134 private void addResponseAsXMLVirtualProperty()
135 {
136 TestStepBeanProperty responseProperty = new TestStepBeanProperty( "ResponseAsXML", false, amfRequest,
137 "responseContent", this )
138 {
139 @Override
140 public String getDefaultValue()
141 {
142 return "";
143 }
144
145 };
146
147 propertyHolderSupport.addVirtualProperty( "ResponseAsXML", responseProperty );
148 }
149
150 public AMFRequestTestStepConfig getAMFRequestTestStepConfig()
151 {
152 return amfRequestTestStepConfig;
153 }
154
155 @Override
156 public WsdlTestStep clone( WsdlTestCase targetTestCase, String name )
157 {
158 beforeSave();
159
160 TestStepConfig config = ( TestStepConfig )getConfig().copy();
161 AMFRequestTestStep result = ( AMFRequestTestStep )targetTestCase.addTestStep( config );
162
163 return result;
164 }
165
166 @Override
167 public void release()
168 {
169 super.release();
170 }
171
172 public TestStepResult run( TestCaseRunner runner, TestCaseRunContext runContext )
173 {
174 AMFTestStepResult testStepResult = new AMFTestStepResult( this );
175 testStepResult.startTimer();
176 runContext.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, testStepResult );
177
178 try
179 {
180 if( !initAmfRequest( runContext ) )
181 {
182 throw new SubmitException( "AMF request is not initialised properly !" );
183 }
184 submit = amfRequest.submit( runContext, false );
185 AMFResponse response = submit.getResponse();
186
187 if( submit.getStatus() != Submit.Status.CANCELED )
188 {
189 if( submit.getStatus() == Submit.Status.ERROR )
190 {
191 testStepResult.setStatus( TestStepStatus.FAILED );
192 testStepResult.addMessage( submit.getError().toString() );
193
194 amfRequest.setResponse( null );
195 }
196 else if( response == null )
197 {
198 testStepResult.setStatus( TestStepStatus.FAILED );
199 testStepResult.addMessage( "Request is missing response" );
200
201 amfRequest.setResponse( null );
202 }
203 else
204 {
205 runContext.setProperty( AssertedXPathsContainer.ASSERTEDXPATHSCONTAINER_PROPERTY, testStepResult );
206 amfRequest.setResponse( response );
207
208 testStepResult.setTimeTaken( response.getTimeTaken() );
209 testStepResult.setSize( response.getContentLength() );
210
211 switch( amfRequest.getAssertionStatus() )
212 {
213 case FAILED :
214 testStepResult.setStatus( TestStepStatus.FAILED );
215 break;
216 case VALID :
217 testStepResult.setStatus( TestStepStatus.OK );
218 break;
219 case UNKNOWN :
220 testStepResult.setStatus( TestStepStatus.UNKNOWN );
221 break;
222 }
223
224 testStepResult.setResponse( response, testStepResult.getStatus() != TestStepStatus.FAILED );
225 }
226 }
227 else
228 {
229 testStepResult.setStatus( TestStepStatus.CANCELED );
230 testStepResult.addMessage( "Request was canceled" );
231 }
232
233 if( response != null )
234 testStepResult.setRequestContent( response.getRequestContent() );
235 else
236 testStepResult.setRequestContent( amfRequest.getRequestContent() );
237
238 testStepResult.stopTimer();
239 }
240 catch( SubmitException e )
241 {
242 testStepResult.setStatus( TestStepStatus.FAILED );
243 testStepResult.addMessage( "SubmitException: " + e );
244 testStepResult.stopTimer();
245 }
246 finally
247 {
248 submit = null;
249 }
250
251 if( testStepResult.getStatus() != TestStepStatus.CANCELED )
252 {
253 assertResponse( runContext );
254
255 AssertionStatus assertionStatus = amfRequest.getAssertionStatus();
256 switch( assertionStatus )
257 {
258 case FAILED :
259 {
260 testStepResult.setStatus( TestStepStatus.FAILED );
261 if( getAssertionCount() == 0 )
262 {
263 testStepResult.addMessage( "Invalid/empty response" );
264 }
265 else
266 for( int c = 0; c < getAssertionCount(); c++ )
267 {
268 TestAssertion assertion = getAssertionAt( c );
269 AssertionError[] errors = assertion.getErrors();
270 if( errors != null )
271 {
272 for( AssertionError error : errors )
273 {
274 testStepResult.addMessage( "[" + assertion.getName() + "] " + error.getMessage() );
275 }
276 }
277 }
278
279 break;
280 }
281
282 }
283 }
284
285 if( !runContext.hasProperty( TestRunContext.INTERACTIVE ) )
286 amfRequest.setResponse( null );
287
288 return testStepResult;
289 }
290
291 @Override
292 public boolean cancel()
293 {
294 if( submit == null )
295 return false;
296
297 submit.cancel();
298
299 return true;
300 }
301
302 public String getDefaultSourcePropertyName()
303 {
304 return "Response";
305 }
306
307 private void initAssertions()
308 {
309 assertionsSupport = new AssertionsSupport( this, new AssertableConfig()
310 {
311
312 public TestAssertionConfig addNewAssertion()
313 {
314 return getAMFRequestTestStepConfig().addNewAssertion();
315 }
316
317 public List<TestAssertionConfig> getAssertionList()
318 {
319 return getAMFRequestTestStepConfig().getAssertionList();
320 }
321
322 public void removeAssertion( int ix )
323 {
324 getAMFRequestTestStepConfig().removeAssertion( ix );
325 }
326
327 public TestAssertionConfig insertAssertion( TestAssertionConfig source, int ix )
328 {
329 TestAssertionConfig conf = getAMFRequestTestStepConfig().insertNewAssertion( ix );
330 conf.set( source );
331 return conf;
332 }
333 } );
334 }
335
336 private class PropertyChangeNotifier
337 {
338 private AssertionStatus oldStatus;
339 private ImageIcon oldIcon;
340
341 public PropertyChangeNotifier()
342 {
343 oldStatus = getAssertionStatus();
344 oldIcon = getIcon();
345 }
346
347 public void notifyChange()
348 {
349 AssertionStatus newStatus = getAssertionStatus();
350 ImageIcon newIcon = getIcon();
351
352 if( oldStatus != newStatus )
353 notifyPropertyChanged( STATUS_PROPERTY, oldStatus, newStatus );
354
355 if( oldIcon != newIcon )
356 notifyPropertyChanged( ICON_PROPERTY, oldIcon, getIcon() );
357
358 oldStatus = newStatus;
359 oldIcon = newIcon;
360 }
361 }
362
363 public TestAssertion addAssertion( String assertionLabel )
364 {
365 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
366
367 try
368 {
369 WsdlMessageAssertion assertion = assertionsSupport.addWsdlAssertion( assertionLabel );
370 if( assertion == null )
371 return null;
372
373 if( getAMFRequest().getResponse() != null )
374 {
375 assertion.assertResponse( new AMFMessageExchange( this, getAMFRequest().getResponse() ),
376 new WsdlTestRunContext( this ) );
377 notifier.notifyChange();
378 }
379
380 return assertion;
381 }
382 catch( Exception e )
383 {
384 SoapUI.logError( e );
385 return null;
386 }
387 }
388
389 public void addAssertionsListener( AssertionsListener listener )
390 {
391 assertionsSupport.addAssertionsListener( listener );
392 }
393
394 public TestAssertion cloneAssertion( TestAssertion source, String name )
395 {
396 return assertionsSupport.cloneAssertion( source, name );
397 }
398
399 public String getAssertableContent()
400 {
401 return getAMFRequest().getResponse() == null ? null : getAMFRequest().getResponse().getContentAsString();
402 }
403
404 public WsdlMessageAssertion importAssertion( WsdlMessageAssertion source, boolean overwrite, boolean createCopy )
405 {
406 return assertionsSupport.importAssertion( source, overwrite, createCopy );
407 }
408
409 public AssertableType getAssertableType()
410 {
411 return AssertableType.RESPONSE;
412 }
413
414 public TestAssertion getAssertionAt( int c )
415 {
416 return assertionsSupport.getAssertionAt( c );
417 }
418
419 public TestAssertion getAssertionByName( String name )
420 {
421 return assertionsSupport.getAssertionByName( name );
422 }
423
424 public int getAssertionCount()
425 {
426 return assertionsSupport.getAssertionCount();
427 }
428
429 public List<TestAssertion> getAssertionList()
430 {
431 return new ArrayList<TestAssertion>( assertionsSupport.getAssertionList() );
432 }
433
434 public void propertyChange( PropertyChangeEvent arg0 )
435 {
436 if( arg0.getPropertyName().equals( TestAssertion.CONFIGURATION_PROPERTY )
437 || arg0.getPropertyName().equals( TestAssertion.DISABLED_PROPERTY ) )
438 {
439 if( getAMFRequest().getResponse() != null )
440 {
441 assertResponse( new WsdlTestRunContext( this ) );
442 }
443 }
444 }
445
446 public Map<String, TestAssertion> getAssertions()
447 {
448 return assertionsSupport.getAssertions();
449 }
450
451 public String getDefaultAssertableContent()
452 {
453 return null;
454 }
455
456 public AssertionStatus getAssertionStatus()
457 {
458 return amfRequest.getAssertionStatus();
459 }
460
461 public ImageIcon getIcon()
462 {
463 return amfRequest.getIcon();
464 }
465
466 public Interface getInterface()
467 {
468 return null;
469 }
470
471 public TestAssertion moveAssertion( int ix, int offset )
472 {
473 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
474 TestAssertion assertion = getAssertionAt( ix );
475 try
476 {
477 return assertionsSupport.moveAssertion( ix, offset );
478 }
479 finally
480 {
481 ( ( WsdlMessageAssertion )assertion ).release();
482 notifier.notifyChange();
483 }
484 }
485
486 public void removeAssertion( TestAssertion assertion )
487 {
488 PropertyChangeNotifier notifier = new PropertyChangeNotifier();
489
490 try
491 {
492 assertionsSupport.removeAssertion( ( WsdlMessageAssertion )assertion );
493
494 }
495 finally
496 {
497 ( ( WsdlMessageAssertion )assertion ).release();
498 notifier.notifyChange();
499 }
500 }
501
502 public void removeAssertionsListener( AssertionsListener listener )
503 {
504 assertionsSupport.removeAssertionsListener( listener );
505 }
506
507 public void assertResponse( SubmitContext context )
508 {
509 try
510 {
511 if( notifier == null )
512 notifier = new PropertyChangeNotifier();
513
514 AMFMessageExchange messageExchange = new AMFMessageExchange( this, getAMFRequest().getResponse() );
515
516 if( this != null )
517 {
518
519 for( WsdlMessageAssertion assertion : assertionsSupport.getAssertionList() )
520 {
521 assertion.assertResponse( messageExchange, context );
522 }
523 }
524
525 notifier.notifyChange();
526 }
527 catch( Exception e )
528 {
529 e.printStackTrace();
530 }
531 }
532
533 public TestProperty addProperty( String name )
534 {
535 return propertyHolderSupport.addProperty( name );
536 }
537
538 public TestProperty removeProperty( String propertyName )
539 {
540 return propertyHolderSupport.removeProperty( propertyName );
541 }
542
543 public boolean renameProperty( String name, String newName )
544 {
545 return PropertyExpansionUtils.renameProperty( propertyHolderSupport.getProperty( name ), newName, getTestCase() ) != null;
546 }
547
548 public void addTestPropertyListener( TestPropertyListener listener )
549 {
550 propertyHolderSupport.addTestPropertyListener( listener );
551 }
552
553 public Map<String, TestProperty> getProperties()
554 {
555 return propertyHolderSupport.getProperties();
556 }
557
558 public TestProperty getProperty( String name )
559 {
560 return propertyHolderSupport.getProperty( name );
561 }
562
563 public TestProperty getPropertyAt( int index )
564 {
565 return propertyHolderSupport.getPropertyAt( index );
566 }
567
568 public int getPropertyCount()
569 {
570 return propertyHolderSupport.getPropertyCount();
571 }
572
573 public List<TestProperty> getPropertyList()
574 {
575 return propertyHolderSupport.getPropertyList();
576 }
577
578 public String[] getPropertyNames()
579 {
580 return propertyHolderSupport.getPropertyNames();
581 }
582
583 public String getPropertyValue( String name )
584 {
585 return propertyHolderSupport.getPropertyValue( name );
586 }
587
588 public void removeTestPropertyListener( TestPropertyListener listener )
589 {
590 propertyHolderSupport.removeTestPropertyListener( listener );
591 }
592
593 public boolean hasProperty( String name )
594 {
595 return propertyHolderSupport.hasProperty( name );
596 }
597
598 public void setPropertyValue( String name, String value )
599 {
600 propertyHolderSupport.setPropertyValue( name, value );
601 }
602
603 public void setPropertyValue( String name, Object value )
604 {
605 setPropertyValue( name, String.valueOf( value ) );
606 }
607
608 public void moveProperty( String propertyName, int targetIndex )
609 {
610 propertyHolderSupport.moveProperty( propertyName, targetIndex );
611 }
612
613 public AMFRequest getAMFRequest()
614 {
615 return amfRequest;
616 }
617
618 public void setResponse( AMFResponse response, SubmitContext context )
619 {
620 AMFResponse oldResponse = amfRequest.getResponse();
621 amfRequest.setResponse( response );
622
623 notifyPropertyChanged( RESPONSE_PROPERTY, oldResponse, response );
624 assertResponse( context );
625 }
626
627 public String getScript()
628 {
629 return amfRequestTestStepConfig.getScript() != null ? amfRequestTestStepConfig.getScript().getStringValue() : "";
630 }
631
632 public void setScript( String script )
633 {
634 String old = getScript();
635 scriptEngine.setScript( script );
636 if( amfRequestTestStepConfig.getScript() == null )
637 {
638 amfRequestTestStepConfig.addNewScript();
639 }
640
641 amfRequestTestStepConfig.getScript().setStringValue( script );
642 notifyPropertyChanged( "script", old, script );
643 }
644
645 public String getAmfCall()
646 {
647 return amfRequestTestStepConfig.getAmfCall();
648 }
649
650 public void setAmfCall( String amfCall )
651 {
652 String old = getAmfCall();
653 amfRequestTestStepConfig.setAmfCall( amfCall );
654 notifyPropertyChanged( "amfCall", old, amfCall );
655 }
656
657 public String getEndpoint()
658 {
659 return amfRequestTestStepConfig.getEndpoint();
660 }
661
662 public void setEndpoint( String endpoint )
663 {
664 String old = getEndpoint();
665 amfRequestTestStepConfig.setEndpoint( endpoint );
666 notifyPropertyChanged( "endpoint", old, endpoint );
667 }
668
669 public boolean initAmfRequest( SubmitContext submitContext )
670 {
671 amfRequest.setScriptEngine( scriptEngine );
672 amfRequest.setAmfCall( PropertyExpander.expandProperties( submitContext, getAmfCall() ) );
673 amfRequest.setEndpoint( PropertyExpander.expandProperties( submitContext, getEndpoint() ) );
674 amfRequest.setScript( getScript() );
675 amfRequest.setPropertyNames( getPropertyNames() );
676 amfRequest.setPropertyMap( ( HashMap<String, TestProperty> )getProperties() );
677 amfRequest.setHttpHeaders( getHttpHeaders() );
678 amfRequest.setAmfHeadersString( getAmfHeaders() );
679
680 return amfRequest.executeAmfScript( submitContext );
681 }
682
683 public void setHttpHeaders( StringToStringMap httpHeaders )
684 {
685 StringToStringMap old = getHttpHeaders();
686 getSettings().setString( HTTP_HEADERS_PROPERTY, httpHeaders.toXml() );
687 notifyPropertyChanged( HTTP_HEADERS_PROPERTY, old, httpHeaders );
688 }
689
690 public StringToStringMap getHttpHeaders()
691 {
692 return StringToStringMap.fromXml( getSettings().getString( HTTP_HEADERS_PROPERTY, null ) );
693 }
694
695 public void setAmfHeaders( StringToStringMap amfHeaders )
696 {
697 StringToStringMap old = getAmfHeaders();
698 getSettings().setString( AMF_HEADERS_PROPERTY, amfHeaders.toXml() );
699 notifyPropertyChanged( AMF_HEADERS_PROPERTY, old, amfHeaders );
700 }
701
702 public StringToStringMap getAmfHeaders()
703 {
704 return StringToStringMap.fromXml( getSettings().getString( AMF_HEADERS_PROPERTY, null ) );
705 }
706
707 public void resetConfigOnMove( TestStepConfig config )
708 {
709 super.resetConfigOnMove( config );
710 amfRequestTestStepConfig = ( AMFRequestTestStepConfig )config.getConfig().changeType(
711 AMFRequestTestStepConfig.type );
712 propertyHolderSupport.resetPropertiesConfig( amfRequestTestStepConfig.getProperties() );
713
714 assertionsSupport.refresh();
715 }
716
717 public XmlBeansPropertiesTestPropertyHolder getPropertyHolderSupport()
718 {
719 return propertyHolderSupport;
720 }
721 }