1
2
3
4
5
6
7
8
9
10
11
12
13 package com.eviware.soapui.impl.wsdl.monitor;
14
15 import java.io.ByteArrayInputStream;
16 import java.io.IOException;
17 import java.io.StringWriter;
18 import java.net.URL;
19 import java.util.Vector;
20
21 import org.apache.commons.httpclient.Header;
22 import org.apache.commons.httpclient.HttpParser;
23 import org.apache.xmlbeans.XmlObject;
24 import org.w3c.dom.Document;
25
26 import com.eviware.soapui.SoapUI;
27 import com.eviware.soapui.impl.wsdl.WsdlOperation;
28 import com.eviware.soapui.impl.wsdl.WsdlProject;
29 import com.eviware.soapui.impl.wsdl.submit.WsdlMessageExchange;
30 import com.eviware.soapui.impl.wsdl.submit.transports.http.MultipartMessageSupport;
31 import com.eviware.soapui.impl.wsdl.support.soap.SoapUtils;
32 import com.eviware.soapui.impl.wsdl.support.soap.SoapVersion;
33 import com.eviware.soapui.impl.wsdl.support.wss.IncomingWss;
34 import com.eviware.soapui.model.ModelItem;
35 import com.eviware.soapui.model.iface.Attachment;
36 import com.eviware.soapui.model.propertyexpansion.DefaultPropertyExpansionContext;
37 import com.eviware.soapui.settings.WsdlSettings;
38 import com.eviware.soapui.support.Tools;
39 import com.eviware.soapui.support.types.StringToStringMap;
40 import com.eviware.soapui.support.xml.XmlUtils;
41
42 public class WsdlMonitorMessageExchange extends WsdlMessageExchange
43 {
44 private URL targetUrl;
45 private StringToStringMap responseHeaders;
46 private long timeTaken;
47 private long timestamp;
48 private StringToStringMap requestHeaders;
49 private String requestContent;
50 private String responseContent;
51 private int responseContentLength;
52 private int requestContentLength;
53 private String requestHost;
54 private WsdlProject project;
55 private WsdlOperation operation;
56 private byte[] capturedRequestData;
57 private byte[] capturedResponseData;
58 private String responseContentType;
59 private MultipartMessageSupport responseMmSupport;
60
61 private static final String HTTP_ELEMENT_CHARSET = "US-ASCII";
62 private SoapVersion soapVersion;
63 private MultipartMessageSupport requestMmSupport;
64 private String requestContentType;
65 private boolean discarded;
66 private Vector requestWssResult;
67 private Vector responseWssResult;
68
69 public WsdlMonitorMessageExchange( WsdlProject project )
70 {
71 this.project = project;
72 responseHeaders = new StringToStringMap();
73 requestHeaders = new StringToStringMap();
74 timestamp = System.currentTimeMillis();
75 }
76
77 @Override
78 public WsdlOperation getOperation()
79 {
80 return operation;
81 }
82
83 public Attachment[] getRequestAttachments()
84 {
85 return requestMmSupport == null ? new Attachment[0] : requestMmSupport.getAttachments();
86 }
87
88 public String getRequestContent()
89 {
90 return requestMmSupport == null ? requestContent : requestMmSupport.getContentAsString();
91 }
92
93 public StringToStringMap getRequestHeaders()
94 {
95 return requestHeaders;
96 }
97
98 public Attachment[] getResponseAttachments()
99 {
100 return responseMmSupport == null ? new Attachment[0] : responseMmSupport.getAttachments();
101 }
102
103 public String getResponseContent()
104 {
105 return responseMmSupport == null ? responseContent : responseMmSupport.getContentAsString();
106 }
107
108 public StringToStringMap getResponseHeaders()
109 {
110 return responseHeaders;
111 }
112
113 public long getTimeTaken()
114 {
115 return timeTaken;
116 }
117
118 public long getTimestamp()
119 {
120 return timestamp;
121 }
122
123 public void setTargetUrl( URL targetHost )
124 {
125 this.targetUrl = targetHost;
126 }
127
128 public boolean isActive()
129 {
130 return false;
131 }
132
133 public long getRequestContentLength()
134 {
135 return requestContentLength;
136 }
137
138 public long getResponseContentLength()
139 {
140 return responseContentLength;
141 }
142
143 public String getRequestHost()
144 {
145 return requestHost;
146 }
147
148 public URL getTargetUrl()
149 {
150 return targetUrl;
151 }
152
153 public byte[] getRawRequestData()
154 {
155 return capturedRequestData;
156 }
157
158 public byte[] getRawResponseData()
159 {
160 return capturedResponseData;
161 }
162
163 @Override
164 public boolean hasRawData()
165 {
166 return true;
167 }
168
169 public void finish( byte[] capturedRequestData, byte[] capturedResponseData )
170 {
171 this.capturedRequestData = capturedRequestData;
172 this.capturedResponseData = capturedResponseData;
173
174 if( timeTaken == 0 )
175 timeTaken = System.currentTimeMillis() - timestamp;
176 }
177
178 public void prepare( IncomingWss requestWss, IncomingWss responseWss )
179 {
180 parseRequestData( capturedRequestData, requestWss );
181 parseReponseData( capturedResponseData, responseWss );
182 }
183
184 private void parseReponseData( byte[] capturedResponseData, IncomingWss responseWss )
185 {
186 responseContentLength = capturedResponseData.length;
187 ByteArrayInputStream in = new ByteArrayInputStream( capturedResponseData );
188 try
189 {
190
191 String line = null;
192 do
193 {
194 line = HttpParser.readLine( in, HTTP_ELEMENT_CHARSET );
195 }
196 while( line != null && line.length() == 0 );
197
198 if( line == null )
199 {
200 throw new Exception( "Missing request status line" );
201 }
202
203 Header[] headers = HttpParser.parseHeaders( in, HTTP_ELEMENT_CHARSET );
204 if( headers != null )
205 {
206 for( Header header : headers )
207 {
208 responseHeaders.put( header.getName(), header.getValue() );
209 }
210 }
211
212 responseContentType = responseHeaders.get( "Content-Type" );
213 if( responseContentType != null && responseContentType.toUpperCase().startsWith( "MULTIPART" ))
214 {
215 StringToStringMap values = StringToStringMap.fromHttpHeader( responseContentType );
216 responseMmSupport = new MultipartMessageSupport(
217 new MonitorMessageExchangeDataSource( "monitor response", in, responseContentType ), values.get( "start" ), null, true,
218 SoapUI.getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES ));
219 responseContentType = responseMmSupport.getRootPart().getContentType();
220 }
221 else
222 {
223 this.responseContent = XmlUtils.prettyPrintXml( Tools.readAll( in, 0 ).toString());
224 }
225
226 processResponseWss( responseWss );
227 }
228 catch( Exception e )
229 {
230 try
231 {
232 in.close();
233 }
234 catch( IOException e1 )
235 {
236 e1.printStackTrace();
237 }
238 }
239 }
240
241 private void processResponseWss( IncomingWss responseWss ) throws IOException
242 {
243 if( responseWss != null )
244 {
245 Document dom = XmlUtils.parseXml( responseContent );
246 try
247 {
248 responseWssResult = responseWss.processIncoming( dom, new DefaultPropertyExpansionContext(project ) );
249 if( responseWssResult != null && responseWssResult.size() > 0 )
250 {
251 StringWriter writer = new StringWriter();
252 XmlUtils.serialize( dom, writer );
253 responseContent = writer.toString();
254 }
255 }
256 catch( Exception e )
257 {
258 if( responseWssResult == null )
259 responseWssResult = new Vector();
260 responseWssResult.add( e );
261 }
262 }
263 }
264
265 private void parseRequestData( byte[] capturedRequestData, IncomingWss requestWss )
266 {
267 requestContentLength = capturedRequestData.length;
268 ByteArrayInputStream in = new ByteArrayInputStream( capturedRequestData );
269 try
270 {
271
272 String line = null;
273 do
274 {
275 line = HttpParser.readLine( in, HTTP_ELEMENT_CHARSET );
276 }
277 while( line != null && line.length() == 0 );
278
279 if( line == null )
280 {
281 throw new Exception( "Missing request status line" );
282 }
283
284 Header[] headers = HttpParser.parseHeaders( in, HTTP_ELEMENT_CHARSET );
285 if( headers != null )
286 {
287 for( Header header : headers )
288 {
289 requestHeaders.put( header.getName(), header.getValue() );
290 }
291 }
292
293 requestContentType = requestHeaders.get( "Content-Type" );
294 if( requestContentType != null && requestContentType.toUpperCase().startsWith( "MULTIPART" ))
295 {
296 StringToStringMap values = StringToStringMap.fromHttpHeader( requestContentType );
297 requestMmSupport = new MultipartMessageSupport(
298 new MonitorMessageExchangeDataSource( "monitor request", in, requestContentType ), values.get( "start" ), null, true,
299 SoapUI.getSettings().getBoolean( WsdlSettings.PRETTY_PRINT_RESPONSE_MESSAGES ));
300 requestContentType = requestMmSupport.getRootPart().getContentType();
301 }
302 else
303 {
304 this.requestContent = XmlUtils.prettyPrintXml( Tools.readAll( in, 0 ).toString() );
305 }
306
307 processRequestWss( requestWss );
308
309 operation = findOperation();
310 }
311 catch( Exception e )
312 {
313 try
314 {
315 in.close();
316 }
317 catch( IOException e1 )
318 {
319 e1.printStackTrace();
320 }
321 }
322 }
323
324 private void processRequestWss( IncomingWss requestWss ) throws IOException
325 {
326 if( requestWss != null )
327 {
328 Document dom = XmlUtils.parseXml( requestContent );
329 try
330 {
331 requestWssResult = requestWss.processIncoming( dom, new DefaultPropertyExpansionContext(project ) );
332 if( requestWssResult != null && requestWssResult.size() > 0 )
333 {
334 StringWriter writer = new StringWriter();
335 XmlUtils.serialize( dom, writer );
336 requestContent = writer.toString();
337 }
338 }
339 catch( Exception e )
340 {
341 if( requestWssResult == null )
342 requestWssResult = new Vector();
343 requestWssResult.add( e );
344 }
345 }
346 }
347
348 private WsdlOperation findOperation() throws Exception
349 {
350 soapVersion = SoapUtils.initSoapVersion( requestContentType );
351 if( soapVersion == null )
352 throw new Exception( "Unrecognized SOAP Version" );
353
354 String soapAction = SoapUtils.getSoapAction( soapVersion, requestHeaders );
355
356 return SoapUtils.findOperationForRequest( soapVersion, soapAction,
357 XmlObject.Factory.parse( getRequestContent() ), project.getInterfaceList(), true, false );
358 }
359
360 public void setRequestHost( String requestHost )
361 {
362 this.requestHost = requestHost;
363 }
364
365 public SoapVersion getSoapVersion()
366 {
367 if( soapVersion == null )
368 soapVersion = SoapUtils.initSoapVersion( requestHeaders.get( "Content-Type" ) );
369
370 return soapVersion;
371 }
372
373 public void setTimeTaken( long timeTaken )
374 {
375 this.timeTaken = timeTaken;
376 }
377
378 public void discard()
379 {
380 operation = null;
381 project = null;
382
383 requestContent = null;
384 requestHeaders = null;
385
386 responseContent = null;
387 responseHeaders = null;
388
389 requestMmSupport = null;
390
391 discarded = true;
392 }
393
394 public ModelItem getModelItem()
395 {
396 return null;
397 }
398
399 public boolean isDiscarded()
400 {
401 return discarded;
402 }
403
404 public Vector getRequestWssResult()
405 {
406 return requestWssResult;
407 }
408
409 public Vector getResponseWssResult()
410 {
411 return responseWssResult;
412 }
413 }