001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.test.cluster.httpsessionreplication;
023:
024: import java.io.BufferedReader;
025: import java.io.IOException;
026: import java.io.InputStreamReader;
027: import java.net.URL;
028: import java.net.URLConnection;
029: import java.util.Properties;
030:
031: import junit.framework.Test;
032:
033: import org.apache.commons.httpclient.HttpClient;
034: import org.apache.commons.httpclient.HttpMethod;
035: import org.apache.commons.httpclient.HttpRecoverableException;
036: import org.apache.commons.httpclient.methods.GetMethod;
037: import org.jboss.test.JBossClusteredTestCase;
038:
039: /**
040: *
041: * @see org.jboss.test.cluster.httpsessionreplication
042: *
043: * @author <a href="mailto:anil.saldhana@jboss.com">Anil Saldhana</a>.
044: * @version $Revision: 1.0
045: */
046: public class HttpSessionReplicationUnitTestCase extends
047: JBossClusteredTestCase {
048: /**
049: * The Servernames should be configurable.
050: */
051: private String[] servernames = {
052: "jnp://" + getServerHost() + ":1099",
053: "jnp://" + getServerHost() + ":1199" };
054:
055: /**
056: * The main properties file that should be under src/resources/cluster
057: */
058: private Properties prop = null;
059:
060: /**
061: * Denotes number of nodes in the cluster test
062: */
063: private int numInstances = 0;
064:
065: public HttpSessionReplicationUnitTestCase(String name) {
066: super (name);
067: try {
068: this .getPropertiesFile();
069: String numin = prop.getProperty("NumOfInstances");
070: numInstances = Integer.parseInt(numin);
071: if (numInstances < 2)
072: fail("Atleast two nodes needed");
073:
074: //Lets build up the jndi server urls now
075: this .setServerNames(servernames);
076: } catch (Exception e) {
077: fail(e.getMessage());
078: }
079: }
080:
081: public static Test suite() throws Exception {
082: //The following jar deployment is a dummy.
083: Test t1 = JBossClusteredTestCase.getDeploySetup(
084: HttpSessionReplicationUnitTestCase.class,
085: "httpsessionreplication.jar");
086: return t1;
087: }
088:
089: /**
090: * Tests connection to the Apache Server.
091: * Note: We deal with just one Apache Server. We can bounce the different
092: * JBoss/Tomcat servers and Apache will loadbalance.
093: * @throws Exception
094: */
095: public void testApacheConnection() throws Exception {
096: getLog().debug("Enter testApacheConnection");
097: try {
098: // makeConnection( "http://localhost");
099: this .makeConnection(prop.getProperty("ApacheUrl"));
100: } catch (Exception e) {
101: }
102: getLog().debug("Exit testApacheConnection");
103: }
104:
105: /**
106: * Main method that deals with the Http Session Replication Test
107: * @throws Exception
108: */
109: public void testHttpSessionReplication() throws Exception {
110: String attr = "";
111: getLog().debug("Enter testHttpSessionReplication");
112: //First need to make a Http Connection to Apache and get the session id
113: //Then bring down the first instance and make another call
114: //Then check the session id or just see if the server has not returned an error
115: //String urlname = "http://localhost/testsessionreplication.jsp";
116: //String geturlname = "http://localhost/getattribute.jsp";
117:
118: String urlname = prop.getProperty("SetAttrUrl");
119: String geturlname = prop.getProperty("GetAttrUrl");
120: /*
121: makeConnection(urlname);
122: getHttpText( urlname );
123:
124: //Get the Attribute set by testsessionreplication.jsp
125: attr= getAttribute( geturlname );
126: //Shut down the first instance
127: shutDownInstance( "localhost:1099");
128: //Give 30 seconds for things to stabilize.
129: sleepThread(30*1000);//30 seconds
130: if( !getAttribute(geturlname).equals(attr)) fail("Http Session Replication Failed");
131: getLog().debug("Http Session Replication has happened");
132: getLog().debug("Exit testHttpSessionReplication");
133: */
134:
135: // Create an instance of HttpClient.
136: HttpClient client = new HttpClient();
137:
138: // Create a method instance.
139: HttpMethod method = new GetMethod(urlname);
140: String str = makeGet(client, method);
141:
142: //Make a second connection
143: method = new GetMethod(geturlname);
144:
145: // Get the Attribute set by testsessionreplication.jsp
146: attr = makeGet(client, method);
147: // Shut down the first instance
148: //shutDownInstance( "localhost:1099");
149: shutDownInstance(1);
150: getLog().debug("Brought down the first instance");
151: // Give 30 seconds for things to stabilize.
152: sleepThread(30 * 1000);//30 seconds
153:
154: // Make connection
155: method = new GetMethod(geturlname);
156: String attr2 = makeGet(client, method);
157: if (!attr2.equals(attr))
158: fail("Http Session Replication Failed");
159: getLog().debug("Http Session Replication has happened");
160: getLog().debug("Exit testHttpSessionReplication");
161: }
162:
163: /**
164: * Reads in the properties file
165: */
166: public void getPropertiesFile() {
167: prop = new Properties();
168: try {
169: java.net.URL url = ClassLoader
170: .getSystemResource("cluster/cluster-test.properties");
171: prop.load(url.openStream());
172: } catch (Exception e) {
173: fail("Need a properties file under src/resources/cluster:"
174: + e.getMessage());
175: }
176: }
177:
178: /**
179: * Shuts down an instance of JBoss.
180: * @throws Exception
181: */
182: private void shutDownInstance(int instancenum) throws Exception {
183: String command = getCommand(instancenum);
184:
185: getLog().debug("Going to execute:" + command);
186: Process child = Runtime.getRuntime().exec(command);
187: sleepThread(10 * 1000);
188: getLog().debug("Process exit value=" + child.exitValue());
189: }
190:
191: /**
192: * Generate the command to run to shutdown a jboss node
193: * @param instancenum
194: * @return
195: */
196: private String getCommand(int instancenum) {
197: //String base="/Users/anil/jboss-head/build/output/jboss-4.0.0DR4";
198: //String cpath = base+"/bin/shutdown.jar:"+base+"/client/jbossall-client.jar";
199: //String command = "java -server -Xms128m -Xmx128m -classpath "+" org.jboss.Shutdown -s "+jndiurl;
200: //String command = base+"/bin/shutdown.sh -s "+jndiurl;
201: String command = "";
202: try {
203: command = prop.getProperty("jboss.location")
204: + prop.getProperty("ShutDownScript");
205: command += " -s "
206: + "jnp://"
207: + prop.getProperty("Instance" + instancenum
208: + ".host")
209: + ":"
210: + prop.getProperty("Instance" + instancenum
211: + ".port.jndi");
212: } catch (Exception e) {
213: fail("getCommand Failed with:" + e.getMessage());
214: }
215:
216: return command;
217: }
218:
219: /**
220: * Sleep for specified time
221: * @param millisecs
222: * @throws Exception
223: */
224: private void sleepThread(long millisecs) throws Exception {
225: Thread.sleep(millisecs);
226: }
227:
228: /**
229: * Makes a HTTP Connection
230: * @param urlname
231: * @throws Exception
232: */
233: private void makeConnection(String urlname) throws Exception {
234: getLog().debug("Enter makeConnection");
235: try {
236: // Step 1: Create URLConnection for URL
237: URL url = new URL(urlname);
238: URLConnection conn = url.openConnection();
239:
240: // List all the response headers from the server.
241: for (int i = 0;; i++) {
242: String hname = conn.getHeaderFieldKey(i);
243: String hvalue = conn.getHeaderField(i);
244:
245: getLog().debug(
246: "hname=" + hname + "::" + "value=" + hvalue);
247: if (hname == null && hvalue == null) {
248: // No more headers
249: break;
250: }
251: if (hname == null) {
252: getLog().debug("Response from Apache=" + hvalue);
253: // The header value contains the server's HTTP version
254: if (hvalue.indexOf("200") < 0
255: && hvalue.indexOf("301") < 0
256: && hvalue.indexOf("302") < 0)
257: fail(urlname + " Down");
258: break;
259: }
260: }
261: } catch (Exception e) {
262: getLog().debug(e);
263: }
264: }
265:
266: /**
267: * This method gets the response from the HTTP Server provided an URl
268: * @param urlname
269: */
270: private void getHttpText(String urlname) {
271: getLog().debug(getAttribute(urlname));
272: }//end method
273:
274: /**
275: * Returns the attribute set on the session
276: * Refer to getattribute.jsp
277: * @param urlname
278: * @return
279: */
280: private String getAttribute(String urlname) {
281: BufferedReader in = null;
282: StringBuffer sb = new StringBuffer();
283: try {
284: URL url = new URL(urlname);
285:
286: //Read all the text returned by the server
287: in = new BufferedReader(new InputStreamReader(url
288: .openStream()));
289: String str;
290: while ((str = in.readLine()) != null) {
291: // str is one line of text; readLine() strips the newline character(s)
292: sb.append(str);
293: }
294: getLog().debug(sb.toString());
295: } catch (Exception e) {
296: getLog().debug(e);
297: } finally {
298: try {
299: in.close();
300: } catch (Exception y) {
301: }
302: }
303: return sb.toString();
304: }
305:
306: /**
307: * Makes a http call to the jsp that retrieves the attribute stored on the
308: * session. When the attribute values mathes with the one retrieved earlier,
309: * we have HttpSessionReplication.
310: * Makes use of commons-httpclient library of Apache
311: * @param client
312: * @param method
313: * @return session attribute
314: * @throws IOException
315: */
316: private String makeGet(HttpClient client, HttpMethod method)
317: throws IOException {
318: // Execute the method.
319: int statusCode = -1;
320:
321: try {
322: // execute the method.
323: statusCode = client.executeMethod(method);
324: } catch (HttpRecoverableException e) {
325: System.err
326: .println("A recoverable exception occurred, retrying."
327: + e.getMessage());
328: } catch (IOException e) {
329: System.err.println("Failed to download file.");
330: e.printStackTrace();
331: System.exit(-1);
332: }
333:
334: // Read the response body.
335: byte[] responseBody = method.getResponseBody();
336:
337: // Release the connection.
338: method.releaseConnection();
339:
340: // Deal with the response.
341: // Use caution: ensure correct character encoding and is not binary data
342: return new String(responseBody);
343: }
344:
345: /*
346: * Override the method and do nothing. It fails when we run this testcase
347: * because we have brought down instances.
348: * @see org.jboss.test.JBossTestCase#testServerFound()
349: */
350: public void testServerFound() throws Exception {
351: }
352:
353: }
|