View Javadoc

1   // ========================================================================
2   // Copyright 2004-2010 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses.
12  // ========================================================================
13  
14  package org.eclipse.jetty.server.session;
15  
16  import java.io.File;
17  import java.io.FileInputStream;
18  import java.io.FileOutputStream;
19  import java.io.FileWriter;
20  import java.util.Random;
21  
22  import javax.servlet.http.HttpServletResponse;
23  
24  import org.eclipse.jetty.client.ContentExchange;
25  import org.eclipse.jetty.client.HttpClient;
26  import org.eclipse.jetty.http.HttpMethods;
27  import org.eclipse.jetty.util.IO;
28  import org.eclipse.jetty.util.resource.Resource;
29  import org.junit.Test;
30  import static org.junit.Assert.assertEquals;
31  import static org.junit.Assert.assertTrue;
32  
33  /**
34   * AbstractWebAppObjectInSessionTest
35   * 
36   * Target of this test is to check that when a webapp on nodeA puts in the session
37   * an object of a class loaded from the war (and hence with a WebAppClassLoader),
38   * the same webapp on nodeB is able to load that object from the session.
39   * 
40   * This test is only appropriate for clustered session managers.
41   */
42  public abstract class AbstractWebAppObjectInSessionTest
43  {
44      public abstract AbstractTestServer createServer(int port);
45  
46  
47      private void copy(File source, File target) throws Exception
48      {
49          FileInputStream input = new FileInputStream(source);
50          FileOutputStream output = new FileOutputStream(target);
51          int read = -1;
52          byte[] bytes = new byte[64];
53          while ((read = input.read(bytes)) >= 0) output.write(bytes, 0, read);
54          input.close();
55          output.close();
56      }
57      
58      @Test
59      public void testWebappObjectInSession() throws Exception
60      {
61          String contextName = "webappObjectInSessionTest";
62          String contextPath = "/" + contextName;
63          String servletMapping = "/server";
64  
65          File targetDir = new File(System.getProperty("basedir"), "target");
66          File warDir = new File(targetDir, contextName);
67          warDir.mkdir();
68          File webInfDir = new File(warDir, "WEB-INF");
69          webInfDir.mkdir();
70          // Write web.xml
71          File webXml = new File(webInfDir, "web.xml");
72          String xml =
73                  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
74                  "<web-app xmlns=\"http://java.sun.com/xml/ns/j2ee\"\n" +
75                  "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
76                  "         xsi:schemaLocation=\"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd\"\n" +
77                  "         version=\"2.4\">\n" +
78                  "\n" +
79                  "</web-app>";
80          FileWriter w = new FileWriter(webXml);
81          w.write(xml);
82          w.close();
83          File classesDir = new File(webInfDir, "classes");
84          classesDir.mkdir();
85          String packageName = WebAppObjectInSessionServlet.class.getPackage().getName();
86          File packageDirs = new File(classesDir, packageName.replace('.', File.separatorChar));
87          packageDirs.mkdirs();
88          String resourceName = WebAppObjectInSessionServlet.class.getName().replace('.', File.separatorChar) + ".class";
89          
90          
91          Resource res = Resource.newResource(getClass().getClassLoader().getResource(resourceName));
92         
93          //File sourceFile = new File(getClass().getClassLoader().getResource(resourceName).toURI());       
94          File targetFile = new File(packageDirs, resourceName.substring(packageName.length()));
95          //copy(sourceFile, targetFile);
96          resourceName = WebAppObjectInSessionServlet.TestSharedNonStatic.class.getName().replace('.', File.separatorChar) + ".class";
97          IO.copy(res.getInputStream(), new FileOutputStream(targetFile));
98       
99          
100         resourceName = WebAppObjectInSessionServlet.TestSharedStatic.class.getName().replace('.', File.separatorChar) + ".class";
101         res = Resource.newResource(getClass().getClassLoader().getResource(resourceName));
102         //sourceFile = new File(getClass().getClassLoader().getResource(resourceName).toURI());
103         targetFile = new File(packageDirs, resourceName.substring(packageName.length()));
104         //copy(sourceFile, targetFile);
105         IO.copy(res.getInputStream(), new FileOutputStream(targetFile));
106         Random random = new Random(System.nanoTime());
107 
108         int port1 = random.nextInt(50000) + 10000;
109         AbstractTestServer server1 = createServer(port1);
110         server1.addWebAppContext(warDir.getCanonicalPath(), contextPath).addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping);
111         server1.start();
112         try
113         {
114             int port2 = random.nextInt(50000) + 10000;
115             AbstractTestServer server2 = createServer(port2);
116             server2.addWebAppContext(warDir.getCanonicalPath(), contextPath).addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping);
117             server2.start();
118             try
119             {
120                 HttpClient client = new HttpClient();
121                 client.setConnectorType(HttpClient.CONNECTOR_SOCKET);
122                 client.start();
123                 try
124                 {
125                     // Perform one request to server1 to create a session
126                     ContentExchange exchange1 = new ContentExchange(true);
127                     exchange1.setMethod(HttpMethods.GET);
128                     exchange1.setURL("http://localhost:" + port1 + contextPath + servletMapping + "?action=set");
129                     client.send(exchange1);
130                     exchange1.waitForDone();
131                     assertEquals( HttpServletResponse.SC_OK, exchange1.getResponseStatus());
132                     String sessionCookie = exchange1.getResponseFields().getStringField("Set-Cookie");
133                     assertTrue(sessionCookie != null);
134                     // Mangle the cookie, replacing Path with $Path, etc.
135                     sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
136 
137                     // Perform a request to server2 using the session cookie from the previous request
138                     ContentExchange exchange2 = new ContentExchange(true);
139                     exchange2.setMethod(HttpMethods.GET);
140                     exchange2.setURL("http://localhost:" + port2 + contextPath + servletMapping + "?action=get");
141                     exchange2.getRequestFields().add("Cookie", sessionCookie);
142                     client.send(exchange2);
143                     exchange2.waitForDone();
144                     
145                     assertEquals(HttpServletResponse.SC_OK,exchange2.getResponseStatus());
146                 }
147                 finally
148                 {
149                     client.stop();
150                 }
151             }
152             finally
153             {
154                 server2.stop();
155             }
156         }
157         finally
158         {
159             server1.stop();
160         }
161     }
162 }