1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.panels.teststeps.amf;
14
15 import java.util.List;
16 import java.util.concurrent.Future;
17
18 import com.eviware.soapui.SoapUI;
19 import com.eviware.soapui.config.TestCaseConfig;
20 import com.eviware.soapui.impl.wsdl.testcase.WsdlTestCase;
21 import com.eviware.soapui.impl.wsdl.teststeps.AMFRequestTestStep;
22 import com.eviware.soapui.model.iface.Submit;
23 import com.eviware.soapui.model.iface.SubmitContext;
24 import com.eviware.soapui.model.iface.SubmitListener;
25 import com.eviware.soapui.support.StringUtils;
26 import com.eviware.soapui.support.UISupport;
27 import com.eviware.soapui.support.types.StringToStringsMap;
28
29 import flex.messaging.io.amf.client.exceptions.ClientStatusException;
30 import flex.messaging.io.amf.client.exceptions.ServerStatusException;
31
32 public class AMFSubmit implements Submit, Runnable
33 {
34 public static final String AMF_CONNECTION = "AMF_CONNECTION";
35 private volatile Future<?> future;
36 private SubmitContext context;
37 private Status status;
38 private SubmitListener[] listeners;
39 private Exception error;
40 private long timestamp;
41 private final AMFRequest request;
42 private AMFResponse response;
43 private AMFCredentials credentials;
44
45 public AMFSubmit( AMFRequest request, SubmitContext submitContext, boolean async )
46 {
47 this.request = request;
48 this.context = submitContext;
49
50 List<SubmitListener> regListeners = SoapUI.getListenerRegistry().getListeners( SubmitListener.class );
51
52 SubmitListener[] submitListeners = request.getSubmitListeners();
53 this.listeners = new SubmitListener[submitListeners.length + regListeners.size()];
54 for( int c = 0; c < submitListeners.length; c++ )
55 this.listeners[c] = submitListeners[c];
56
57 for( int c = 0; c < regListeners.size(); c++ )
58 this.listeners[submitListeners.length + c] = regListeners.get( c );
59
60 error = null;
61 status = Status.INITIALIZED;
62 timestamp = System.currentTimeMillis();
63
64 if( async )
65 future = SoapUI.getThreadPool().submit( this );
66 else
67 run();
68 }
69
70 public void cancel()
71 {
72 if( status == Status.CANCELED )
73 return;
74
75 SoapUI.log.info( "Canceling request.." );
76
77 status = Status.CANCELED;
78
79 for( int i = 0; i < listeners.length; i++ )
80 {
81 try
82 {
83 listeners[i].afterSubmit( this, context );
84 }
85 catch( Throwable e )
86 {
87 SoapUI.logError( e );
88 }
89 }
90 }
91
92 public Status waitUntilFinished()
93 {
94 if( future != null )
95 {
96 if( !future.isDone() )
97 {
98 try
99 {
100 future.get();
101 }
102 catch( Exception e )
103 {
104 SoapUI.logError( e );
105 }
106 }
107 }
108 else
109 throw new RuntimeException( "cannot wait on null future" );
110
111 return getStatus();
112 }
113
114 public void run()
115 {
116 try
117 {
118 for( int i = 0; i < listeners.length; i++ )
119 {
120 if( !listeners[i].beforeSubmit( this, context ) )
121 {
122 status = Status.CANCELED;
123 SoapUI.log.error( "listener cancelled submit.." );
124 return;
125 }
126 }
127
128 status = Status.RUNNING;
129 Object responseContent = executeAmfCall( getRequest() );
130 createResponse( responseContent );
131
132 if( status != Status.CANCELED && status != Status.ERROR )
133 {
134 status = Status.FINISHED;
135 }
136 }
137 catch( Exception e )
138 {
139 UISupport.showErrorMessage( "There's been an error in executing query " + e.toString() );
140 error = e;
141 }
142 finally
143 {
144
145 if( status != Status.CANCELED )
146 {
147 for( int i = 0; i < listeners.length; i++ )
148 {
149 try
150 {
151 listeners[i].afterSubmit( this, context );
152 }
153 catch( Throwable e )
154 {
155 SoapUI.logError( e );
156 }
157 }
158 }
159 }
160 }
161
162 protected void createResponse( Object responseContent )
163 {
164 try
165 {
166 response = new AMFResponse( request, context, responseContent );
167 response.setTimestamp( timestamp );
168 response.setTimeTaken( System.currentTimeMillis() - timestamp );
169 }
170 catch( Exception e )
171 {
172 SoapUI.logError( e );
173 }
174
175 }
176
177 private Object executeAmfCall( AMFRequest amfRequest ) throws ClientStatusException, ServerStatusException
178 {
179 SoapUIAMFConnection amfConnection = null;
180 try
181 {
182 amfConnection = getConnection( amfRequest );
183 addAmfHeaders( amfRequest, amfConnection );
184 addHttpHeaders( amfRequest, amfConnection );
185 Object result = amfConnection.call( context, amfRequest.getAmfCall(), amfRequest.argumentsToArray() );
186
187 return result;
188 }
189 catch( Exception e )
190 {
191 SoapUI.logError( e );
192 error = e;
193 status = Status.ERROR;
194 }
195 finally
196 {
197 amfRequest.clearArguments();
198 if( context.getModelItem() instanceof AMFRequestTestStep )
199 {
200 if( credentials != null && credentials.isLoggedIn() )
201 {
202 credentials.logout();
203 credentials = null;
204 }
205 else
206 {
207 amfConnection.close();
208 }
209 }
210 }
211 return null;
212
213 }
214
215 private SoapUIAMFConnection getConnection( AMFRequest amfRequest ) throws Exception
216 {
217 SoapUIAMFConnection amfConnection = null;
218 if( isAuthorisationEnabled( amfRequest ) && ( context.getModelItem() instanceof WsdlTestCase ) )
219 {
220 if( ( amfConnection = ( SoapUIAMFConnection )context.getProperty( AMF_CONNECTION ) ) != null )
221 {
222 return amfConnection;
223 }
224 else
225 {
226 throw new Exception( "amf session connection error! " );
227 }
228 }
229 else if( isAuthorisationEnabled( amfRequest ) && ( context.getModelItem() instanceof AMFRequestTestStep ) )
230 {
231 String endpoint = context.expand( getTestCaseConfig( amfRequest ).getAmfEndpoint() );
232 String username = context.expand( getTestCaseConfig( amfRequest ).getAmfLogin() );
233 String password = context.expand( getTestCaseConfig( amfRequest ).getAmfPassword() );
234
235 if( StringUtils.hasContent( endpoint ) && StringUtils.hasContent( username ) )
236 {
237 credentials = new AMFCredentials( endpoint, username, password, context );
238 amfConnection = credentials.login();
239 }
240 else
241 {
242 amfConnection = new SoapUIAMFConnection();
243 amfConnection.connect( context.expand( amfRequest.getEndpoint() ) );
244 }
245
246 context.setProperty( AMF_CONNECTION, amfConnection );
247 return amfConnection;
248 }
249 else
250 {
251 amfConnection = new SoapUIAMFConnection();
252 amfConnection.connect( context.expand( amfRequest.getEndpoint() ) );
253 return amfConnection;
254 }
255 }
256
257 private boolean isAuthorisationEnabled( AMFRequest amfRequest )
258 {
259 return getTestCaseConfig( amfRequest ).getAmfAuthorisation();
260 }
261
262 private TestCaseConfig getTestCaseConfig( AMFRequest amfRequest )
263 {
264 return amfRequest.getTestStep().getTestCase().getConfig();
265 }
266
267 private void addHttpHeaders( AMFRequest amfRequest, SoapUIAMFConnection amfConnection )
268 {
269 StringToStringsMap httpHeaders = amfRequest.getHttpHeaders();
270 if( httpHeaders != null )
271 {
272 for( String key : httpHeaders.getKeys() )
273 {
274 for( String value : httpHeaders.get( key ) )
275 amfConnection.addHttpRequestHeader( key, context.expand( value ) );
276 }
277 }
278 }
279
280 private void addAmfHeaders( AMFRequest amfRequest, SoapUIAMFConnection amfConnection )
281 {
282 if( amfRequest.getAmfHeaders() != null )
283 {
284 for( String key : amfRequest.getAmfHeaders().keySet() )
285 {
286 Object data = amfRequest.getAmfHeaders().get( key );
287 if( data instanceof String )
288 data = context.expand( ( String )data );
289
290 amfConnection.addAmfHeader( key, data );
291 }
292 }
293 }
294
295 public Exception getError()
296 {
297 return error;
298 }
299
300 public AMFRequest getRequest()
301 {
302 return request;
303 }
304
305 public AMFResponse getResponse()
306 {
307 return response;
308 }
309
310 public Status getStatus()
311 {
312 return status;
313 }
314
315 }