View Javadoc

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