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