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