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  package org.eclipse.jetty.server.session;
14  
15  import java.io.IOException;
16  import java.util.Random;
17  
18  import javax.servlet.ServletException;
19  import javax.servlet.http.HttpServlet;
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  import javax.servlet.http.HttpSession;
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.server.Request;
28  import org.eclipse.jetty.server.SessionManager;
29  import org.junit.Test;
30  import static org.junit.Assert.assertEquals;
31  import static org.junit.Assert.assertTrue;
32  
33  /**
34   * AbstractLocalSessionScavengingTest
35   */
36  public abstract class AbstractLocalSessionScavengingTest
37  {
38      public abstract AbstractTestServer createServer(int port, int max, int scavenge);
39  
40      public void pause(int scavengePeriod)
41      {
42          try
43          {
44              Thread.sleep(scavengePeriod * 2500L);
45          }
46          catch (InterruptedException e)
47          {
48              e.printStackTrace();
49          }
50      }
51      
52      @Test
53      public void testLocalSessionsScavenging() throws Exception
54      {
55          Random random = new Random(System.nanoTime());
56          String contextPath = "";
57          String servletMapping = "/server";
58          int port1 = random.nextInt(50000) + 10000;
59          int inactivePeriod = 1;
60          int scavengePeriod = 2;
61          AbstractTestServer server1 = createServer(port1, inactivePeriod, scavengePeriod);
62          server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
63          server1.start();
64          try
65          {
66              int port2 = random.nextInt(50000) + 10000;
67              AbstractTestServer server2 = createServer(port2, inactivePeriod, scavengePeriod * 3);
68              server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
69              server2.start();
70              try
71              {
72                  HttpClient client = new HttpClient();
73                  client.setConnectorType(HttpClient.CONNECTOR_SOCKET);
74                  client.start();
75                  try
76                  {
77                      String[] urls = new String[2];
78                      urls[0] = "http://localhost:" + port1 + contextPath + servletMapping;
79                      urls[1] = "http://localhost:" + port2 + contextPath + servletMapping;
80  
81                      // Create the session on node1
82                      ContentExchange exchange1 = new ContentExchange(true);
83                      exchange1.setMethod(HttpMethods.GET);
84                      exchange1.setURL(urls[0] + "?action=init");
85                      client.send(exchange1);
86                      exchange1.waitForDone();
87                      assertEquals(HttpServletResponse.SC_OK,exchange1.getResponseStatus());
88                      String sessionCookie = exchange1.getResponseFields().getStringField("Set-Cookie");
89                      assertTrue(sessionCookie != null);
90                      // Mangle the cookie, replacing Path with $Path, etc.
91                      sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
92  
93                      // Be sure the session is also present in node2
94                      ContentExchange exchange2 = new ContentExchange(true);
95                      exchange2.setMethod(HttpMethods.GET);
96                      exchange2.setURL(urls[1] + "?action=test");
97                      exchange2.getRequestFields().add("Cookie", sessionCookie);
98                      client.send(exchange2);
99                      exchange2.waitForDone();
100                     assertEquals(HttpServletResponse.SC_OK,exchange2.getResponseStatus());
101                     
102                     
103                     // Wait for the scavenger to run on node1, waiting 2.5 times the scavenger period
104                     pause(scavengePeriod);
105                     
106                     // Check that node1 does not have any local session cached
107                     exchange1 = new ContentExchange(true);
108                     exchange1.setMethod(HttpMethods.GET);
109                     exchange1.setURL(urls[0] + "?action=check");
110                     client.send(exchange1);
111                     exchange1.waitForDone();
112                     assertEquals(HttpServletResponse.SC_OK,exchange1.getResponseStatus());
113 
114 
115                     // Wait for the scavenger to run on node2, waiting 2 times the scavenger period
116                     // This ensures that the scavenger on node2 runs at least once.
117                     pause(scavengePeriod);
118 
119                     // Check that node2 does not have any local session cached   
120                     exchange2 = new ContentExchange(true);
121                     exchange2.setMethod(HttpMethods.GET);
122                     exchange2.setURL(urls[1] + "?action=check");
123                     client.send(exchange2);
124                     exchange2.waitForDone();
125                     assertEquals(HttpServletResponse.SC_OK,exchange2.getResponseStatus());
126                 }
127                 finally
128                 {
129                     client.stop();
130                 }
131             }
132             finally
133             {
134                 server2.stop();
135             }
136         }
137         finally
138         {
139             server1.stop();
140         }
141     }
142 
143     public static class TestServlet extends HttpServlet
144     {
145         private SessionManager sessionManager;
146 
147         @Override
148         protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
149         {
150             String action = request.getParameter("action");
151             if ("init".equals(action))
152             {
153                 HttpSession session = request.getSession(true);
154                 session.setAttribute("test", "test");
155                 this.sessionManager = ((Request)request).getSessionManager();
156             }
157             else if ("test".equals(action))
158             {
159                 HttpSession session = request.getSession(false);
160                 session.setAttribute("test", "test");
161                 this.sessionManager = ((Request)request).getSessionManager();
162             }
163             else if ("check".equals(action))
164             {
165                 HttpSession session = request.getSession(false);
166                 assertTrue(session == null);
167             }
168         }
169     }
170 }