You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ds...@apache.org on 2015/07/06 23:46:29 UTC
[08/20] incubator-geode git commit: GEODE-14: Imported modules from
geode-1.0.0-SNAPSHOT-2.src.tar
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/IntegrationTest.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/IntegrationTest.java b/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/IntegrationTest.java
new file mode 100644
index 0000000..50b6425
--- /dev/null
+++ b/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/IntegrationTest.java
@@ -0,0 +1,1552 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.gemstone.gemfire.modules.session.filter;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.EnumSet;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.concurrent.TimeUnit;
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.junit.PerTestClassLoaderRunner;
+import org.apache.jasper.servlet.JspServlet;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.eclipse.jetty.servlet.FilterHolder;
+import org.eclipse.jetty.servlet.ServletHolder;
+import org.eclipse.jetty.http.HttpTester;
+
+import static org.junit.Assert.*;
+
+/**
+ * In-container testing using Jetty. This allows us to test context listener
+ * events as well as dispatching actions.
+ */
+@RunWith(PerTestClassLoaderRunner.class)
+public class IntegrationTest {
+
+ private MyServletTester tester;
+
+ private HttpTester.Request request;
+
+ private HttpTester.Response response;
+
+ private ServletHolder servletHolder;
+
+ private FilterHolder filterHolder;
+
+ private static final File tmpdir;
+
+ private static final String gemfire_log;
+
+ static {
+ // Create a per-user scratch directory
+ tmpdir = new File(System.getProperty("java.io.tmpdir"),
+ "gemfire_modules-" + System.getProperty("user.name"));
+ tmpdir.mkdirs();
+ tmpdir.deleteOnExit();
+
+ gemfire_log = tmpdir.getPath() +
+ System.getProperty("file.separator") + "gemfire_modules.log";
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ request = HttpTester.newRequest();
+
+ tester = new MyServletTester();
+ tester.setContextPath("/test");
+
+ filterHolder = tester.addFilter(SessionCachingFilter.class, "/*",
+ EnumSet.of(DispatcherType.REQUEST));
+ filterHolder.setInitParameter("gemfire.property.mcast-port", "0");
+ filterHolder.setInitParameter("gemfire.property.writable-working-dir",
+ tmpdir.getPath());
+ filterHolder.setInitParameter("cache-type", "peer-to-peer");
+ filterHolder.setInitParameter("gemfire.property.log-file",
+ gemfire_log);
+
+ servletHolder = tester.addServlet(BasicServlet.class, "/hello");
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ /**
+ * This starts the servlet. Our wrapped servlets *must* start
+ * immediately otherwise the ServletContext is not captured correctly.
+ */
+ servletHolder.setInitOrder(0);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (tester.isStarted()) {
+ ContextManager.getInstance().removeContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+ }
+ tester.stop();
+ }
+
+ @Test
+ public void testSanity() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ PrintWriter out = response.getWriter();
+ out.write("Hello World");
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals(200, response.getStatus());
+ assertEquals("Hello World", response.getContent());
+ }
+
+ @Test
+ public void testSessionGenerated() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ PrintWriter out = response.getWriter();
+ out.write(request.getSession().getId());
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertTrue("Not a correctly generated session id",
+ response.getContent().endsWith("-GF"));
+
+ List<Cookie> cookies = getCookies(response);
+ assertEquals("Session id != JSESSIONID from cookie",
+ response.getContent(), cookies.get(0).getValue());
+
+ Region r = getRegion();
+ assertNotNull("Session not found in region",
+ r.get(cookies.get(0).getValue()));
+ }
+
+
+ /**
+ * Test that getSession(false) does not create a new session
+ */
+ @Test
+ public void testSessionNotGenerated() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ String output = "OK";
+ HttpSession s = request.getSession(false);
+ if (s != null) {
+ output = s.getId();
+ }
+ PrintWriter out = response.getWriter();
+ out.write(output);
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("Session should not have been created", "OK",
+ response.getContent());
+ }
+
+
+ @Test
+ public void testUnknownAttributeIsNull() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ Object o = request.getSession().getAttribute("unknown");
+ PrintWriter out = response.getWriter();
+ if (o == null) {
+ out.write("null");
+ } else {
+ out.write(o.toString());
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("Unknown attribute should be null", "null",
+ response.getContent());
+ }
+
+
+ @Test
+ public void testSessionRemains1() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ String output = "null";
+ HttpSession session = request.getSession();
+ if (session.isNew()) {
+ output = "new";
+ session.setAttribute("foo", output);
+ } else {
+ output = (String) session.getAttribute("foo");
+ if (output != null) {
+ output = "old";
+ }
+ }
+ PrintWriter out = response.getWriter();
+ out.write(output);
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("Session should be new", "new", response.getContent());
+
+ List<Cookie> cookies = getCookies(response);
+ request.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue());
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("Session should be old", "old", response.getContent());
+
+ List<Cookie> cookies2 = getCookies(response);
+ assertEquals("Session IDs should be the same", cookies.get(0).getValue(),
+ cookies2.get(0).getValue());
+
+ Region r = getRegion();
+ assertNotNull("Session object should exist in region",
+ r.get(cookies.get(0).getValue()));
+ }
+
+ /**
+ * Test that attributes are updated on the backend
+ */
+ @Test
+ public void testAttributesUpdatedInRegion() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ request.getSession().setAttribute("foo", "bar");
+ }
+ };
+
+ // This is the callback used to invalidate the session
+ Callback c_2 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ request.getSession().setAttribute("foo", "baz");
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+ tester.setAttribute("callback_2", c_2);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ ServletHolder sh2 = tester.addServlet(BasicServlet.class, "/request2");
+ sh2.setInitParameter("test.callback", "callback_2");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ List<Cookie> cookies = getCookies(response);
+
+ Region r = getRegion();
+ assertEquals("bar",
+ ((HttpSession) r.get(cookies.get(0).getValue())).getAttribute("foo"));
+
+ request.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue());
+ request.setURI("/test/request2");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("baz",
+ ((HttpSession) r.get(cookies.get(0).getValue())).getAttribute(
+ "foo"));
+ }
+
+ /**
+ * Test setting an attribute to null deletes it
+ */
+ @Test
+ public void testSetAttributeNullDeletesIt() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ request.getSession().setAttribute("foo", "bar");
+ }
+ };
+
+ // This is the callback used to invalidate the session
+ Callback c_2 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ request.getSession().setAttribute("foo", null);
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+ tester.setAttribute("callback_2", c_2);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ ServletHolder sh2 = tester.addServlet(BasicServlet.class, "/request2");
+ sh2.setInitParameter("test.callback", "callback_2");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ List<Cookie> cookies = getCookies(response);
+
+ Region r = getRegion();
+ assertEquals("bar",
+ ((HttpSession) r.get(cookies.get(0).getValue())).getAttribute(
+ "foo"));
+
+ request.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue());
+ request.setURI("/test/request2");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertNull(
+ ((HttpSession) r.get(cookies.get(0).getValue())).getAttribute(
+ "foo"));
+ }
+
+// Don't see how to do this currently as the SessionListener needs a full
+// web context to work in.
+
+// /**
+// * Test that sessions expire correctly
+// */
+// public void testSessionExpiration() throws Exception {
+// Callback c_1 = new Callback() {
+// @Override
+// public void call(HttpServletRequest request, HttpServletResponse response)
+// throws IOException, ServletException {
+// HttpSession s = request.getSession();
+// s.setAttribute("foo", "bar");
+// s.setMaxInactiveInterval(1);
+//
+// PrintWriter out = response.getWriter();
+// out.write(s.getId());
+// }
+// };
+//
+// // This is the callback used to check if the session is still there
+// Callback c_2 = new Callback() {
+// @Override
+// public void call(HttpServletRequest request, HttpServletResponse response)
+// throws IOException, ServletException {
+// HttpSession s = request.getSession(false);
+// String output;
+// if (s == null) {
+// output = "null";
+// } else {
+// output = s.getId();
+// }
+//
+// PrintWriter out = response.getWriter();
+// out.write(output);
+// }
+// };
+//
+// tester.addEventListener(new SessionListener());
+// tester.setAttribute("callback_1", c_1);
+// tester.setAttribute("callback_2", c_2);
+//
+// servletHolder.setInitParameter("test.callback", "callback_1");
+//
+// ServletHolder sh2 = tester.addServlet(BasicServlet.class, "/request2");
+// sh2.setInitParameter("test.callback", "callback_2");
+//
+// tester.start();
+// ContextManager.getInstance().putContext(
+// servletHolder.getServlet().getServletConfig().getServletContext());
+//
+// request.setMethod("GET");
+// request.setURI("/test/hello");
+// request.setHeader("Host", "tester");
+// request.setVersion("HTTP/1.0");
+// response.parse(tester.getResponses(request.generate()));
+//
+// String id = response.getContent();
+//
+// // Wait for the session to expire
+// Thread.sleep(2000);
+//
+// request.setHeader("Cookie", "JSESSIONID=" + id);
+// request.setURI("/test/request2");
+// response.parse(tester.getResponses(request.generate()));
+//
+// assertEquals("null", response.getContent());
+//
+// Region r = getRegion();
+// assertNull("Region should not contain session", r.get(id));
+// }
+
+ /**
+ * Test that invalidating a session destroys it as well as the backend
+ * object.
+ */
+ @Test
+ public void testInvalidateSession1() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ request.getSession().setAttribute("foo", "bar");
+ }
+ };
+
+ // This is the callback used to invalidate the session
+ Callback c_2 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ request.getSession(false).invalidate();
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+ tester.setAttribute("callback_2", c_2);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ ServletHolder sh2 = tester.addServlet(BasicServlet.class, "/request2");
+ sh2.setInitParameter("test.callback", "callback_2");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ List<Cookie> cookies = getCookies(response);
+ Region r = getRegion();
+ assertEquals("bar",
+ ((HttpSession) r.get(cookies.get(0).getValue())).getAttribute("foo"));
+
+ request.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue());
+ request.setURI("/test/request2");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertNull("Region should not contain session",
+ r.get(cookies.get(0).getValue()));
+ }
+
+ /**
+ * Test that invalidating a session throws an exception on subsequent access.
+ */
+ @Test
+ public void testInvalidateSession2() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ PrintWriter out = response.getWriter();
+ try {
+ s.getAttribute("foo");
+ } catch (IllegalStateException iex) {
+ out.write("OK");
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session throws an exception on subsequent access.
+ */
+ @Test
+ public void testInvalidateSession3() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ PrintWriter out = response.getWriter();
+ try {
+ s.getAttributeNames();
+ } catch (IllegalStateException iex) {
+ out.write("OK");
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session throws an exception on subsequent access.
+ */
+ @Test
+ public void testInvalidateSession4() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ PrintWriter out = response.getWriter();
+ try {
+ s.getCreationTime();
+ } catch (IllegalStateException iex) {
+ out.write("OK");
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session does not throw an exception for subsequent
+ * getId calls.
+ */
+ @Test
+ public void testInvalidateSession5() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ s.getId();
+ PrintWriter out = response.getWriter();
+ out.write("OK");
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session throws an exception on subsequent access.
+ */
+ @Test
+ public void testInvalidateSession6() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ PrintWriter out = response.getWriter();
+ try {
+ s.getLastAccessedTime();
+ } catch (IllegalStateException iex) {
+ out.write("OK");
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session does not throw an exception for
+ * subsequent getMaxInactiveInterval calls.
+ */
+
+// I've commented this out for now as Jetty seems to want to throw an
+// Exception here where the HttpServlet api doesn't specify that.
+ @Test
+ public void testInvalidateSession7() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request,
+ HttpServletResponse response) throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ s.getMaxInactiveInterval();
+ PrintWriter out = response.getWriter();
+ out.write("OK");
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session does not throw an exception for subsequent
+ * getServletContext calls.
+ */
+ @Test
+ public void testInvalidateSession8() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ s.getServletContext();
+ PrintWriter out = response.getWriter();
+ out.write("OK");
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session throws an exception on subsequent access.
+ */
+ @Test
+ public void testInvalidateSession9() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ PrintWriter out = response.getWriter();
+ try {
+ s.isNew();
+ } catch (IllegalStateException iex) {
+ out.write("OK");
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session throws an exception on subsequent access.
+ */
+ @Test
+ public void testInvalidateSession10() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ PrintWriter out = response.getWriter();
+ try {
+ s.removeAttribute("foo");
+ } catch (IllegalStateException iex) {
+ out.write("OK");
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session throws an exception on subsequent access.
+ */
+ @Test
+ public void testInvalidateSession11() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ PrintWriter out = response.getWriter();
+ try {
+ s.setAttribute("foo", "bar");
+ } catch (IllegalStateException iex) {
+ out.write("OK");
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session does not throw an exception for subsequent
+ * setMaxInactiveInterval calls.
+ */
+ @Test
+ public void testInvalidateSession12() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ s.setMaxInactiveInterval(1);
+ PrintWriter out = response.getWriter();
+ out.write("OK");
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+ /**
+ * Test that invalidating a session results in null being returned on
+ * subsequent getSession(false) calls.
+ */
+ @Test
+ public void testInvalidateSession13() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+ s = request.getSession(false);
+ PrintWriter out = response.getWriter();
+ if (s == null) {
+ out.write("OK");
+ } else {
+ out.write(s.toString());
+ }
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+
+ servletHolder.setInitParameter("test.callback", "callback_1");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("OK", response.getContent());
+ }
+
+
+ /**
+ * Test that we can invalidate and then recreate a new session
+ */
+ @Test
+ public void testInvalidateAndRecreateSession() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+
+ PrintWriter out = response.getWriter();
+ out.write(request.getSession().getId());
+ }
+ };
+
+ Callback c_2 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.invalidate();
+
+ PrintWriter out = response.getWriter();
+ out.write(request.getSession().getId());
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+ tester.setAttribute("callback_2", c_2);
+
+ ServletHolder sh = tester.addServlet(BasicServlet.class, "/dispatch");
+ sh.setInitParameter("test.callback", "callback_2");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ sh.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ String session1 = response.getContent();
+
+ request.setHeader("Cookie", "JSESSIONID=" + session1);
+ request.setURI("/test/request2");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ String session12 = response.getContent();
+ assertFalse("First and subsequent session ids must not be the same",
+ session1.equals(session12));
+ }
+
+
+ /**
+ * Test that creation time does not change on subsequent access
+ */
+ @Test
+ public void testGetCreationTime() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ HttpSession session = request.getSession();
+ PrintWriter out = response.getWriter();
+ out.write(Long.toString(session.getCreationTime()));
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ long time1 = Long.parseLong(response.getContent());
+ assertTrue("Creation time should be positive", time1 > 0);
+
+ List<Cookie> cookies = getCookies(response);
+ request.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue());
+
+ try {
+ Thread.sleep(1000);
+ } catch (Exception ex) {
+ }
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ long time2 = Long.parseLong(response.getContent());
+ assertTrue("Creation time should be the same across requests",
+ time1 == time2);
+ }
+
+ /**
+ * Test that the last accessed time is updated on subsequent access
+ */
+ @Test
+ public void testGetLastAccessedTime() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ HttpSession session = request.getSession();
+ PrintWriter out = response.getWriter();
+ out.write(Long.toString(session.getLastAccessedTime()));
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ long time1 = Long.parseLong(response.getContent());
+// assertTrue("Last accessed time should be positive", time1 > 0);
+
+ List<Cookie> cookies = getCookies(response);
+ request.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue());
+
+ Thread.sleep(1000);
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ long time2 = Long.parseLong(response.getContent());
+ assertTrue("Last accessed time should be increasing across requests",
+ time2 > time1);
+ }
+
+ /**
+ * Test that the underlying native session remains the same across requests
+ */
+ @Test
+ public void testNativeSessionRemainsUnchanged() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ GemfireHttpSession session = (GemfireHttpSession) request.getSession();
+ PrintWriter out = response.getWriter();
+ out.write(session.getNativeSession().getId());
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ String nativeSessionId = response.getContent();
+
+ List<Cookie> cookies = getCookies(response);
+ String sessionId = cookies.get(0).getValue();
+ Region r = getRegion();
+
+ assertEquals(
+ "Cached native session id does not match servlet returned native session id",
+ nativeSessionId,
+ ((GemfireHttpSession) r.get(sessionId)).getNativeSession().getId());
+
+ request.setHeader("Cookie", "JSESSIONID=" + cookies.get(0).getValue());
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals(
+ "Underlying native sessions must remain the same across requests",
+ nativeSessionId,
+ ((GemfireHttpSession) r.get(sessionId)).getNativeSession().getId());
+ }
+
+ /**
+ * Test session id embedded in the URL
+ */
+ @Test
+ public void testSessionIdEmbeddedInUrl() throws Exception {
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ GemfireHttpSession session = (GemfireHttpSession) request.getSession();
+ PrintWriter out = response.getWriter();
+ out.write(session.getId());
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ List<Cookie> cookies = getCookies(response);
+ String sessionId = response.getContent();
+ assertEquals("Session ids should be the same", sessionId,
+ cookies.get(0).getValue());
+
+ request.setURI("/test/hello;jsessionid=" + sessionId);
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ cookies = getCookies(response);
+
+ assertEquals("Session ids should be the same", sessionId,
+ cookies.get(0).getValue());
+ }
+
+
+ /**
+ * Test that request forward dispatching works
+ */
+ @Test
+ public void testDispatchingForward1() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ RequestDispatcher dispatcher = request.getRequestDispatcher("dispatch");
+ dispatcher.forward(request, response);
+
+ // This should not appear in the output
+ PrintWriter out = response.getWriter();
+ out.write("bang");
+ }
+ };
+
+ // This is the callback used by the forward servlet
+ Callback c_2 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ PrintWriter out = response.getWriter();
+ out.write("dispatched");
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+ tester.setAttribute("callback_2", c_2);
+
+ ServletHolder sh = tester.addServlet(BasicServlet.class, "/dispatch");
+ sh.setInitParameter("test.callback", "callback_2");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ sh.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ assertEquals("dispatched", response.getContent());
+
+ ContextManager.getInstance().removeContext(
+ sh.getServlet().getServletConfig().getServletContext());
+ }
+
+
+ /**
+ * Test that request include dispatching works
+ */
+ @Test
+ public void testDispatchingInclude() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ RequestDispatcher dispatcher = request.getRequestDispatcher("dispatch");
+ dispatcher.include(request, response);
+
+ // This *should* appear in the output
+ PrintWriter out = response.getWriter();
+ out.write("_bang");
+ }
+ };
+
+ // This is the callback used by the include servlet
+ Callback c_2 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ PrintWriter out = response.getWriter();
+ out.write("dispatched");
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+ tester.setAttribute("callback_2", c_2);
+
+ ServletHolder sh = tester.addServlet(BasicServlet.class, "/dispatch");
+ sh.setInitParameter("test.callback", "callback_2");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ sh.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ assertEquals("dispatched_bang", response.getContent());
+
+ ContextManager.getInstance().removeContext(
+ sh.getServlet().getServletConfig().getServletContext());
+ }
+
+
+ /**
+ * Test to try and simulate a failover scenario
+ */
+ @Test
+ public void testFailover1() throws Exception {
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+ s.setAttribute("foo", "bar");
+
+ PrintWriter out = response.getWriter();
+ out.write(request.getSession().getId());
+ }
+ };
+
+ Callback c_2 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ HttpSession s = request.getSession();
+
+ PrintWriter out = response.getWriter();
+ out.write((String) s.getAttribute("foo"));
+ }
+ };
+
+ tester.setAttribute("callback_1", c_1);
+ tester.setAttribute("callback_2", c_2);
+
+ ServletHolder sh = tester.addServlet(BasicServlet.class, "/request2");
+ sh.setInitParameter("test.callback", "callback_2");
+
+ tester.start();
+ ContextManager.getInstance().putContext(
+ sh.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+ String id = response.getContent();
+
+ // Now we simulate the failover by removing the native session from
+ // the stored session
+ Region r = getRegion();
+ GemfireHttpSession sessObj = (GemfireHttpSession) r.get(id);
+ sessObj.setNativeSession(null);
+
+ r.put(id, sessObj);
+
+ request.setHeader("Cookie", "JSESSIONID=" + id);
+ request.setURI("/test/request2");
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals("bar", response.getContent());
+ }
+
+ @Test
+ public void testHttpSessionListener1() throws Exception {
+ HttpSessionListenerImpl listener = new HttpSessionListenerImpl();
+ tester.getContext().getSessionHandler().addEventListener(listener);
+
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ HttpSession s = request.getSession();
+ // This is set in HttpSessionListenerImpl
+ String result = (String) s.getAttribute("gemfire-session-id");
+ response.getWriter().write(result);
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals(200, response.getStatus());
+
+ List<Cookie> cookies = getCookies(response);
+
+// AbstractListener listener = RendezvousManager.getListener();
+ tester.stop();
+
+ assertTrue("Timeout waiting for events",
+ listener.await(1, TimeUnit.SECONDS));
+ assertEquals(ListenerEventType.SESSION_CREATED,
+ listener.events.get(0));
+ assertEquals(ListenerEventType.SESSION_DESTROYED,
+ listener.events.get(1));
+ assertEquals(cookies.get(0).getValue(), response.getContent());
+ }
+
+ @Test
+ public void testHttpSessionListener2() throws Exception {
+ HttpSessionListenerImpl2 listener = new HttpSessionListenerImpl2();
+ tester.getContext().getSessionHandler().addEventListener(listener);
+
+ Callback c = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException {
+ HttpSession s = request.getSession();
+ s.setAttribute("test01", "test01");
+ s = request.getSession(false);
+ s.invalidate();
+ response.getWriter().write(s.getId());
+ }
+ };
+
+ tester.setAttribute("callback_1", c);
+ tester.start();
+ ContextManager.getInstance().putContext(
+ servletHolder.getServlet().getServletConfig().getServletContext());
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals(200, response.getStatus());
+
+ List<Cookie> cookies = getCookies(response);
+
+ tester.stop();
+
+ assertTrue("Timeout waiting for events",
+ listener.await(1, TimeUnit.SECONDS));
+ assertEquals(ListenerEventType.SESSION_CREATED,
+ listener.events.get(0));
+ assertEquals(ListenerEventType.SESSION_DESTROYED,
+ listener.events.get(1));
+ assertEquals(cookies.get(0).getValue(), response.getContent());
+ }
+
+
+
+
+// @Test
+ public void testJsp() throws Exception {
+ tester.setResourceBase("target/test-classes");
+ ServletHolder jspHolder = tester.addServlet(JspServlet.class, "/test/*");
+ jspHolder.setInitOrder(1);
+
+ jspHolder.setInitParameter("scratchdir", tmpdir.getPath());
+
+ Callback c_1 = new Callback() {
+ @Override
+ public void call(HttpServletRequest request, HttpServletResponse response)
+ throws IOException, ServletException {
+ request.getSession().setAttribute("foo", "bar");
+ request.setAttribute("foo", "baz");
+ RequestDispatcher dispatcher = request.getRequestDispatcher(
+ "pagecontext.jsp");
+ dispatcher.forward(request, response);
+ }
+ };
+
+ tester.getContext().setClassLoader(Thread.currentThread().getContextClassLoader());
+ tester.setAttribute("callback_1", c_1);
+
+ tester.start();
+
+ request.setMethod("GET");
+ request.setURI("/test/hello");
+ request.setHeader("Host", "tester");
+ request.setVersion("HTTP/1.0");
+
+ response = HttpTester.parseResponse(tester.getResponses(request.generate()));
+
+ assertEquals(200, response.getStatus());
+ assertEquals("baz", response.getContent().trim());
+ }
+
+
+ ////////////////////////////////////////////////////////////////////
+ // Private methods
+
+ /**
+ * Why doesn't HttpTester do this already??
+ */
+ private List<Cookie> getCookies(HttpTester.Response response) {
+ List<Cookie> cookies = new ArrayList<Cookie>();
+
+ Enumeration e = response.getValues("Set-Cookie");
+
+ while (e != null && e.hasMoreElements()) {
+ String header = (String) e.nextElement();
+ Cookie c = null;
+
+ StringTokenizer st = new StringTokenizer(header, ";");
+ while (st.hasMoreTokens()) {
+ String[] split = st.nextToken().split("=");
+ String param = split[0].trim();
+ String value = null;
+ if (split.length > 1) {
+ value = split[1].trim();
+ }
+ if ("version".equalsIgnoreCase(param)) {
+ c.setVersion(Integer.parseInt(value));
+ } else if ("comment".equalsIgnoreCase(param)) {
+ c.setComment(value);
+ } else if ("domain".equalsIgnoreCase(param)) {
+ c.setDomain(value);
+ } else if ("max-age".equalsIgnoreCase(param)) {
+ c.setMaxAge(Integer.parseInt(value));
+ } else if ("discard".equalsIgnoreCase(param)) {
+ c.setMaxAge(-1);
+ } else if ("path".equalsIgnoreCase(param)) {
+ c.setPath(value);
+ } else if ("secure".equalsIgnoreCase(param)) {
+ c.setSecure(true);
+ } else if ("httponly".equalsIgnoreCase(param)) {
+ // Ignored??
+ } else {
+ if (c == null) {
+ c = new Cookie(param, value);
+ } else {
+ throw new IllegalStateException("Unknown cookie param: " + param);
+ }
+ }
+ }
+
+ if (c != null) {
+ cookies.add(c);
+ }
+ }
+
+ return cookies;
+ }
+
+ private Region getRegion() {
+ // Yuck...
+ return ((GemfireSessionManager) ((SessionCachingFilter) filterHolder.getFilter()).getSessionManager()).getCache().getCache().getRegion(
+ "gemfire_modules_sessions");
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/MyServletTester.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/MyServletTester.java b/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/MyServletTester.java
new file mode 100644
index 0000000..43aed76
--- /dev/null
+++ b/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/MyServletTester.java
@@ -0,0 +1,33 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.gemstone.gemfire.modules.session.filter;
+
+import org.eclipse.jetty.servlet.ServletTester;
+
+/**
+ * Extend the base ServletTester class with a couple of helper methods. This
+ * depends on a patched ServletTester class which exposes the _server variable
+ * as package-private.
+ */
+public class MyServletTester extends ServletTester {
+
+ public boolean isStarted() {
+// return _server.isStarted();
+ return false;
+ }
+
+ public boolean isStopped() {
+// return _server.isStopped();
+ return false;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/ServletContextListenerImpl.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/ServletContextListenerImpl.java b/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/ServletContextListenerImpl.java
new file mode 100644
index 0000000..0eae4d5
--- /dev/null
+++ b/modules/gemfire-modules-session-integration-test/src/test/java/com/gemstone/gemfire/modules/session/filter/ServletContextListenerImpl.java
@@ -0,0 +1,48 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+
+package com.gemstone.gemfire.modules.session.filter;
+
+import com.gemstone.gemfire.modules.session.filter.ListenerEventType;
+
+import javax.servlet.ServletContextEvent;
+import javax.servlet.ServletContextListener;
+
+/**
+ * @author jdeppe
+ */
+public class ServletContextListenerImpl extends AbstractListener
+ implements ServletContextListener {
+
+ /**
+ * This is a 'custom' constructor which sets our latch count to 2. This is
+ * done because the earliest point, within our test code, where we can get a
+ * reference to the listener (in order to reset the latch count) an event
+ * *may* (more than likely) already have been fired.
+ */
+ public ServletContextListenerImpl() {
+ super(2);
+ }
+
+ @Override
+ public void contextInitialized(ServletContextEvent sce) {
+ events.add(ListenerEventType.SERVLET_CONTEXT_INITIALIZED);
+ latch.countDown();
+ }
+
+ @Override
+ public void contextDestroyed(ServletContextEvent sce) {
+ events.add(ListenerEventType.SERVLET_CONTEXT_DESTROYED);
+ latch.countDown();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session-integration-test/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-integration-test/src/test/resources/log4j.properties b/modules/gemfire-modules-session-integration-test/src/test/resources/log4j.properties
new file mode 100644
index 0000000..b346714
--- /dev/null
+++ b/modules/gemfire-modules-session-integration-test/src/test/resources/log4j.properties
@@ -0,0 +1,12 @@
+# To change this template, choose Tools | Templates
+# and open the template in the editor.
+
+# Set root logger level to DEBUG and its only appender to A1.
+log4j.rootLogger=DEBUG, A1
+
+# A1 is set to be a ConsoleAppender.
+log4j.appender.A1=org.apache.log4j.ConsoleAppender
+
+# A1 uses PatternLayout.
+log4j.appender.A1.layout=org.apache.log4j.PatternLayout
+log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session-integration-test/src/test/resources/pagecontext.jsp
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session-integration-test/src/test/resources/pagecontext.jsp b/modules/gemfire-modules-session-integration-test/src/test/resources/pagecontext.jsp
new file mode 100644
index 0000000..17f0009
--- /dev/null
+++ b/modules/gemfire-modules-session-integration-test/src/test/resources/pagecontext.jsp
@@ -0,0 +1 @@
+<%= pageContext.getRequest().getAttribute("foo") %> <%-- PAGE_SCOPE --%>
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/build.gradle
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/build.gradle b/modules/gemfire-modules-session/build.gradle
new file mode 100644
index 0000000..f6b074b
--- /dev/null
+++ b/modules/gemfire-modules-session/build.gradle
@@ -0,0 +1,3 @@
+dependencies {
+ compile project(':gemfire-modules')
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/pom.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/pom.xml b/modules/gemfire-modules-session/pom.xml
new file mode 100644
index 0000000..b274ab3
--- /dev/null
+++ b/modules/gemfire-modules-session/pom.xml
@@ -0,0 +1,46 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+ <groupId>com.gemstone</groupId>
+ <artifactId>gemfire-modules-session</artifactId>
+ <packaging>jar</packaging>
+ <version>${gemfire.modules.version}</version>
+ <url>http://maven.apache.org</url>
+ <name>gemfire-modules-session</name>
+
+ <parent>
+ <groupId>com.gemstone</groupId>
+ <artifactId>gemfire-modules-parent</artifactId>
+ <version>1.0-SNAPSHOT</version>
+ </parent>
+
+ <dependencies>
+ <dependency>
+ <groupId>junit</groupId>
+ <artifactId>junit</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>javax.servlet</groupId>
+ <artifactId>servlet-api</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.gemstone</groupId>
+ <artifactId>gemfire-modules</artifactId>
+ </dependency>
+
+ <dependency>
+ <groupId>com.gemstone.gemfire</groupId>
+ <artifactId>gemfire</artifactId>
+ </dependency>
+
+ <!--<dependency>-->
+ <!--<groupId>org.slf4j</groupId>-->
+ <!--<artifactId>slf4j-log4j12</artifactId>-->
+ <!--<scope>compile</scope>-->
+ <!--</dependency>-->
+
+ </dependencies>
+</project>
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/profiles.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/profiles.xml b/modules/gemfire-modules-session/profiles.xml
new file mode 100644
index 0000000..3bad1da
--- /dev/null
+++ b/modules/gemfire-modules-session/profiles.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<profilesXml xmlns="http://maven.apache.org/PROFILES/1.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/PROFILES/1.0.0 http://maven.apache.org/xsd/profiles-1.0.0.xsd">
+ <profiles>
+ <profile>
+ <id>netbeans-private</id>
+ <activation>
+ <property>
+ <name>netbeans.execution</name>
+ <value>true</value>
+ </property>
+ </activation>
+ <properties>
+ <netbeans.deployment.server.id>[/Users/jdeppe/apps/glassfishv3/glassfish]deployer:gfv3ee6:localhost:4848</netbeans.deployment.server.id>
+ </properties>
+ </profile>
+ </profiles>
+</profilesXml>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/bin/cacheserver.bat
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/bin/cacheserver.bat b/modules/gemfire-modules-session/release/bin/cacheserver.bat
new file mode 100755
index 0000000..2632dc7
--- /dev/null
+++ b/modules/gemfire-modules-session/release/bin/cacheserver.bat
@@ -0,0 +1,33 @@
+@setlocal enableextensions
+@set scriptdir=%~dp0
+@set gf=%scriptdir:\bin\=%
+@if exist "%gf%\lib\gemfire.jar" @goto gfok
+@echo Could not determine GEMFIRE location
+@verify other 2>nul
+@goto done
+:gfok
+
+@REM Initialize classpath
+
+@REM Add GemFire classes
+@set GEMFIRE_JARS=%gf%/lib/gemfire.jar;%gf%/lib/antlr.jar;%gf%/lib/mail.jar
+
+@REM Add Tomcat classes
+@set GEMFIRE_JARS=%GEMFIRE_JARS%;%gf%/lib/servlet-api.jar;%gf%/lib/catalina.jar;%gf%/lib/${artifact.artifactId}-${artifact.version}.jar;%gf%/bin/tomcat-juli.jar
+
+@REM Add conf directory
+@set GEMFIRE_JARS=%GEMFIRE_JARS%;%gf%/conf
+
+@if defined CLASSPATH set GEMFIRE_JARS=%GEMFIRE_JARS%;%CLASSPATH%
+
+@if not defined GF_JAVA (
+@REM %GF_JAVA% is not defined, assume it is on the PATH
+@set GF_JAVA=java
+)
+
+@"%GF_JAVA%" %JAVA_ARGS% -classpath "%GEMFIRE_JARS%" com.gemstone.gemfire.internal.cache.CacheServerLauncher %*
+:done
+@set scriptdir=
+@set gf=
+@set GEMFIRE_JARS=
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/bin/cacheserver.sh
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/bin/cacheserver.sh b/modules/gemfire-modules-session/release/bin/cacheserver.sh
new file mode 100755
index 0000000..e395001
--- /dev/null
+++ b/modules/gemfire-modules-session/release/bin/cacheserver.sh
@@ -0,0 +1,33 @@
+#!/bin/bash
+# Set GEMFIRE to the product toplevel directory
+GEMFIRE=`dirname $0`
+OLDPWD=$PWD
+cd $GEMFIRE
+GEMFIRE=`dirname $PWD`
+cd $OLDPWD
+
+if [ "x$WINDIR" != "x" ]; then
+ echo "ERROR: The variable WINDIR is set indicating this script is running in a Windows OS, please use the .bat file version instead."
+ exit 1
+fi
+
+GEMFIRE_JARS=$GEMFIRE/lib/gemfire-[0-9]*.jar
+if [ ! -f ${GEMFIRE_JARS} ]; then
+ echo "ERROR: Could not determine GEMFIRE location."
+ exit 1
+fi
+
+# Initialize classpath
+GEMFIRE_JARS=$GEMFIRE_JARS:$GEMFIRE/lib/gemfire-modules-[0-9]*
+GEMFIRE_JARS=$GEMFIRE_JARS:$GEMFIRE/lib/servlet-api-[0-9]*
+GEMFIRE_JARS=$GEMFIRE_JARS:$GEMFIRE/lib/slf4j-api-[0-9]*
+GEMFIRE_JARS=$GEMFIRE_JARS:$GEMFIRE/lib/slf4j-jdk14-[0-9]*
+
+# Add configuration
+GEMFIRE_JARS=$GEMFIRE_JARS:$GEMFIRE/conf
+
+if [ "x$CLASSPATH" != "x" ]; then
+ GEMFIRE_JARS=$GEMFIRE_JARS:$CLASSPATH
+fi
+
+${GF_JAVA:-java} ${JAVA_ARGS} -classpath ${GEMFIRE_JARS} com.gemstone.gemfire.internal.cache.CacheServerLauncher "$@"
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/bin/gemfire.bat
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/bin/gemfire.bat b/modules/gemfire-modules-session/release/bin/gemfire.bat
new file mode 100755
index 0000000..96d2564
--- /dev/null
+++ b/modules/gemfire-modules-session/release/bin/gemfire.bat
@@ -0,0 +1,23 @@
+@setlocal enableextensions
+@set scriptdir=%~dp0
+@set gf=%scriptdir:\bin\=%
+@if exist "%gf%\lib\gemfire.jar" @goto gfok
+@echo Could not determine GEMFIRE location
+@verify other 2>nul
+@goto done
+:gfok
+
+@set GEMFIRE_JARS=%gf%/lib/gemfire.jar;%gf%/lib/antlr.jar;%gf%/lib/mail.jar
+@if defined CLASSPATH set GEMFIRE_JARS=%GEMFIRE_JARS%;%CLASSPATH%
+
+@if not defined GF_JAVA (
+@REM %GF_JAVA% is not defined, assume it is on the PATH
+@set GF_JAVA=java
+)
+
+@"%GF_JAVA%" %JAVA_ARGS% -classpath "%GEMFIRE_JARS%" com.gemstone.gemfire.internal.SystemAdmin %*
+:done
+@set scriptdir=
+@set gf=
+@set GEMFIRE_JARS=
+
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/bin/gemfire.sh
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/bin/gemfire.sh b/modules/gemfire-modules-session/release/bin/gemfire.sh
new file mode 100755
index 0000000..fa5f4cd
--- /dev/null
+++ b/modules/gemfire-modules-session/release/bin/gemfire.sh
@@ -0,0 +1,41 @@
+#!/bin/bash
+# Set GEMFIRE to the product toplevel directory
+GEMFIRE=`dirname $0`
+OLDPWD=$PWD
+cd $GEMFIRE
+GEMFIRE=`dirname $PWD`
+cd $OLDPWD
+
+if [ "x$WINDIR" != "x" ]; then
+ echo "ERROR: The variable WINDIR is set indicating this script is running in a Windows OS, please use the .bat file version instead."
+ exit 1
+fi
+
+if [ ! -f $GEMFIRE/lib/gemfire.jar ]; then
+ echo "ERROR: Could not determine GEMFIRE location."
+ exit 1
+fi
+
+GEMFIRE_JARS=$GEMFIRE/lib/gemfire.jar:$GEMFIRE/lib/antlr.jar
+
+if [ "x$CLASSPATH" != "x" ]; then
+ GEMFIRE_JARS=$GEMFIRE_JARS:$CLASSPATH
+fi
+
+# Command line args that start with -J will be passed to the java vm in JARGS.
+# See java --help for a listing of valid vm args.
+# Example: -J-Xmx1g sets the max heap size to 1 gigabyte.
+
+JARGS=
+GEMFIRE_ARGS=
+for i in "$@"
+do
+ if [ "-J" == "${i:0:2}" ]
+ then
+ JARGS="${JARGS} \"${i#-J}\""
+ else
+ GEMFIRE_ARGS="${GEMFIRE_ARGS} \"${i}\""
+ fi
+done
+
+eval ${GF_JAVA:-java} ${JAVA_ARGS} ${JARGS} -classpath ${GEMFIRE_JARS} com.gemstone.gemfire.internal.SystemAdmin ${GEMFIRE_ARGS}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/bin/setenv.properties
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/bin/setenv.properties b/modules/gemfire-modules-session/release/bin/setenv.properties
new file mode 100644
index 0000000..fc8918b
--- /dev/null
+++ b/modules/gemfire-modules-session/release/bin/setenv.properties
@@ -0,0 +1,6 @@
+java.opt.1=-Xms${initial.vm.heap.size.mb:512}M
+java.opt.2=-Xmx${maximum.vm.heap.size.mb:512}M
+java.opt.hotspot.1=-XX:+UseParNewGC
+java.opt.hotspot.2=-XX:+UseConcMarkSweepGC
+java.opt.hotspot.3=-XX:CMSInitiatingOccupancyFraction=${cms.initiating.heap.percentage:50}
+java.opt.j9.1=-Xgcpolicy:gencon
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/conf/cache-client.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/conf/cache-client.xml b/modules/gemfire-modules-session/release/conf/cache-client.xml
new file mode 100755
index 0000000..c8444b2
--- /dev/null
+++ b/modules/gemfire-modules-session/release/conf/cache-client.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE client-cache PUBLIC
+ "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.5//EN"
+ "http://www.gemstone.com/dtd/cache6_6.dtd">
+
+<client-cache>
+
+ <!-- The default pool connects to a cache server running on localhost at
+ port 40404. To connect to a different server host and port, modify
+ the following pool server host and port. -->
+ <pool name="sessions" subscription-enabled="true">
+ <server host="localhost" port="40404"/>
+ </pool>
+
+ <!-- To configure the client to use a locator instead of a server, replace
+ the server pool above with the locator pool below and modify the locator
+ host and port as necessary. -->
+ <!--
+ <pool name="sessions" subscription-enabled="true">
+ <locator host="localhost" port="10334"/>
+ </pool>
+ -->
+
+</client-cache>
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/conf/cache-peer.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/conf/cache-peer.xml b/modules/gemfire-modules-session/release/conf/cache-peer.xml
new file mode 100755
index 0000000..1a49637
--- /dev/null
+++ b/modules/gemfire-modules-session/release/conf/cache-peer.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE cache PUBLIC
+ "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.5//EN"
+ "http://www.gemstone.com/dtd/cache6_6.dtd">
+
+<cache>
+
+ <!-- Uncomment the following disk-store element to modify the default disk store directory -->
+ <!--
+ <disk-store name="DEFAULT">
+ <disk-dirs>
+ <disk-dir>/path/to/persistent/data</disk-dir>
+ </disk-dirs>
+ </disk-store>
+ -->
+
+ <!-- This is the definition of the default session region -->
+ <!--
+ <region name="gemfire_modules_sessions">
+ <region-attributes scope="distributed-ack" enable-gateway="false" data-policy="replicate" statistics-enabled="true">
+ <entry-idle-time>
+ <expiration-attributes timeout="0" action="invalidate">
+ <custom-expiry>
+ <class-name>com.gemstone.gemfire.modules.util.SessionCustomExpiry</class-name>
+ </custom-expiry>
+ </expiration-attributes>
+ </entry-idle-time>
+ </region-attributes>
+ </region>
+ -->
+
+</cache>
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/release/conf/cache-server.xml
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/release/conf/cache-server.xml b/modules/gemfire-modules-session/release/conf/cache-server.xml
new file mode 100755
index 0000000..6ee2223
--- /dev/null
+++ b/modules/gemfire-modules-session/release/conf/cache-server.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<!DOCTYPE cache PUBLIC
+ "-//GemStone Systems, Inc.//GemFire Declarative Caching 6.5//EN"
+ "http://www.gemstone.com/dtd/cache6_6.dtd">
+
+<cache>
+
+ <!-- Uncomment the following gateway-hub element to create a gateway hub -->
+ <!--
+ <gateway-hub id="NY" port="11110">
+ <gateway id="LN">
+ <gateway-endpoint id="LN-1" host="localhost" port="22220"/>
+ <gateway-queue disk-store-name="NY_GATEWAY"/>
+ </gateway>
+ </gateway-hub>
+ -->
+
+ <!-- Uncomment the following cache-server element to modify the listen port -->
+ <!--
+ <cache-server port="44444"/>
+ -->
+
+ <!-- Uncomment the following disk-store element to modify the default disk store directory -->
+ <!--
+ <disk-store name="DEFAULT">
+ <disk-dirs>
+ <disk-dir>/path/to/persistent/data</disk-dir>
+ </disk-dirs>
+ </disk-store>
+ -->
+
+ <!-- Uncomment the following disk-store element to create the NY_GATEWAY disk store
+ (for the gateway-hub element defined above) -->
+ <!--
+ <disk-store name="NY_GATEWAY">
+ <disk-dirs>
+ <disk-dir>/path/to/persistent/data</disk-dir>
+ </disk-dirs>
+ </disk-store>
+ -->
+
+ <!-- This is the definition of the default session region -->
+ <!--
+ <region name="gemfire_modules_sessions">
+ <region-attributes enable-gateway="false" data-policy="partition" statistics-enabled="true">
+ <entry-idle-time>
+ <expiration-attributes timeout="0" action="invalidate">
+ <custom-expiry>
+ <class-name>com.gemstone.gemfire.modules.util.SessionCustomExpiry</class-name>
+ </custom-expiry>
+ </expiration-attributes>
+ </entry-idle-time>
+ <partition-attributes redundant-copies="1" total-num-buckets="113"/>
+ </region-attributes>
+ </region>
+ -->
+
+</cache>
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/AbstractSessionCache.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/AbstractSessionCache.java b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/AbstractSessionCache.java
new file mode 100644
index 0000000..a60b154
--- /dev/null
+++ b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/AbstractSessionCache.java
@@ -0,0 +1,92 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.common;
+
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.modules.session.catalina.internal.DeltaSessionStatistics;
+import com.gemstone.gemfire.modules.session.filter.util.TypeAwareMap;
+import com.gemstone.gemfire.modules.util.RegionConfiguration;
+
+import java.util.Map;
+import javax.servlet.http.HttpSession;
+
+public abstract class AbstractSessionCache implements SessionCache {
+
+ /**
+ * The sessionRegion is the <code>Region</code> that actually stores and
+ * replicates the <code>Session</code>s.
+ */
+ protected Region<String, HttpSession> sessionRegion;
+
+ /**
+ * The operatingRegion is the <code>Region</code> used to do HTTP operations.
+ * if local cache is enabled, then this will be the local <code>Region</code>;
+ * otherwise, it will be the session <code>Region</code>.
+ */
+ protected Region<String, HttpSession> operatingRegion;
+
+ protected Map<CacheProperty, Object> properties =
+ new TypeAwareMap<CacheProperty, Object>(CacheProperty.class);
+
+ protected DeltaSessionStatistics statistics;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stop() {
+ sessionRegion.close();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Region<String, HttpSession> getOperatingRegion() {
+ return this.operatingRegion;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Region<String, HttpSession> getSessionRegion() {
+ return this.sessionRegion;
+ }
+
+ protected void createStatistics() {
+ this.statistics =
+ new DeltaSessionStatistics(getCache().getDistributedSystem(),
+ (String) properties.get(CacheProperty.STATISTICS_NAME));
+ }
+
+ /**
+ * Build up a {@code RegionConfiguraton} object from parameters originally
+ * passed in as filter initialization parameters.
+ *
+ * @return a {@code RegionConfiguration} object
+ */
+ protected RegionConfiguration createRegionConfiguration() {
+ RegionConfiguration configuration = new RegionConfiguration();
+
+ configuration.setRegionName(
+ (String) properties.get(CacheProperty.REGION_NAME));
+ configuration.setRegionAttributesId(
+ (String) properties.get(CacheProperty.REGION_ATTRIBUTES_ID));
+
+ configuration.setEnableGatewayDeltaReplication(
+ (Boolean) properties.get(
+ CacheProperty.ENABLE_GATEWAY_DELTA_REPLICATION));
+ configuration.setEnableGatewayReplication(
+ (Boolean) properties.get(CacheProperty.ENABLE_GATEWAY_REPLICATION));
+ configuration.setEnableDebugListener(
+ (Boolean) properties.get(CacheProperty.ENABLE_DEBUG_LISTENER));
+
+ return configuration;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/CacheProperty.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/CacheProperty.java b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/CacheProperty.java
new file mode 100644
index 0000000..d8b7c64
--- /dev/null
+++ b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/CacheProperty.java
@@ -0,0 +1,56 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+
+package com.gemstone.gemfire.modules.session.common;
+
+/**
+ * Used to define cache properties
+ */
+public enum CacheProperty {
+
+ ENABLE_DEBUG_LISTENER(Boolean.class),
+
+ ENABLE_GATEWAY_REPLICATION(Boolean.class),
+
+ ENABLE_GATEWAY_DELTA_REPLICATION(Boolean.class),
+
+ ENABLE_LOCAL_CACHE(Boolean.class),
+
+ REGION_NAME(String.class),
+
+ REGION_ATTRIBUTES_ID(String.class),
+
+ STATISTICS_NAME(String.class),
+
+ /**
+ * This parameter can take the following values which match the respective
+ * attribute container classes
+ * <p/>
+ * delta_queued : QueuedDeltaSessionAttributes delta_immediate :
+ * DeltaSessionAttributes immediate : ImmediateSessionAttributes queued
+ * : QueuedSessionAttributes
+ */
+ SESSION_DELTA_POLICY(String.class),
+
+ /**
+ * This parameter can take the following values:
+ * <p/>
+ * set (default) set_and_get
+ */
+ REPLICATION_TRIGGER(String.class);
+
+ Class clazz;
+
+ CacheProperty(Class clazz) {
+ this.clazz = clazz;
+ }
+
+ public Class getClazz() {
+ return clazz;
+ }
+}
http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/4b56f5e4/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/ClientServerSessionCache.java
----------------------------------------------------------------------
diff --git a/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/ClientServerSessionCache.java b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/ClientServerSessionCache.java
new file mode 100644
index 0000000..a53bfbc
--- /dev/null
+++ b/modules/gemfire-modules-session/src/main/java/com/gemstone/gemfire/modules/session/common/ClientServerSessionCache.java
@@ -0,0 +1,176 @@
+/*=========================================================================
+ * Copyright (c) 2010-2014 Pivotal Software, Inc. All Rights Reserved.
+ * This product is protected by U.S. and international copyright
+ * and intellectual property laws. Pivotal products are covered by
+ * one or more patents listed at http://www.pivotal.io/patents.
+ *=========================================================================
+ */
+package com.gemstone.gemfire.modules.session.common;
+
+import com.gemstone.gemfire.cache.GemFireCache;
+import com.gemstone.gemfire.cache.Region;
+import com.gemstone.gemfire.cache.RegionShortcut;
+import com.gemstone.gemfire.cache.client.ClientCache;
+import com.gemstone.gemfire.cache.client.ClientRegionFactory;
+import com.gemstone.gemfire.cache.client.ClientRegionShortcut;
+import com.gemstone.gemfire.cache.execute.Execution;
+import com.gemstone.gemfire.cache.execute.FunctionService;
+import com.gemstone.gemfire.cache.execute.ResultCollector;
+import com.gemstone.gemfire.modules.util.BootstrappingFunction;
+import com.gemstone.gemfire.modules.util.CreateRegionFunction;
+import com.gemstone.gemfire.modules.util.RegionConfiguration;
+import com.gemstone.gemfire.modules.util.RegionStatus;
+
+import java.util.List;
+import java.util.Map;
+import javax.servlet.http.HttpSession;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Class which defines a client/server cache.
+ */
+public class ClientServerSessionCache extends AbstractSessionCache {
+
+ private static final Logger LOG =
+ LoggerFactory.getLogger(PeerToPeerSessionCache.class.getName());
+
+ private ClientCache cache;
+
+ protected static final String DEFAULT_REGION_ATTRIBUTES_ID =
+ RegionShortcut.PARTITION_REDUNDANT.toString();
+
+ protected static final Boolean DEFAULT_ENABLE_LOCAL_CACHE = true;
+
+ /**
+ * Constructor
+ *
+ * @param cache
+ * @param properties
+ */
+ public ClientServerSessionCache(ClientCache cache,
+ Map<CacheProperty, Object> properties) {
+ super();
+ this.cache = cache;
+
+ /**
+ * Set some default properties for this cache if they haven't already
+ * been set
+ */
+ this.properties.put(CacheProperty.REGION_ATTRIBUTES_ID,
+ DEFAULT_REGION_ATTRIBUTES_ID);
+ this.properties.put(CacheProperty.ENABLE_LOCAL_CACHE,
+ DEFAULT_ENABLE_LOCAL_CACHE);
+ this.properties.putAll(properties);
+ }
+
+ @Override
+ public void initialize() {
+ // Bootstrap the servers
+ bootstrapServers();
+
+ // Create or retrieve the region
+ createOrRetrieveRegion();
+
+ // Set the session region directly as the operating region since there is no difference
+ // between the local cache region and the session region.
+ operatingRegion = sessionRegion;
+
+ // Create or retrieve the statistics
+ createStatistics();
+ }
+
+ @Override
+ public GemFireCache getCache() {
+ return cache;
+ }
+
+ @Override
+ public boolean isClientServer() {
+ return true;
+ }
+
+
+ ////////////////////////////////////////////////////////////////////////
+ // Private methods
+
+ private void bootstrapServers() {
+ Execution execution = FunctionService.onServers(this.cache);
+ ResultCollector collector = execution.execute(new BootstrappingFunction());
+ // Get the result. Nothing is being done with it.
+ try {
+ collector.getResult();
+ } catch (Exception e) {
+ // If an exception occurs in the function, log it.
+ LOG.warn("Caught unexpected exception:", e);
+ }
+ }
+
+ private void createOrRetrieveRegion() {
+ // Retrieve the local session region
+ this.sessionRegion =
+ this.cache.getRegion(
+ (String) properties.get(CacheProperty.REGION_NAME));
+
+ // If necessary, create the regions on the server and client
+ if (this.sessionRegion == null) {
+ // Create the PR on the servers
+ createSessionRegionOnServers();
+
+ // Create the region on the client
+ this.sessionRegion = createLocalSessionRegion();
+ LOG.debug("Created session region: " + this.sessionRegion);
+ } else {
+ LOG.debug("Retrieved session region: " + this.sessionRegion);
+ }
+ }
+
+ private void createSessionRegionOnServers() {
+ // Create the RegionConfiguration
+ RegionConfiguration configuration = createRegionConfiguration();
+
+ // Send it to the server tier
+ Execution execution = FunctionService.onServer(this.cache).withArgs(
+ configuration);
+ ResultCollector collector = execution.execute(CreateRegionFunction.ID);
+
+ // Verify the region was successfully created on the servers
+ List<RegionStatus> results = (List<RegionStatus>) collector.getResult();
+ for (RegionStatus status : results) {
+ if (status == RegionStatus.INVALID) {
+ StringBuilder builder = new StringBuilder();
+ builder.append(
+ "An exception occurred on the server while attempting to create or validate region named ");
+ builder.append(properties.get(CacheProperty.REGION_NAME));
+ builder.append(". See the server log for additional details.");
+ throw new IllegalStateException(builder.toString());
+ }
+ }
+ }
+
+ private Region<String, HttpSession> createLocalSessionRegion() {
+ ClientRegionFactory<String, HttpSession> factory = null;
+ boolean enableLocalCache =
+ (Boolean) properties.get(CacheProperty.ENABLE_LOCAL_CACHE);
+
+ String regionName = (String) properties.get(CacheProperty.REGION_NAME);
+ if (enableLocalCache) {
+ // Create the region factory with caching and heap LRU enabled
+ factory = ((ClientCache) this.cache).
+ createClientRegionFactory(
+ ClientRegionShortcut.CACHING_PROXY_HEAP_LRU);
+ LOG.info("Created new local client session region: {}", regionName);
+ } else {
+ // Create the region factory without caching enabled
+ factory = ((ClientCache) this.cache).createClientRegionFactory(
+ ClientRegionShortcut.PROXY);
+ LOG.info(
+ "Created new local client (uncached) session region: {} without any session expiry",
+ regionName);
+ }
+
+ // Create the region
+ return factory.create(regionName);
+ }
+}