View Javadoc

1   /*
2    *  soapui, copyright (C) 2005 Ole Matzura / eviware.com 
3    *
4    *  SoapUI is free software; you can redistribute it and/or modify it under the 
5    *  terms of the GNU Lesser General Public License as published by the Free Software Foundation; 
6    *  either version 2.1 of the License, or (at your option) any later version.
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;
14  
15  import java.io.IOException;
16  
17  import org.apache.commons.httpclient.Credentials;
18  import org.apache.commons.httpclient.HostConfiguration;
19  import org.apache.commons.httpclient.HttpClient;
20  import org.apache.commons.httpclient.HttpState;
21  import org.apache.commons.httpclient.NTCredentials;
22  import org.apache.commons.httpclient.UsernamePasswordCredentials;
23  import org.apache.commons.httpclient.auth.AuthScheme;
24  import org.apache.commons.httpclient.auth.CredentialsNotAvailableException;
25  import org.apache.commons.httpclient.auth.CredentialsProvider;
26  import org.apache.commons.httpclient.auth.NTLMScheme;
27  import org.apache.commons.httpclient.auth.RFC2617Scheme;
28  import org.apache.commons.httpclient.methods.ByteArrayRequestEntity;
29  import org.apache.commons.httpclient.methods.PostMethod;
30  import org.apache.log4j.Logger;
31  
32  import com.eviware.soapui.impl.wsdl.support.HttpClientSupport;
33  import com.eviware.soapui.model.iface.Request;
34  import com.eviware.soapui.model.iface.Response;
35  import com.eviware.soapui.model.iface.Submit;
36  import com.eviware.soapui.model.iface.SubmitListener;
37  
38  /***
39   * Submit implementation for submitting a WsdlRequest
40   * 
41   * @author Ole.Matzura
42   */
43  
44  public class WsdlSubmit implements Runnable, Submit
45  {
46     private final static Logger logger = Logger.getLogger( WsdlSubmit.class ); 
47     private final WsdlRequest wsdlRequest;
48     private PostMethod postMethod;
49  	private SubmitListener[] listeners;
50  	private String responseContent;
51  	private Status status;
52  	private Exception error;
53  	private WsdlResponse response = new WsdlResponse();
54  	private long timeTaken;
55  	private Thread thread;
56  
57     public WsdlSubmit( WsdlRequest wsdlRequest, SubmitListener [] listeners )
58     {
59        this.wsdlRequest = wsdlRequest;
60  		this.listeners = listeners;
61  		
62  		status = Status.CREATED;
63     }
64     
65     public void submitRequest()
66     {
67  		thread = new Thread( this );
68  		thread.start();
69     }
70  
71     public void cancel()
72     {
73     	if( status == Status.CANCELED ) return;
74        status = Status.CANCELED;
75        
76        logger.info( "Canceling request.." );
77        if( postMethod.isRequestSent() )
78        {
79           postMethod.abort();
80        }
81  
82        status = Status.CANCELED;
83        
84        for (int i = 0; i < listeners.length; i++) {
85  			listeners[i].afterSubmit( this );
86  		}
87     }
88  
89     public void run()
90     {
91        try
92        {
93        	for (int i = 0; i < listeners.length; i++) {
94     			if( !listeners[i].beforeSubmit( this )) return;
95     		}
96  
97        	status = Status.RUNNING;
98        	
99           WsdlInterface wsdlInterface = (WsdlInterface) wsdlRequest.getOperation().getInterface();
100          String strURL = wsdlInterface.getEndpointURL( wsdlRequest.getEndpoint() );
101 
102          postMethod = new PostMethod( strURL );
103          postMethod.getParams().setParameter( CredentialsProvider.PROVIDER, new SoapUICredentialsProvider());
104          postMethod.setDoAuthentication( true );
105          
106          // create new client since we dont want caching of authentications
107          HttpClient httpclient = HttpClientSupport.getHttpClient();
108          String encoding = wsdlRequest.getEncoding();
109          if( encoding != null && encoding.trim().length() == 0) 
110             encoding = null;
111          if( encoding == null  )
112             postMethod.setRequestHeader( "Content-type", "text/xml" );
113          else
114             postMethod.setRequestHeader( "Content-type", "text/xml;charset=" + encoding );
115          
116          String soapAction = wsdlRequest.getOperation().getAction();
117          if( soapAction == null || soapAction.length() == 0 )
118          {	
119          	soapAction = "\"\"";
120          }
121          else
122          {
123          	soapAction = "\"" + soapAction + "\"";
124          }
125          
126          postMethod.setRequestHeader( "SOAPAction", soapAction );
127 
128          // Request content will be retrieved directly
129          // from the input stream
130          String request = wsdlRequest.getRequestContent();
131          if( request == null ) request = "";
132 
133          byte [] content = encoding == null ? request.getBytes() : request.getBytes( encoding );
134          postMethod.setRequestEntity( new ByteArrayRequestEntity( content ));
135          
136          long now = System.currentTimeMillis();
137          httpclient.executeMethod( new HostConfiguration(), postMethod, new HttpState() );
138          timeTaken = System.currentTimeMillis() - now;
139 			if( status != Status.CANCELED )
140 			{         
141 	         byte[] responseBody = postMethod.getResponseBody();
142 	         responseContent = encoding == null ? new String( responseBody ) : 
143 				            new String( responseBody, encoding );
144 	         
145 	         status = Status.FINISHED;
146 			}
147       }
148       catch( Exception e1 )
149       {
150       	error = e1;
151       	status = Status.ERROR;
152       }
153       finally
154       {
155       	if( postMethod != null )
156       	{
157       		postMethod.releaseConnection();
158       	}
159 
160          if( status != Status.CANCELED )
161          {
162             for (int i = 0; i < listeners.length; i++) {
163       			listeners[i].afterSubmit( this );
164       		}
165          }
166       }
167    }
168 
169 	public Request getRequest() 
170 	{
171 		return wsdlRequest;
172 	}
173 
174 	public String getResponseContent() {
175 		return responseContent;
176 	}
177 
178 	public Status getStatus() {
179 		return status;
180 	}
181 
182 	public Exception getError() {
183 		return error;
184 	}
185 	
186 	private class WsdlResponse implements Response
187 	{
188 		public String getContentAsString() {
189 			try 
190 			{
191 				return postMethod.getResponseBodyAsString();
192 			} 
193 			catch (IOException e) 
194 			{
195 				e.printStackTrace();
196 				return null;
197 			}
198 		}
199 
200 		public long getContentLength() 
201 		{
202 			try {
203 				long length = postMethod.getResponseContentLength();
204 				if (length == -1)
205 					length = postMethod.getResponseBody().length;
206 
207 				return length;
208 			} catch (Exception e) 
209 			{
210 				e.printStackTrace();
211 				return getContentAsString().length();
212 			}
213 		}
214 
215 		public Request getRequest()
216 		{
217 			return wsdlRequest;
218 		}
219 		
220 	}
221 
222 	public Response getResponse( boolean wait )
223 	{
224 		if( wait && (status == Status.RUNNING || status == Status.CREATED) )
225 		{
226 			synchronized (thread)
227 			{
228 				try
229 				{
230 					thread.wait();
231 				}
232 				catch (InterruptedException e)
233 				{
234 					e.printStackTrace();
235 				}
236 			}
237 		}
238 		
239 		return response;
240 	}
241 
242 	public long getTimeTaken() {
243 		return timeTaken;
244 	}
245 	
246 	public class SoapUICredentialsProvider implements CredentialsProvider {
247 
248       public Credentials getCredentials(
249           final AuthScheme authscheme, 
250           final String host, 
251           int port, 
252           boolean proxy)
253           throws CredentialsNotAvailableException 
254       {
255           if (authscheme == null) {
256               return null;
257           }
258           try{
259               if (authscheme instanceof NTLMScheme) {
260                   logger.info(host + ":" + port + " requires Windows authentication");
261                   return new NTCredentials(wsdlRequest.getUsername(), 
262                   		wsdlRequest.getPassword(), host, wsdlRequest.getDomain());    
263               } else
264               if (authscheme instanceof RFC2617Scheme) {
265             	  logger.info(host + ":" + port + " requires authentication with the realm '" 
266                       + authscheme.getRealm() + "'");
267                   return new UsernamePasswordCredentials(wsdlRequest.getUsername(), 
268                   		wsdlRequest.getPassword());    
269               } else {
270                   throw new CredentialsNotAvailableException("Unsupported authentication scheme: " +
271                       authscheme.getSchemeName());
272               }
273           } catch (IOException e) {
274               throw new CredentialsNotAvailableException(e.getMessage(), e);
275           }
276       }
277   }
278 }