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