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