1
2
3
4
5
6
7
8
9
10
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
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
129
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 }