/* * JBoss, Home of Professional Open Source. * Copyright 2008, Red Hat Middleware LLC, and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. */ package org.jboss.test.cluster.httpsessionreplication; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.URL; import java.net.URLConnection; import java.util.Properties; import junit.framework.Test; import org.apache.commons.httpclient.HttpClient; import org.apache.commons.httpclient.HttpMethod; import org.apache.commons.httpclient.HttpRecoverableException; import org.apache.commons.httpclient.methods.GetMethod; import org.jboss.test.JBossClusteredTestCase; /** * * @see org.jboss.test.cluster.httpsessionreplication * * @author <a href="mailto:anil.saldhana@jboss.com">Anil Saldhana</a>. * @version $Revision: 1.0 */ public class HttpSessionReplicationUnitTestCase extends JBossClusteredTestCase { /** * The Servernames should be configurable. */ private String[] servernames= {"jnp://localhost:1099", "jnp://localhost:1199"}; /** * The main properties file that should be under src/resources/cluster */ private Properties prop = null; /** * Denotes number of nodes in the cluster test */ private int numInstances = 0; public HttpSessionReplicationUnitTestCase (String name) { super(name); try{ this.getPropertiesFile(); String numin = prop.getProperty("NumOfInstances"); numInstances = Integer.parseInt( numin ); if( numInstances < 2 ) fail( "Atleast two nodes needed"); //Lets build up the jndi server urls now this.setServerNames(servernames); }catch( Exception e){ fail( e.getMessage()); } } public static Test suite() throws Exception { //The following jar deployment is a dummy. Test t1 = JBossClusteredTestCase.getDeploySetup(HttpSessionReplicationUnitTestCase.class, "httpsessionreplication.jar"); return t1; } /** * Tests connection to the Apache Server. * Note: We deal with just one Apache Server. We can bounce the different * JBoss/Tomcat servers and Apache will loadbalance. * @throws Exception */ public void testApacheConnection() throws Exception { getLog().debug("Enter testApacheConnection"); try { // makeConnection( "http://localhost"); this.makeConnection(prop.getProperty("ApacheUrl")); } catch (Exception e) { } getLog().debug("Exit testApacheConnection"); } /** * Main method that deals with the Http Session Replication Test * @throws Exception */ public void testHttpSessionReplication() throws Exception { String attr = ""; getLog().debug("Enter testHttpSessionReplication"); //First need to make a Http Connection to Apache and get the session id //Then bring down the first instance and make another call //Then check the session id or just see if the server has not returned an error //String urlname = "http://localhost/testsessionreplication.jsp"; //String geturlname = "http://localhost/getattribute.jsp"; String urlname = prop.getProperty("SetAttrUrl"); String geturlname = prop.getProperty("GetAttrUrl"); /* makeConnection(urlname); getHttpText( urlname ); //Get the Attribute set by testsessionreplication.jsp attr= getAttribute( geturlname ); //Shut down the first instance shutDownInstance( "localhost:1099"); //Give 30 seconds for things to stabilize. sleepThread(30*1000);//30 seconds if( !getAttribute(geturlname).equals(attr)) fail("Http Session Replication Failed"); getLog().debug("Http Session Replication has happened"); getLog().debug("Exit testHttpSessionReplication"); */ // Create an instance of HttpClient. HttpClient client = new HttpClient(); // Create a method instance. HttpMethod method = new GetMethod(urlname); String str = makeGet( client, method ); //Make a second connection method = new GetMethod(geturlname); // Get the Attribute set by testsessionreplication.jsp attr= makeGet( client,method ); // Shut down the first instance //shutDownInstance( "localhost:1099"); shutDownInstance( 1 ); getLog().debug( "Brought down the first instance"); // Give 30 seconds for things to stabilize. sleepThread(30*1000);//30 seconds // Make connection method = new GetMethod(geturlname); String attr2= makeGet( client, method ); if( ! attr2.equals(attr)) fail("Http Session Replication Failed"); getLog().debug("Http Session Replication has happened"); getLog().debug("Exit testHttpSessionReplication"); } /** * Reads in the properties file */ public void getPropertiesFile(){ prop = new Properties(); try{ java.net.URL url = ClassLoader.getSystemResource("cluster/cluster-test.properties"); prop.load( url.openStream()); }catch( Exception e){ fail("Need a properties file under src/resources/cluster:"+e.getMessage()); } } /** * Shuts down an instance of JBoss. * @throws Exception */ private void shutDownInstance(int instancenum) throws Exception { String command = getCommand(instancenum); getLog().debug("Going to execute:"+command); Process child = Runtime.getRuntime().exec(command); sleepThread( 10*1000 ); getLog().debug("Process exit value="+child.exitValue()); } /** * Generate the command to run to shutdown a jboss node * @param instancenum * @return */ private String getCommand( int instancenum) { //String base="/Users/anil/jboss-head/build/output/jboss-4.0.0DR4"; //String cpath = base+"/bin/shutdown.jar:"+base+"/client/jbossall-client.jar"; //String command = "java -server -Xms128m -Xmx128m -classpath "+" org.jboss.Shutdown -s "+jndiurl; //String command = base+"/bin/shutdown.sh -s "+jndiurl; String command = ""; try{ command = prop.getProperty("jboss.location") + prop.getProperty("ShutDownScript"); command += " -s " + "jnp://"+prop.getProperty("Instance"+instancenum+".host")+":"+ prop.getProperty("Instance"+instancenum+".port.jndi"); }catch( Exception e){ fail( "getCommand Failed with:"+ e.getMessage()); } return command; } /** * Sleep for specified time * @param millisecs * @throws Exception */ private void sleepThread(long millisecs) throws Exception { Thread.sleep(millisecs); } /** * Makes a HTTP Connection * @param urlname * @throws Exception */ private void makeConnection( String urlname ) throws Exception { getLog().debug("Enter makeConnection"); try { // Step 1: Create URLConnection for URL URL url = new URL(urlname); URLConnection conn = url.openConnection(); // List all the response headers from the server. for (int i=0; ; i++) { String hname = conn.getHeaderFieldKey(i); String hvalue = conn.getHeaderField(i); getLog().debug("hname="+hname+"::"+"value="+hvalue); if (hname == null && hvalue == null) { // No more headers break; } if (hname == null) { getLog().debug("Response from Apache="+hvalue); // The header value contains the server's HTTP version if( hvalue.indexOf("200") < 0 && hvalue.indexOf("301") < 0 && hvalue.indexOf("302") < 0) fail(urlname+" Down"); break; } } } catch (Exception e) { getLog().debug(e); } } /** * This method gets the response from the HTTP Server provided an URl * @param urlname */ private void getHttpText( String urlname ){ getLog().debug( getAttribute(urlname)); }//end method /** * Returns the attribute set on the session * Refer to getattribute.jsp * @param urlname * @return */ private String getAttribute( String urlname){ BufferedReader in = null; StringBuffer sb = new StringBuffer(); try{ URL url = new URL(urlname); //Read all the text returned by the server in = new BufferedReader(new InputStreamReader(url.openStream())); String str; while ((str = in.readLine()) != null) { // str is one line of text; readLine() strips the newline character(s) sb.append(str); } getLog().debug(sb.toString()); }catch( Exception e){ getLog().debug( e); }finally{ try{ in.close(); }catch(Exception y){} } return sb.toString(); } /** * Makes a http call to the jsp that retrieves the attribute stored on the * session. When the attribute values mathes with the one retrieved earlier, * we have HttpSessionReplication. * Makes use of commons-httpclient library of Apache * @param client * @param method * @return session attribute * @throws IOException */ private String makeGet( HttpClient client, HttpMethod method) throws IOException{ // Execute the method. int statusCode = -1; try { // execute the method. statusCode = client.executeMethod(method); } catch (HttpRecoverableException e) { System.err.println( "A recoverable exception occurred, retrying." + e.getMessage()); } catch (IOException e) { System.err.println("Failed to download file."); e.printStackTrace(); System.exit(-1); } // Read the response body. byte[] responseBody = method.getResponseBody(); // Release the connection. method.releaseConnection(); // Deal with the response. // Use caution: ensure correct character encoding and is not binary data return new String(responseBody); } /* * Override the method and do nothing. It fails when we run this testcase * because we have brought down instances. * @see org.jboss.test.JBossTestCase#testServerFound() */ public void testServerFound() throws Exception { } }