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