diff --git a/tomcat-core/src/test/java/com/hazelcast/session/AbstractSessionExpireTest.java b/tomcat-core/src/test/java/com/hazelcast/session/AbstractSessionExpireTest.java new file mode 100644 index 0000000..b4fc0d3 --- /dev/null +++ b/tomcat-core/src/test/java/com/hazelcast/session/AbstractSessionExpireTest.java @@ -0,0 +1,55 @@ +package com.hazelcast.session; + +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.apache.http.client.CookieStore; +import org.apache.http.impl.client.BasicCookieStore; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +public abstract class AbstractSessionExpireTest extends AbstractHazelcastSessionsTest { + + @Test + public void testSessionExpireAfterFailoverAndSessionTimeout() throws Exception { + final int SESSION_TIMEOUT_IN_MINUTES = 1; + final int EXTRA_DELAY_IN_SECONDS = 5; + + instance1 = getWebContainerConfigurator(); + instance1.port(SERVER_PORT_1) + .sticky(true) + .clientOnly(false) + .mapName(SESSION_REPLICATION_MAP_NAME) + .sessionTimeout(SESSION_TIMEOUT_IN_MINUTES) + .configLocation("hazelcast-1.xml") + .start(); + + instance2 = getWebContainerConfigurator(); + instance2.port(SERVER_PORT_2) + .sticky(true) + .clientOnly(false) + .mapName(SESSION_REPLICATION_MAP_NAME) + .sessionTimeout(SESSION_TIMEOUT_IN_MINUTES) + .configLocation("hazelcast-2.xml") + .start(); + + CookieStore cookieStore = new BasicCookieStore(); + executeRequest("write", SERVER_PORT_1, cookieStore); + String value = executeRequest("read", SERVER_PORT_1, cookieStore); + assertEquals("value", value); + + instance1.stop(); + + HazelcastInstance hzInstance1 = Hazelcast.getHazelcastInstanceByName("hzInstance1"); + if (hzInstance1 != null) { + hzInstance1.shutdown(); + } + + + sleepSeconds(SESSION_TIMEOUT_IN_MINUTES * 60 + EXTRA_DELAY_IN_SECONDS); + + assertEquals(0, instance2.getManager().getDistributedMap().size()); + + instance2.stop(); + } +} diff --git a/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index bba7a99..77db3ff 100644 --- a/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat6/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -25,6 +25,9 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; public class HazelcastSessionManager extends ManagerBase implements Lifecycle, PropertyChangeListener, SessionManager { @@ -259,6 +262,31 @@ public Session findSession(String id) throws IOException { } } + @Override + public Session[] findSessions() { + // Get all local sessions + Set allSessions = new HashSet(sessions.values()); + + // Get all non-local sessions ids + Set keys = new HashSet(sessionMap.keySet()); + keys.removeAll(sessions.keySet()); + + // Get all non-local sessions + final Collection nonLocalSessions = sessionMap.getAll(keys).values(); + + // Set SessionManager since it's a transient field + for (HazelcastSession nonLocalSession : nonLocalSessions) { + if (nonLocalSession.getManager() == null) { + nonLocalSession.setSessionManager(this); + } + } + + // Add all non-local sessions + allSessions.addAll(nonLocalSessions); + + return allSessions.toArray(new Session[allSessions.size()]); + } + public void commit(Session session) { HazelcastSession hazelcastSession = (HazelcastSession) session; if (hazelcastSession.isDirty()) { diff --git a/tomcat6/src/test/java/com/hazelcast/session/Tomcat6Configurator.java b/tomcat6/src/test/java/com/hazelcast/session/Tomcat6Configurator.java index 8eeb728..0a437da 100644 --- a/tomcat6/src/test/java/com/hazelcast/session/Tomcat6Configurator.java +++ b/tomcat6/src/test/java/com/hazelcast/session/Tomcat6Configurator.java @@ -119,5 +119,6 @@ private void updateManager(HazelcastSessionManager manager) { manager.setMapName(mapName); manager.setMaxInactiveInterval(sessionTimeout); manager.setDeferredWrite(deferredWrite); + manager.setProcessExpiresFrequency(1); } } diff --git a/tomcat6/src/test/java/com/hazelcast/session/Tomcat6SessionExpireTest.java b/tomcat6/src/test/java/com/hazelcast/session/Tomcat6SessionExpireTest.java new file mode 100644 index 0000000..45f2031 --- /dev/null +++ b/tomcat6/src/test/java/com/hazelcast/session/Tomcat6SessionExpireTest.java @@ -0,0 +1,15 @@ +package com.hazelcast.session; + +import com.hazelcast.test.HazelcastSerialClassRunner; +import com.hazelcast.test.annotation.QuickTest; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +@RunWith(HazelcastSerialClassRunner.class) +@Category(QuickTest.class) +public class Tomcat6SessionExpireTest extends AbstractSessionExpireTest { + @Override + protected WebContainerConfigurator getWebContainerConfigurator() { + return new Tomcat6Configurator(); + } +} diff --git a/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index d6a2453..4d698f7 100644 --- a/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat7/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -26,6 +26,9 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; public class HazelcastSessionManager extends ManagerBase implements Lifecycle, PropertyChangeListener, SessionManager { @@ -258,6 +261,31 @@ public Session findSession(String id) throws IOException { } } + @Override + public Session[] findSessions() { + // Get all local sessions + Set allSessions = new HashSet(sessions.values()); + + // Get all non-local sessions ids + Set keys = new HashSet(sessionMap.keySet()); + keys.removeAll(sessions.keySet()); + + // Get all non-local sessions + final Collection nonLocalSessions = sessionMap.getAll(keys).values(); + + // Set SessionManager since it's a transient field + for (HazelcastSession nonLocalSession : nonLocalSessions) { + if (nonLocalSession.getManager() == null) { + nonLocalSession.setSessionManager(this); + } + } + + // Add all non-local sessions + allSessions.addAll(nonLocalSessions); + + return allSessions.toArray(new Session[allSessions.size()]); + } + public void commit(Session session) { HazelcastSession hazelcastSession = (HazelcastSession) session; if (hazelcastSession.isDirty()) { diff --git a/tomcat7/src/test/java/com/hazelcast/session/Tomcat7AsyncConfigurator.java b/tomcat7/src/test/java/com/hazelcast/session/Tomcat7AsyncConfigurator.java index 71e9b3a..6437bd2 100644 --- a/tomcat7/src/test/java/com/hazelcast/session/Tomcat7AsyncConfigurator.java +++ b/tomcat7/src/test/java/com/hazelcast/session/Tomcat7AsyncConfigurator.java @@ -93,6 +93,8 @@ private void updateManager(HazelcastSessionManager manager) { manager.setSticky(sticky); manager.setClientOnly(clientOnly); manager.setMapName(mapName); + manager.setMaxInactiveInterval(sessionTimeout); manager.setDeferredWrite(deferredWrite); + manager.setProcessExpiresFrequency(1); } } \ No newline at end of file diff --git a/tomcat7/src/test/java/com/hazelcast/session/Tomcat7Configurator.java b/tomcat7/src/test/java/com/hazelcast/session/Tomcat7Configurator.java index afd2878..305d638 100644 --- a/tomcat7/src/test/java/com/hazelcast/session/Tomcat7Configurator.java +++ b/tomcat7/src/test/java/com/hazelcast/session/Tomcat7Configurator.java @@ -94,5 +94,6 @@ private void updateManager(HazelcastSessionManager manager) { manager.setMapName(mapName); manager.setMaxInactiveInterval(sessionTimeout); manager.setDeferredWrite(deferredWrite); + manager.setProcessExpiresFrequency(1); } } diff --git a/tomcat7/src/test/java/com/hazelcast/session/Tomcat7SessionExpireTest.java b/tomcat7/src/test/java/com/hazelcast/session/Tomcat7SessionExpireTest.java new file mode 100644 index 0000000..7ea4046 --- /dev/null +++ b/tomcat7/src/test/java/com/hazelcast/session/Tomcat7SessionExpireTest.java @@ -0,0 +1,15 @@ +package com.hazelcast.session; + +import com.hazelcast.test.HazelcastSerialClassRunner; +import com.hazelcast.test.annotation.QuickTest; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +@RunWith(HazelcastSerialClassRunner.class) +@Category(QuickTest.class) +public class Tomcat7SessionExpireTest extends AbstractSessionExpireTest { + @Override + protected WebContainerConfigurator getWebContainerConfigurator() { + return new Tomcat7Configurator(); + } +} diff --git a/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index eff76fb..ed811a5 100644 --- a/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat8/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -26,6 +26,9 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; public class HazelcastSessionManager extends ManagerBase implements Lifecycle, PropertyChangeListener, SessionManager { @@ -51,6 +54,10 @@ public class HazelcastSessionManager extends ManagerBase implements Lifecycle, P private HazelcastInstance instance; + public void setSessionTimeout(int t) { + getContext().setSessionTimeout(t); + } + @Override public String getName() { return NAME; @@ -251,6 +258,31 @@ public Session findSession(String id) throws IOException { } } + @Override + public Session[] findSessions() { + // Get all local sessions + Set allSessions = new HashSet(sessions.values()); + + // Get all non-local sessions ids + Set keys = new HashSet(sessionMap.keySet()); + keys.removeAll(sessions.keySet()); + + // Get all non-local sessions + final Collection nonLocalSessions = sessionMap.getAll(keys).values(); + + // Set SessionManager since it's a transient field + for (HazelcastSession nonLocalSession : nonLocalSessions) { + if (nonLocalSession.getManager() == null) { + nonLocalSession.setSessionManager(this); + } + } + + // Add all non-local sessions + allSessions.addAll(nonLocalSessions); + + return allSessions.toArray(new Session[allSessions.size()]); + } + public void commit(Session session) { HazelcastSession hazelcastSession = (HazelcastSession) session; if (hazelcastSession.isDirty()) { diff --git a/tomcat8/src/test/java/Tomcat8SessionExpireTest.java b/tomcat8/src/test/java/Tomcat8SessionExpireTest.java new file mode 100644 index 0000000..a1bceb5 --- /dev/null +++ b/tomcat8/src/test/java/Tomcat8SessionExpireTest.java @@ -0,0 +1,10 @@ +import com.hazelcast.session.AbstractSessionExpireTest; +import com.hazelcast.session.Tomcat8Configurator; +import com.hazelcast.session.WebContainerConfigurator; + +public class Tomcat8SessionExpireTest extends AbstractSessionExpireTest { + @Override + protected WebContainerConfigurator getWebContainerConfigurator() { + return new Tomcat8Configurator(); + } +} diff --git a/tomcat8/src/test/java/com/hazelcast/session/Tomcat8AsyncConfigurator.java b/tomcat8/src/test/java/com/hazelcast/session/Tomcat8AsyncConfigurator.java index f25d85f..d374d0d 100644 --- a/tomcat8/src/test/java/com/hazelcast/session/Tomcat8AsyncConfigurator.java +++ b/tomcat8/src/test/java/com/hazelcast/session/Tomcat8AsyncConfigurator.java @@ -10,7 +10,7 @@ public class Tomcat8AsyncConfigurator extends WebContainerConfigurator { private final String baseDir; private Tomcat tomcat; - private SessionManager manager; + private HazelcastSessionManager manager; public Tomcat8AsyncConfigurator(String baseDir) { this.baseDir = baseDir; @@ -53,8 +53,8 @@ public Tomcat configure() throws Exception { } this.manager = new HazelcastSessionManager(); - context.setManager((HazelcastSessionManager) manager); - updateManager((HazelcastSessionManager) manager); + context.setManager(manager); + updateManager(manager); context.setCookies(true); context.setBackgroundProcessorDelay(1); context.setReloadable(true); @@ -66,6 +66,7 @@ public Tomcat configure() throws Exception { public void start() throws Exception { tomcat = configure(); tomcat.start(); + setSessionTimeout(); } @Override @@ -82,6 +83,7 @@ public void reload() { context = (Context) tomcat.getHost().findChild(""); } context.reload(); + setSessionTimeout(); } @Override @@ -94,5 +96,10 @@ private void updateManager(HazelcastSessionManager manager) { manager.setClientOnly(clientOnly); manager.setMapName(mapName); manager.setDeferredWrite(deferredWrite); + manager.setProcessExpiresFrequency(1); + } + + private void setSessionTimeout() { + manager.setSessionTimeout(sessionTimeout); } } \ No newline at end of file diff --git a/tomcat8/src/test/java/com/hazelcast/session/Tomcat8Configurator.java b/tomcat8/src/test/java/com/hazelcast/session/Tomcat8Configurator.java index cc1c1f8..bd45d20 100644 --- a/tomcat8/src/test/java/com/hazelcast/session/Tomcat8Configurator.java +++ b/tomcat8/src/test/java/com/hazelcast/session/Tomcat8Configurator.java @@ -11,7 +11,7 @@ public class Tomcat8Configurator extends WebContainerConfigurator { private Tomcat tomcat; - private SessionManager manager; + private HazelcastSessionManager manager; private String appName; public Tomcat8Configurator(String appName) { @@ -58,8 +58,8 @@ public Tomcat configure() throws Exception { } this.manager = new HazelcastSessionManager(); - context.setManager((HazelcastSessionManager) manager); - updateManager((HazelcastSessionManager) manager); + context.setManager(manager); + updateManager(manager); context.setCookies(true); context.setBackgroundProcessorDelay(1); context.setReloadable(true); @@ -71,6 +71,7 @@ public Tomcat configure() throws Exception { public void start() throws Exception { tomcat = configure(); tomcat.start(); + setSessionTimeout(); } @Override @@ -88,6 +89,7 @@ public void reload() { context = (Context) tomcat.getHost().findChild(""); } context.reload(); + setSessionTimeout(); } @Override @@ -99,7 +101,11 @@ private void updateManager(HazelcastSessionManager manager) { manager.setSticky(sticky); manager.setClientOnly(clientOnly); manager.setMapName(mapName); - manager.setMaxInactiveInterval(sessionTimeout); manager.setDeferredWrite(deferredWrite); + manager.setProcessExpiresFrequency(1); + } + + private void setSessionTimeout() { + manager.setSessionTimeout(sessionTimeout); } } diff --git a/tomcat8/src/test/java/com/hazelcast/session/Tomcat8SessionExpireTest.java b/tomcat8/src/test/java/com/hazelcast/session/Tomcat8SessionExpireTest.java new file mode 100644 index 0000000..e76f546 --- /dev/null +++ b/tomcat8/src/test/java/com/hazelcast/session/Tomcat8SessionExpireTest.java @@ -0,0 +1,15 @@ +package com.hazelcast.session; + +import com.hazelcast.test.HazelcastSerialClassRunner; +import com.hazelcast.test.annotation.QuickTest; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +@RunWith(HazelcastSerialClassRunner.class) +@Category(QuickTest.class) +public class Tomcat8SessionExpireTest extends AbstractSessionExpireTest { + @Override + protected WebContainerConfigurator getWebContainerConfigurator() { + return new Tomcat8Configurator(); + } +} diff --git a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java index 968f876..1a76aaf 100644 --- a/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java +++ b/tomcat85/src/main/java/com/hazelcast/session/HazelcastSessionManager.java @@ -24,6 +24,9 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.Set; public class HazelcastSessionManager extends ManagerBase implements Lifecycle, PropertyChangeListener, SessionManager { @@ -239,6 +242,31 @@ public Session findSession(String id) throws IOException { } } + @Override + public Session[] findSessions() { + // Get all local sessions + Set allSessions = new HashSet(sessions.values()); + + // Get all non-local sessions ids + Set keys = new HashSet(sessionMap.keySet()); + keys.removeAll(sessions.keySet()); + + // Get all non-local sessions + final Collection nonLocalSessions = sessionMap.getAll(keys).values(); + + // Set SessionManager since it's a transient field + for (HazelcastSession nonLocalSession : nonLocalSessions) { + if (nonLocalSession.getManager() == null) { + nonLocalSession.setSessionManager(this); + } + } + + // Add all non-local sessions + allSessions.addAll(nonLocalSessions); + + return allSessions.toArray(new Session[allSessions.size()]); + } + public void commit(Session session) { HazelcastSession hazelcastSession = (HazelcastSession) session; if (hazelcastSession.isDirty()) { diff --git a/tomcat85/src/test/java/com/hazelcast/session/Tomcat85AsyncConfigurator.java b/tomcat85/src/test/java/com/hazelcast/session/Tomcat85AsyncConfigurator.java index 7f916ec..c67e719 100644 --- a/tomcat85/src/test/java/com/hazelcast/session/Tomcat85AsyncConfigurator.java +++ b/tomcat85/src/test/java/com/hazelcast/session/Tomcat85AsyncConfigurator.java @@ -10,7 +10,7 @@ public class Tomcat85AsyncConfigurator extends WebContainerConfigurator private final String baseDir; private Tomcat tomcat; - private SessionManager manager; + private HazelcastSessionManager manager; public Tomcat85AsyncConfigurator(String baseDir) { this.baseDir = baseDir; @@ -46,15 +46,15 @@ public Tomcat configure() throws Exception { asyncServlet.setAsyncSupported(true); context.addChild(asyncServlet); - context.addServletMapping("/*", "asyncServlet"); + context.addServletMappingDecoded("/*", "asyncServlet"); } catch (final Exception e) { throw new IllegalStateException(e); } this.manager = new HazelcastSessionManager(); - context.setManager((HazelcastSessionManager) manager); - updateManager((HazelcastSessionManager) manager); + context.setManager(manager); + updateManager(manager); context.setCookies(true); context.setBackgroundProcessorDelay(1); context.setReloadable(true); @@ -66,6 +66,7 @@ public Tomcat configure() throws Exception { public void start() throws Exception { tomcat = configure(); tomcat.start(); + setSessionTimeout(); } @Override @@ -82,6 +83,7 @@ public void reload() { context = (Context) tomcat.getHost().findChild(""); } context.reload(); + setSessionTimeout(); } @Override @@ -94,5 +96,10 @@ private void updateManager(HazelcastSessionManager manager) { manager.setClientOnly(clientOnly); manager.setMapName(mapName); manager.setDeferredWrite(deferredWrite); + manager.setProcessExpiresFrequency(1); + } + + private void setSessionTimeout() { + manager.setSessionTimeout(sessionTimeout); } } \ No newline at end of file diff --git a/tomcat85/src/test/java/com/hazelcast/session/Tomcat85Configurator.java b/tomcat85/src/test/java/com/hazelcast/session/Tomcat85Configurator.java index a9e6fa8..7de5b83 100644 --- a/tomcat85/src/test/java/com/hazelcast/session/Tomcat85Configurator.java +++ b/tomcat85/src/test/java/com/hazelcast/session/Tomcat85Configurator.java @@ -11,7 +11,7 @@ public class Tomcat85Configurator extends WebContainerConfigurator { private Tomcat tomcat; - private SessionManager manager; + private HazelcastSessionManager manager; private String appName; public Tomcat85Configurator(String appName) { @@ -58,8 +58,8 @@ public Tomcat configure() throws Exception { } this.manager = new HazelcastSessionManager(); - context.setManager((HazelcastSessionManager) manager); - updateManager((HazelcastSessionManager) manager); + context.setManager(manager); + updateManager(manager); context.setCookies(true); context.setBackgroundProcessorDelay(1); context.setReloadable(true); @@ -71,6 +71,7 @@ public Tomcat configure() throws Exception { public void start() throws Exception { tomcat = configure(); tomcat.start(); + setSessionTimeout(); } @Override @@ -88,6 +89,7 @@ public void reload() { context = (Context) tomcat.getHost().findChild(""); } context.reload(); + setSessionTimeout(); } @Override @@ -99,7 +101,11 @@ private void updateManager(HazelcastSessionManager manager) { manager.setSticky(sticky); manager.setClientOnly(clientOnly); manager.setMapName(mapName); - manager.setSessionTimeout(sessionTimeout); manager.setDeferredWrite(deferredWrite); + manager.setProcessExpiresFrequency(1); + } + + private void setSessionTimeout() { + manager.setSessionTimeout(sessionTimeout); } } diff --git a/tomcat85/src/test/java/com/hazelcast/session/Tomcat85SessionExpireTest.java b/tomcat85/src/test/java/com/hazelcast/session/Tomcat85SessionExpireTest.java new file mode 100644 index 0000000..f35cd88 --- /dev/null +++ b/tomcat85/src/test/java/com/hazelcast/session/Tomcat85SessionExpireTest.java @@ -0,0 +1,15 @@ +package com.hazelcast.session; + +import com.hazelcast.test.HazelcastSerialClassRunner; +import com.hazelcast.test.annotation.QuickTest; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; + +@RunWith(HazelcastSerialClassRunner.class) +@Category(QuickTest.class) +public class Tomcat85SessionExpireTest extends AbstractSessionExpireTest { + @Override + protected WebContainerConfigurator getWebContainerConfigurator() { + return new Tomcat85Configurator(); + } +}