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  
31  /**
32   * AbstractWebAppObjectInSessionTest
33   * 
34   * Target of this test is to check that when a webapp on nodeA puts in the session
35   * an object of a class loaded from the war (and hence with a WebAppClassLoader),
36   * the same webapp on nodeB is able to load that object from the session.
37   * 
38   * This test is only appropriate for clustered session managers.
39   */
40  public abstract class AbstractWebAppObjectInSessionTest
41  {
42      public abstract AbstractTestServer createServer(int port);
43  
44  
45      private void copy(File source, File target) throws Exception
46      {
47          FileInputStream input = new FileInputStream(source);
48          FileOutputStream output = new FileOutputStream(target);
49          int read = -1;
50          byte[] bytes = new byte[64];
51          while ((read = input.read(bytes)) >= 0) output.write(bytes, 0, read);
52          input.close();
53          output.close();
54      }
55      
56      @Test
57      public void testWebappObjectInSession() throws Exception
58      {
59          String contextName = "webappObjectInSessionTest";
60          String contextPath = "/" + contextName;
61          String servletMapping = "/server";
62  
63          File targetDir = new File(System.getProperty("basedir"), "target");
64          File warDir = new File(targetDir, contextName);
65          warDir.mkdir();
66          File webInfDir = new File(warDir, "WEB-INF");
67          webInfDir.mkdir();
68          // Write web.xml
69          File webXml = new File(webInfDir, "web.xml");
70          String xml =
71                  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" +
72                  "<web-app xmlns=\"http://java.sun.com/xml/ns/j2ee\"\n" +
73                  "         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n" +
74                  "         xsi:schemaLocation=\"http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd\"\n" +
75                  "         version=\"2.4\">\n" +
76                  "\n" +
77                  "</web-app>";
78          FileWriter w = new FileWriter(webXml);
79          w.write(xml);
80          w.close();
81          File classesDir = new File(webInfDir, "classes");
82          classesDir.mkdir();
83          String packageName = WebAppObjectInSessionServlet.class.getPackage().getName();
84          File packageDirs = new File(classesDir, packageName.replace('.', File.separatorChar));
85          packageDirs.mkdirs();
86          String resourceName = WebAppObjectInSessionServlet.class.getName().replace('.', File.separatorChar) + ".class";
87          
88          
89          Resource res = Resource.newResource(getClass().getClassLoader().getResource(resourceName));
90         
91          //File sourceFile = new File(getClass().getClassLoader().getResource(resourceName).toURI());       
92          File targetFile = new File(packageDirs, resourceName.substring(packageName.length()));
93          //copy(sourceFile, targetFile);
94          resourceName = WebAppObjectInSessionServlet.TestSharedNonStatic.class.getName().replace('.', File.separatorChar) + ".class";
95          IO.copy(res.getInputStream(), new FileOutputStream(targetFile));
96       
97          
98          resourceName = WebAppObjectInSessionServlet.TestSharedStatic.class.getName().replace('.', File.separatorChar) + ".class";
99          res = Resource.newResource(getClass().getClassLoader().getResource(resourceName));
100         //sourceFile = new File(getClass().getClassLoader().getResource(resourceName).toURI());
101         targetFile = new File(packageDirs, resourceName.substring(packageName.length()));
102         //copy(sourceFile, targetFile);
103         IO.copy(res.getInputStream(), new FileOutputStream(targetFile));
104         Random random = new Random(System.nanoTime());
105 
106         int port1 = random.nextInt(50000) + 10000;
107         AbstractTestServer server1 = createServer(port1);
108         server1.addWebAppContext(warDir.getCanonicalPath(), contextPath).addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping);
109         server1.start();
110         try
111         {
112             int port2 = random.nextInt(50000) + 10000;
113             AbstractTestServer server2 = createServer(port2);
114             server2.addWebAppContext(warDir.getCanonicalPath(), contextPath).addServlet(WebAppObjectInSessionServlet.class.getName(), servletMapping);
115             server2.start();
116             try
117             {
118                 HttpClient client = new HttpClient();
119                 client.setConnectorType(HttpClient.CONNECTOR_SOCKET);
120                 client.start();
121                 try
122                 {
123                     // Perform one request to server1 to create a session
124                     ContentExchange exchange1 = new ContentExchange(true);
125                     exchange1.setMethod(HttpMethods.GET);
126                     exchange1.setURL("http://localhost:" + port1 + contextPath + servletMapping + "?action=set");
127                     client.send(exchange1);
128                     exchange1.waitForDone();
129                     assert exchange1.getResponseStatus() == HttpServletResponse.SC_OK : exchange1.getResponseStatus();
130                     String sessionCookie = exchange1.getResponseFields().getStringField("Set-Cookie");
131                     assert sessionCookie != null;
132                     // Mangle the cookie, replacing Path with $Path, etc.
133                     sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
134 
135                     // Perform a request to server2 using the session cookie from the previous request
136                     ContentExchange exchange2 = new ContentExchange(true);
137                     exchange2.setMethod(HttpMethods.GET);
138                     exchange2.setURL("http://localhost:" + port2 + contextPath + servletMapping + "?action=get");
139                     exchange2.getRequestFields().add("Cookie", sessionCookie);
140                     client.send(exchange2);
141                     exchange2.waitForDone();
142                     assert exchange2.getResponseStatus() == HttpServletResponse.SC_OK;
143                 }
144                 finally
145                 {
146                     client.stop();
147                 }
148             }
149             finally
150             {
151                 server2.stop();
152             }
153         }
154         finally
155         {
156             server1.stop();
157         }
158     }
159 }