KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > inversoft > junit > internal > HttpCaller


1 /*
2  * Copyright (c) 2003, Inversoft
3  *
4  * This software is distribuable under the GNU Lesser General Public License.
5  * For more information visit gnu.org.
6  */

7 package com.inversoft.junit.internal;
8
9
10 import java.io.IOException JavaDoc;
11 import java.net.MalformedURLException JavaDoc;
12 import java.util.Enumeration JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.List JavaDoc;
15 import java.util.Map JavaDoc;
16 import javax.servlet.http.Cookie JavaDoc;
17
18 import org.apache.commons.httpclient.Header;
19 import org.apache.commons.httpclient.HostConfiguration;
20 import org.apache.commons.httpclient.HttpClient;
21 import org.apache.commons.httpclient.HttpState;
22 import org.apache.commons.httpclient.cookie.CookiePolicy;
23 import org.apache.commons.httpclient.cookie.CookieSpec;
24 import org.apache.commons.httpclient.methods.PostMethod;
25 import org.apache.log4j.Logger;
26 import org.jdom.Document;
27 import org.jdom.JDOMException;
28 import org.jdom.input.SAXBuilder;
29
30 import com.inversoft.junit.Configuration;
31 import com.inversoft.junit.Request;
32 import com.inversoft.junit.Response;
33 import com.inversoft.junit.Result;
34 import com.inversoft.junit.URL;
35 import com.inversoft.junit.WebTestCase;
36
37
38 /**
39  * This class is an adapter from the Client interface to
40  * Apache's HTTP Client's UrlPostMethod class.
41  *
42  * @author Brian Pontarelli
43  * @since 1.0
44  * @version 1.0
45  */

46 public class HttpCaller {
47
48     /**
49      * This classes logger
50      */

51     private static final Logger logger = Logger.getLogger(HttpCaller.class);
52
53     /**
54      * The HTTP Client's HttpClient
55      */

56     private static HttpClient client;
57
58     /**
59      * The persisting boolean
60      */

61     private static boolean persisting;
62
63     /**
64      * The cookie headers
65      */

66     public static final String JavaDoc SET_COOKIE = "Set-Cookie";
67     public static final String JavaDoc SET_COOKIE2 = "Set-Cookie2";
68
69
70     // If persisting session across tests, setup the static variables
71
static {
72         persisting = Configuration.isPersistingSession();
73
74         if (persisting) {
75
76             // First fetch the URL from the configuration
77
String JavaDoc urlStr = Configuration.getTestLocation(WebTestCase.class);
78             java.net.URL JavaDoc url = createURL(urlStr);
79
80             HostConfiguration hc = new HostConfiguration();
81             hc.setHost(url.getHost(), url.getPort());
82
83             client = new HttpClient();
84             client.setHostConfiguration(hc);
85         }
86     }
87
88     /**
89      * Sets up the URL
90      */

91     private static java.net.URL JavaDoc createURL(String JavaDoc urlStr) {
92         try {
93             return new java.net.URL JavaDoc(urlStr);
94         } catch (MalformedURLException JavaDoc mue) {
95             logger.error("The test location URL '" + urlStr + "' is invalid", mue);
96
97             throw new IllegalArgumentException JavaDoc("The test location URL '" +
98                 urlStr + "' is invalid");
99         }
100     }
101
102
103     /**
104      * Constructs an instance of the HttpCaller
105      */

106     public HttpCaller() {
107         // EMPTY
108
}
109
110
111     /**
112      * This method uses the given request, which must be an instance of the
113      * DefaultHttpRequest object, to run the test on the server using an
114      * HTTP request to the servet. The HTTP Client does not use request
115      * objects and therefore this one is used.<br>
116      * <br>
117      * The Request can be a sub-class of the DefaultHttpRequest object but
118      * this class must then be sub-classes to make use of it.
119      *
120      * @param testCase The WebTestCase to use when setting the class name
121      * and test method parameters into the HTTP request
122      * @param request The request that should be used when executing the
123      * test.
124      * @return A response object that contains the response of running the
125      * test
126      * @throws Throwable If there was anything thrown from the test location side
127      */

128     public Response runTest(WebTestCase testCase, Request request) throws Throwable JavaDoc {
129         String JavaDoc testLocation = request.getTestLocation();
130
131         // If not overridden, get the default from the configuration file
132
if (testLocation == null) {
133             testLocation = Configuration.getTestLocation(testCase.getClass());
134         }
135
136         java.net.URL JavaDoc url = createURL(testLocation);
137         PostMethod method = new PostMethod(url.getPath());
138         HttpState state = new HttpState();
139
140         executeTestRequest(testCase, request, method, state, url);
141
142         // Get the result to see if there was an exception and if so, throw it
143
Result result = executeResultRequest(request, url);
144
145         if (!result.isSuccessful()) {
146             throw result.getThrowable();
147         }
148
149         Map JavaDoc cookies = fetchCookies(request, method, url);
150         return new Response(request, method.getStatusCode(),
151             method.getResponseBodyAsString(), null,
152             method.getResponseBodyAsStream(), cookies);
153     }
154
155     /**
156      * This method executes the communication with the server for the test request
157      */

158     protected void executeTestRequest(WebTestCase testCase, Request request,
159             PostMethod method, HttpState state, java.net.URL JavaDoc url) {
160         HttpClient localClient;
161
162         if (persisting) {
163             localClient = client;
164         } else {
165             HostConfiguration hc = new HostConfiguration();
166             hc.setHost(url.getHost(), url.getPort());
167
168             localClient = new HttpClient();
169             localClient.setHostConfiguration(hc);
170         }
171
172         // Setup the headers
173
String JavaDoc[] headers = request.getHeaderNames();
174         for (int i = 0; i < headers.length; i++) {
175             method.addRequestHeader(headers[i], request.getHeader(headers[i]));
176         }
177
178         // Setup the cookies
179
Cookie JavaDoc[] cookies = request.getCookies();
180         org.apache.commons.httpclient.Cookie cookie;
181         for (int i = 0; i < cookies.length; i++) {
182             cookie = new org.apache.commons.httpclient.Cookie(
183                 cookies[i].getDomain(), cookies[i].getName(), cookies[i].getValue(),
184                 cookies[i].getPath(), cookies[i].getMaxAge(), cookies[i].getSecure());
185             state.addCookie(cookie);
186         }
187
188         // Setup the parameters
189
setupParameters(request, method);
190
191         // Add the test request type parameter
192
method.addParameter(Constants.URL_REQUEST_TYPE_PARAM, Constants.REQUEST_TYPE_TEST);
193         method.addParameter(Constants.URL_CLASS_PARAM, testCase.getClass().getName());
194         method.addParameter(Constants.URL_METHOD_PARAM, testCase.getName());
195
196         // Execute the HTTP request and get out the response
197
try {
198             localClient.setState(state);
199             localClient.executeMethod(method);
200         } catch (Exception JavaDoc e) {
201             logger.error("Error executing the test HTTP request", e);
202             throw new RuntimeException JavaDoc("Error executing the test HTTP request: " + e.toString());
203         }
204
205         int responseCode = method.getStatusCode();
206         if (responseCode != 200 && responseCode != 202) {
207             logger.error("Server side error: " + responseCode);
208             throw new RuntimeException JavaDoc("Server side error: " + responseCode);
209         }
210     }
211
212     /**
213      * This method executes the communcation with the server for the result request and returns
214      * the result from the server
215      */

216     protected Result executeResultRequest(Request request, java.net.URL JavaDoc url) {
217         HttpClient localClient = new HttpClient();
218         PostMethod method = new PostMethod(url.getPath());
219         HttpState state = new HttpState();
220
221         HostConfiguration hc = new HostConfiguration();
222         hc.setHost(url.getHost(), url.getPort());
223
224         localClient.setHostConfiguration(hc);
225         localClient.setState(state);
226
227         // Setup the parameters
228
setupParameters(request, method);
229
230         // Add the request parameter for the result request
231
method.addParameter(Constants.URL_REQUEST_TYPE_PARAM, Constants.REQUEST_TYPE_RESULT);
232
233         try {
234             localClient.executeMethod(method);
235         } catch (Exception JavaDoc e) {
236             // TO DO - Make exception throwing better
237
logger.error("Error executing the result HTTP request", e);
238             throw new RuntimeException JavaDoc("Error executing the result HTTP request", e);
239         }
240
241         // Get the result XML and parse
242
try {
243             int responseCode = method.getStatusCode();
244             if (responseCode != 200 && responseCode != 202) {
245                 logger.error("Server side error: " + responseCode);
246                 throw new RuntimeException JavaDoc("Server side error: " + responseCode);
247             }
248
249             SAXBuilder builder = new SAXBuilder();
250             Document document = builder.build(method.getResponseBodyAsStream());
251             Result result = new Result();
252
253             result.fromXML(document);
254
255             return result;
256         } catch (JDOMException je) {
257             logger.error("Error parsing result XML", je);
258             throw new RuntimeException JavaDoc("Error parsing result XML", je);
259         } catch (IOException JavaDoc ioe) {
260             logger.error("Error parsing result XML", ioe);
261             throw new RuntimeException JavaDoc("Error parsing result XML", ioe);
262         }
263     }
264
265     /**
266      * Sets the parameters form the Request into the Method.
267      *
268      * @param request The Request to fetch the parameters from.
269      * @param method The method to set the parameters into.
270      */

271     protected void setupParameters(Request request, PostMethod method) {
272         Enumeration JavaDoc keys = request.getParameterNames();
273         while (keys.hasMoreElements()) {
274             String JavaDoc key = (String JavaDoc) keys.nextElement();
275             String JavaDoc[] values = request.getParameterValues(key);
276             for (int i = 0; i < values.length; i++) {
277                 method.addParameter(key, values[i]);
278             }
279         }
280     }
281
282     /**
283      * Using the method, this gets all the cookies from the response headers and
284      * stores them in a Map.
285      */

286     protected Map JavaDoc fetchCookies(Request request, PostMethod method, java.net.URL JavaDoc jurl) {
287         // Loop through the headers and setup the cookies
288
Map JavaDoc cookies = new HashMap JavaDoc();
289         Header[] headers = method.getResponseHeaders();
290         URL url = request.getURL();
291         String JavaDoc name;
292         String JavaDoc domain;
293         String JavaDoc path;
294         int port;
295
296         // Determine the domain, port and path of the request (or spoofed request
297
// URL from the request interface)
298
if (url == null) {
299             domain = jurl.getHost();
300             path = jurl.getPath();
301             port = jurl.getPort();
302         } else {
303             domain = (url.getServerName() != null) ? url.getServerName() :
304                 jurl.getHost();
305             port = (url.getServerPort() != -1) ? url.getServerPort() :
306                 jurl.getPort();
307
308             String JavaDoc servletPath = url.getServletPath();
309             String JavaDoc context = (url.getContextPath() != null) ? url.getContextPath() :
310                 "";
311             String JavaDoc pathInfo = (url.getPathInfo() != null) ? url.getPathInfo() :
312                 "";
313
314             if (servletPath == null) {
315                 path = jurl.getPath();
316             } else {
317                 StringBuffer JavaDoc buf = new StringBuffer JavaDoc();
318                 buf.append(context).append(servletPath).append(pathInfo);
319                 path = buf.toString();
320             }
321         }
322
323         // Loop through all the headers and grab the cookies out
324
CookieSpec spec = CookiePolicy.getCompatibilitySpec();
325         for (int i = 0; i < headers.length; i++) {
326
327             name = headers[i].getName();
328             if (name != null &&
329                     (name.equalsIgnoreCase(SET_COOKIE) ||
330                      name.equalsIgnoreCase(SET_COOKIE2))) {
331
332                 try {
333
334                     org.apache.commons.httpclient.Cookie[] cArray =
335                         spec.parse(domain, port, path, false, headers[i]);
336
337                     for (int j = 0; j < cArray.length; j++) {
338                         Cookie JavaDoc cookie = new Cookie JavaDoc(cArray[j].getName(), cArray[j].getValue());
339                         cookie.setComment(cArray[j].getComment());
340                         cookie.setDomain(cArray[j].getDomain());
341
342                         // Carefully setup the expiration of the cookie
343
if (cArray[j].getExpiryDate() == null) {
344                             cookie.setMaxAge(-1);
345                         } else {
346                             cookie.setMaxAge(
347                                 (int) cArray[j].getExpiryDate().getTime() -
348                                 (int) System.currentTimeMillis());
349                         }
350
351                         cookie.setPath(cArray[j].getPath());
352                         cookie.setSecure(cArray[j].getSecure());
353                         cookie.setVersion(cArray[j].getVersion());
354                         cookies.put(cookie.getName(), cookie);
355                     }
356
357                 // Catch the httpclient HTTPException
358
} catch (Exception JavaDoc e) {
359                     throw new RuntimeException JavaDoc("Error parsing cookies", e);
360                 }
361             }
362         }
363
364         return cookies;
365     }
366 }
Popular Tags