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