View Javadoc

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