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