From 8a300613df81816d40fd3e3a9139aa60f5e22597 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Mon, 29 May 2017 14:47:18 +1000 Subject: [PATCH 01/12] add Hazelcast session management #1571 Signed-off-by: olivier lamy --- jetty-bom/pom.xml | 5 + jetty-hazelcast/pom.xml | 165 ++++++++++++++ jetty-hazelcast/src/main/assembly/config.xml | 27 +++ .../etc/sessions/hazelcast/session-store.xml | 18 ++ .../modules/session-store-hazelcast.mod | 36 +++ .../session/HazelcastSessionDataStore.java | 211 ++++++++++++++++++ .../HazelcastSessionDataStoreFactory.java | 176 +++++++++++++++ .../session/TestHazelcastSessions.java | 203 +++++++++++++++++ jetty-home/pom.xml | 5 + pom.xml | 1 + tests/test-sessions/pom.xml | 1 + .../test-hazelcast-sessions/pom.xml | 94 ++++++++ .../session/ClusteredLastAccessTimeTest.java | 38 ++++ .../session/ClusteredOrphanedSessionTest.java | 44 ++++ .../ClusteredSessionMigrationTest.java | 41 ++++ .../ClusteredSessionScavengingTest.java | 41 ++++ .../ModifyMaxInactiveIntervalTest.java | 42 ++++ .../NonClusteredSessionScavengingTest.java | 69 ++++++ .../hazelcast/session/SessionExpiryTest.java | 40 ++++ .../SessionInvalidateCreateScavengeTest.java | 41 ++++ .../client/ClientLastAccessTimeTest.java | 68 ++++++ .../ClientModifyMaxInactiveIntervalTest.java | 43 ++++ ...ientNonClusteredSessionScavengingTest.java | 96 ++++++++ .../client/ClientOrphanedSessionTest.java | 69 ++++++ .../client/ClientSessionExpiryTest.java | 71 ++++++ ...ntSessionInvalidateCreateScavengeTest.java | 68 ++++++ .../client/ClientSessionMigrationTest.java | 71 ++++++ .../client/ClientSessionScavengingTest.java | 69 ++++++ 28 files changed, 1853 insertions(+) create mode 100644 jetty-hazelcast/pom.xml create mode 100644 jetty-hazelcast/src/main/assembly/config.xml create mode 100644 jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml create mode 100644 jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod create mode 100644 jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java create mode 100644 jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java create mode 100644 jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/pom.xml create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredLastAccessTimeTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionMigrationTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ModifyMaxInactiveIntervalTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/NonClusteredSessionScavengingTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionExpiryTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionInvalidateCreateScavengeTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientModifyMaxInactiveIntervalTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java create mode 100644 tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java diff --git a/jetty-bom/pom.xml b/jetty-bom/pom.xml index 8444f223516..5d1487936ce 100644 --- a/jetty-bom/pom.xml +++ b/jetty-bom/pom.xml @@ -232,6 +232,11 @@ jetty-infinispan 9.4.7-SNAPSHOT + + org.eclipse.jetty + jetty-hazelcast + 9.4.6-SNAPSHOT + org.eclipse.jetty jetty-io diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml new file mode 100644 index 00000000000..d5062f6d23b --- /dev/null +++ b/jetty-hazelcast/pom.xml @@ -0,0 +1,165 @@ + + + + jetty-project + org.eclipse.jetty + 9.4.6-SNAPSHOT + + + 4.0.0 + jetty-hazelcast + Jetty :: Hazelcast Session Manager + + + 3.8.2 + ${project.groupId}.session + + + + + com.hazelcast + hazelcast + ${hazelcast.version} + test-jar + + + com.hazelcast + hazelcast-client + ${hazelcast.version} + + + com.hazelcast + hazelcast + ${hazelcast.version} + + + org.eclipse.jetty + jetty-server + ${project.version} + + + org.eclipse.jetty + jetty-webapp + ${project.version} + test + + + org.eclipse.jetty.websocket + websocket-servlet + ${project.version} + test + + + org.eclipse.jetty.websocket + websocket-server + ${project.version} + test + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + + + + + + + org.apache.felix + maven-bundle-plugin + true + + + + manifest + + + + + org.eclipse.jetty.hazelcast.session.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"; + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + build-deps-file + generate-resources + + list + + + false + ${project.build.directory}/deps.txt + true + org.eclipse.jetty + true + runtime + + + + + + org.apache.maven.plugins + maven-antrun-plugin + + + process-deps + process-resources + + run + + + + + + + + + process-mod + process-resources + + run + + + + + + + + + + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + + src/main/assembly/config.xml + + + + + + + + + diff --git a/jetty-hazelcast/src/main/assembly/config.xml b/jetty-hazelcast/src/main/assembly/config.xml new file mode 100644 index 00000000000..45e740841f1 --- /dev/null +++ b/jetty-hazelcast/src/main/assembly/config.xml @@ -0,0 +1,27 @@ + + + config + false + + jar + + + + src/main/config-template + + + ** + + + **/session-store-hazelcast.mod + + + + target + modules + + session-store-hazelcast.mod + + + + diff --git a/jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml b/jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml new file mode 100644 index 00000000000..ecd6efb1ea0 --- /dev/null +++ b/jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + diff --git a/jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod b/jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod new file mode 100644 index 00000000000..5b70060bf23 --- /dev/null +++ b/jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod @@ -0,0 +1,36 @@ +[description] +Enables Hazelcast session management. + +[tags] +session +hazelcast + +[provides] +session-store + +[depends] +annotations +webapp +sessions + +[lib] +lib/hazelcast/*.jar +lib/jetty-hazelcast-session-manager-${jetty.version}.jar + +[xml] +etc/sessions/hazelcast/session-store.xml + +[license] +Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license. +http://hazelcast.org/ +http://www.apache.org/licenses/LICENSE-2.0.html + +[ini] +## Hide the hazelcast libraries from deployed webapps +jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/hazelcast/ + +[ini-template] + +## Hazelcast Session config +#jetty.session.gracePeriod.seconds=3600 +# FIXME add some configuration diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java new file mode 100644 index 00000000000..9aaccaf21b2 --- /dev/null +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java @@ -0,0 +1,211 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.hazelcast.session; + +import com.hazelcast.core.HazelcastInstance; +import com.hazelcast.core.IMap; +import org.eclipse.jetty.server.session.AbstractSessionDataStore; +import org.eclipse.jetty.server.session.SessionContext; +import org.eclipse.jetty.server.session.SessionData; +import org.eclipse.jetty.server.session.SessionDataMap; +import org.eclipse.jetty.server.session.SessionDataStore; +import org.eclipse.jetty.util.annotation.ManagedObject; +import org.eclipse.jetty.util.component.AbstractLifeCycle; +import org.eclipse.jetty.util.log.Log; +import org.eclipse.jetty.util.log.Logger; + +import java.util.Collections; +import java.util.Set; +import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; + +/** + * Session data stored in Hazelcast + */ +@ManagedObject +public class HazelcastSessionDataStore + extends AbstractSessionDataStore + implements SessionDataStore +{ + + private final static Logger LOG = Log.getLogger( "org.eclipse.jetty.server.session"); + + private HazelcastInstance hazelcastInstance; + + private String jettySessionMapName; + + private IMap sessionDataMap; + + public HazelcastSessionDataStore() + { + // no op + } + + public HazelcastSessionDataStore( HazelcastInstance hazelcastInstance, String jettySessionMapName ) + { + this.hazelcastInstance = hazelcastInstance; + this.jettySessionMapName = jettySessionMapName; + this.sessionDataMap = hazelcastInstance.getMap( getJettySessionMapName() ); + } + + public HazelcastInstance getHazelcastInstance() + { + return hazelcastInstance; + } + + public void setHazelcastInstance( HazelcastInstance hazelcastInstance ) + { + this.hazelcastInstance = hazelcastInstance; + } + + public String getJettySessionMapName() + { + return jettySessionMapName; + } + + public void setJettySessionMapName( String jettySessionMapName ) + { + this.jettySessionMapName = jettySessionMapName; + } + + + @Override + public SessionData load( String id ) + throws Exception + { + return sessionDataMap == null ? null : sessionDataMap.get( id ); + } + + @Override + public boolean delete( String id ) + throws Exception + { + return sessionDataMap == null ? false : sessionDataMap.remove( id ) != null; + } + + @Override + public void initialize( SessionContext context ) + throws Exception + { + _context = context; + if (this.sessionDataMap == null) + { + this.sessionDataMap = getHazelcastInstance().getMap( getJettySessionMapName() ); + } + } + + @Override + public void store( String id, SessionData data ) + throws Exception + { + this.sessionDataMap.put( id, data ); + } + + @Override + public void doStore( String id, SessionData data, long lastSaveTime ) + throws Exception + { + this.sessionDataMap.put( id, data); + } + + @Override + public boolean isPassivating() + { + return false; + } + + @Override + public Set doGetExpired( Set candidates ) + { + if (candidates == null || candidates.isEmpty()) + { + return Collections.emptySet(); + } + long now = System.currentTimeMillis(); + return candidates.stream().filter( candidate -> { + if (LOG.isDebugEnabled()) + { + LOG.debug( "Checking expiry for candidate {}", candidate ); + } + try + { + SessionData sd = load(candidate); + + //if the session no longer exists + if (sd == null) + { + if (LOG.isDebugEnabled()) + { + LOG.debug( "Session {} does not exist in infinispan", candidate ); + } + return true; + } + else + { + if (_context.getWorkerName().equals(sd.getLastNode())) + { + //we are its manager, add it to the expired set if it is expired now + if ((sd.getExpiry() > 0 ) && sd.getExpiry() <= now) + { + if (LOG.isDebugEnabled()) + { + LOG.debug( "Session {} managed by {} is expired", candidate, _context.getWorkerName() ); + } + return true; + } + } + else + { + //if we are not the session's manager, only expire it iff: + // this is our first expiryCheck and the session expired a long time ago + //or + //the session expired at least one graceperiod ago + if (_lastExpiryCheckTime <=0) + { + if ((sd.getExpiry() > 0 ) && sd.getExpiry() < (now - (1000L * (3 * _gracePeriodSec)))) + { + return true; + } + } + else + { + if ((sd.getExpiry() > 0 ) && sd.getExpiry() < (now - (1000L * _gracePeriodSec))) + { + return true; + } + } + } + } + } + catch (Exception e) + { + LOG.warn("Error checking if candidate {} is expired so expire it", candidate, e); + return true; + } + return false; + } ).collect( Collectors.toSet() ); + } + + @Override + public boolean exists( String id ) + throws Exception + { + return this.sessionDataMap.containsKey( id ); + } +} diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java new file mode 100644 index 00000000000..874ada29f1f --- /dev/null +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java @@ -0,0 +1,176 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.hazelcast.session; + +import com.hazelcast.client.HazelcastClient; +import com.hazelcast.client.config.ClientConfig; +import com.hazelcast.client.config.XmlClientConfigBuilder; +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.config.XmlConfigBuilder; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory; +import org.eclipse.jetty.server.session.SessionDataMap; +import org.eclipse.jetty.server.session.SessionDataStore; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.eclipse.jetty.server.session.SessionHandler; + +import java.io.IOException; + +/** + * Factory to construct {@link HazelcastSessionDataStore} + */ +public class HazelcastSessionDataStoreFactory + extends AbstractSessionDataStoreFactory + implements SessionDataStoreFactory +{ + + public static final String DEFAULT_HAZELCAST_INSTANCE_NAME = "JETTY_DISTRIBUTED_SESSION_INSTANCE"; + + public static final String DEFAULT_HAZELCAST_MAP_NAME = "jetty-distributed-session-map"; + + private boolean onlyClient; + + private String configurationLocation; + + private String jettySessionMapName = DEFAULT_HAZELCAST_MAP_NAME; + + private HazelcastInstance hazelcastInstance; + + private MapConfig mapConfig; + + + @Override + public SessionDataStore getSessionDataStore( SessionHandler handler ) + throws Exception + { + HazelcastSessionDataStore hazelcastSessionDataStore = new HazelcastSessionDataStore(); + + if ( hazelcastInstance == null ) + { + try + { + if ( onlyClient ) + { + if ( configurationLocation == null ) + { + hazelcastSessionDataStore.setHazelcastInstance( + HazelcastClient.newHazelcastClient( new ClientConfig() ) ); + } + else + { + hazelcastSessionDataStore.setHazelcastInstance( HazelcastClient.newHazelcastClient( + new XmlClientConfigBuilder( configurationLocation ).build() ) ); + } + + } + else + { + Config config; + if ( configurationLocation == null ) + { + config = new Config(); + // configure a default Map if null + if ( mapConfig == null ) + { + mapConfig = new MapConfig(); + mapConfig.setName( jettySessionMapName ); + } + else + { + // otherwise we reuse the name + jettySessionMapName = mapConfig.getName(); + } + config.addMapConfig( mapConfig ); + } + else + { + config = new XmlConfigBuilder( configurationLocation ).build(); + } + config.setInstanceName( DEFAULT_HAZELCAST_INSTANCE_NAME ); + hazelcastSessionDataStore.setHazelcastInstance( Hazelcast.getOrCreateHazelcastInstance( config ) ); + } + } + catch ( IOException e ) + { + throw new RuntimeException( e.getMessage(), e ); + } + } + else + { + hazelcastSessionDataStore.setHazelcastInstance( hazelcastInstance ); + } + hazelcastSessionDataStore.setJettySessionMapName( jettySessionMapName ); + // initialize the map + hazelcastSessionDataStore.getHazelcastInstance().getMap( jettySessionMapName ); + + return hazelcastSessionDataStore; + } + + public boolean isOnlyClient() + { + return onlyClient; + } + + public void setOnlyClient( boolean onlyClient ) + { + this.onlyClient = onlyClient; + } + + public String getConfigurationLocation() + { + return configurationLocation; + } + + public void setConfigurationLocation( String configurationLocation ) + { + this.configurationLocation = configurationLocation; + } + + public String getJettySessionMapName() + { + return jettySessionMapName; + } + + public void setJettySessionMapName( String jettySessionMapName ) + { + this.jettySessionMapName = jettySessionMapName; + } + + public HazelcastInstance getHazelcastInstance() + { + return hazelcastInstance; + } + + public void setHazelcastInstance( HazelcastInstance hazelcastInstance ) + { + this.hazelcastInstance = hazelcastInstance; + } + + public MapConfig getMapConfig() + { + return mapConfig; + } + + public void setMapConfig( MapConfig mapConfig ) + { + this.mapConfig = mapConfig; + } +} diff --git a/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java b/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java new file mode 100644 index 00000000000..0435d391ae2 --- /dev/null +++ b/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java @@ -0,0 +1,203 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.hazelcast.session; + + +import org.eclipse.jetty.client.HttpClient; +import org.eclipse.jetty.client.api.ContentResponse; +import org.eclipse.jetty.client.api.Request; +import org.eclipse.jetty.server.HttpConnectionFactory; +import org.eclipse.jetty.server.Server; +import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.session.AbstractSessionCache; +import org.eclipse.jetty.server.session.CachingSessionDataStore; +import org.eclipse.jetty.server.session.DefaultSessionCache; +import org.eclipse.jetty.server.session.NullSessionDataStore; +import org.eclipse.jetty.server.session.Session; +import org.eclipse.jetty.server.session.SessionContext; +import org.eclipse.jetty.server.session.SessionData; +import org.eclipse.jetty.server.session.SessionDataMap; +import org.eclipse.jetty.server.session.SessionHandler; +import org.eclipse.jetty.servlet.ServletContextHandler; +import org.eclipse.jetty.servlet.ServletHolder; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.io.PrintWriter; + +import static org.junit.Assert.*; + +public class TestHazelcastSessions +{ + public static class TestServlet + extends HttpServlet + { + + @Override + protected void doGet( HttpServletRequest req, HttpServletResponse resp ) + throws ServletException, IOException + { + String arg = req.getParameter( "action" ); + if ( arg == null ) + { + return; + } + HttpSession s = null; + if ( "set".equals( arg ) ) + { + s = req.getSession( true ); + assertNotNull( s ); + s.setAttribute( "val", req.getParameter( "value" ) ); + } + else if ( "get".equals( arg ) ) + { + s = req.getSession( false ); + System.err.println( "GET: s=" + s + ",id=" + (s != null ? s.getId() : "" ) ); + } + else if ( "del".equals( arg ) ) + { + s = req.getSession(); + assertNotNull( s ); + s.invalidate(); + s = null; + } + + resp.setContentType( "text/html" ); + PrintWriter w = resp.getWriter(); + if ( s == null ) + { + w.write( "No session" ); + } + else + { + w.write( (String) s.getAttribute( "val" ) ); + } + } + + } + + private HazelcastSessionDataStore hazelcastSessionDataStore; + + private Server server; + + private ServerConnector serverConnector; + + String contextPath = "/"; + + @Before + public void initialize() + throws Exception + { + + server = new Server(); + serverConnector = new ServerConnector( server, new HttpConnectionFactory() ); + server.addConnector( serverConnector ); + + ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS ); + context.setContextPath( contextPath ); + context.setResourceBase( System.getProperty( "java.io.tmpdir" ) ); + server.setHandler( context ); + + SessionContext sessionContext = new SessionContext( "foo", null ); + + HazelcastSessionDataStoreFactory hazelcastSessionDataStoreFactory = new HazelcastSessionDataStoreFactory(); + hazelcastSessionDataStore = (HazelcastSessionDataStore) hazelcastSessionDataStoreFactory.getSessionDataStore( + context.getSessionHandler() ); + hazelcastSessionDataStore.initialize( sessionContext ); + + DefaultSessionCache defaultSessionCache = new DefaultSessionCache( context.getSessionHandler() ); + defaultSessionCache.setSessionDataStore( hazelcastSessionDataStore ); + context.getSessionHandler().setSessionCache( defaultSessionCache ); + // Add a test servlet + context.addServlet( new ServletHolder( new TestServlet() ), contextPath ); + + server.start(); + } + + @After + public void shutdown() + throws Exception + { + hazelcastSessionDataStore.getHazelcastInstance().shutdown(); + server.stop(); + } + + @Test + public void testHazelcast() + throws Exception + { + + int port = serverConnector.getLocalPort(); + HttpClient client = new HttpClient(); + client.start(); + try + { + int value = 42; + ContentResponse response = + client.GET( "http://localhost:" + port + contextPath + "?action=set&value=" + value ); + assertEquals( HttpServletResponse.SC_OK, response.getStatus() ); + String sessionCookie = response.getHeaders().get( "Set-Cookie" ); + assertTrue( sessionCookie != null ); + // Mangle the cookie, replacing Path with $Path, etc. + sessionCookie = sessionCookie.replaceFirst( "(\\W)(P|p)ath=", "$1\\$Path=" ); + + String resp = response.getContentAsString(); + assertEquals( resp.trim(), String.valueOf( value ) ); + + // Be sure the session value is still there + Request request = client.newRequest( "http://localhost:" + port + contextPath + "?action=get" ); + request.header( "Cookie", sessionCookie ); + response = request.send(); + assertEquals( HttpServletResponse.SC_OK, response.getStatus() ); + + resp = response.getContentAsString(); + assertEquals( String.valueOf( value ), resp.trim() ); + + //Delete the session + request = client.newRequest( "http://localhost:" + port + contextPath + "?action=del" ); + request.header( "Cookie", sessionCookie ); + response = request.send(); + assertEquals( HttpServletResponse.SC_OK, response.getStatus() ); + + //Check that the session is gone + request = client.newRequest( "http://localhost:" + port + contextPath + "?action=get" ); + request.header( "Cookie", sessionCookie ); + response = request.send(); + assertEquals( HttpServletResponse.SC_OK, response.getStatus() ); + resp = response.getContentAsString(); + assertEquals( "No session", resp.trim() ); + + + + } + finally + { + client.stop(); + } + + } + +} diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index ec37181e6e7..177475eeeeb 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -562,6 +562,11 @@ jetty-infinispan ${project.version} + + org.eclipse.jetty + jetty-hazelcast + ${project.version} + org.eclipse.jetty.gcloud jetty-gcloud-session-manager diff --git a/pom.xml b/pom.xml index 60e1000d768..4b7b68f15f6 100644 --- a/pom.xml +++ b/pom.xml @@ -79,6 +79,7 @@ jetty-infinispan jetty-gcloud jetty-memcached + jetty-hazelcast jetty-unixsocket tests examples diff --git a/tests/test-sessions/pom.xml b/tests/test-sessions/pom.xml index 281f705d55d..962172f91c5 100644 --- a/tests/test-sessions/pom.xml +++ b/tests/test-sessions/pom.xml @@ -21,5 +21,6 @@ test-infinispan-sessions test-gcloud-sessions test-memcached-sessions + test-hazelcast-sessions diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml new file mode 100644 index 00000000000..8f357e30ba4 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -0,0 +1,94 @@ + + + 4.0.0 + + org.eclipse.jetty.tests + test-sessions-parent + 9.4.6-SNAPSHOT + + test-hazelcast-sessions + Jetty Tests :: Sessions :: Hazelcast + http://www.eclipse.org/jetty + + ${project.groupId}.sessions.hazelcast + + + + + org.apache.maven.plugins + maven-deploy-plugin + + + true + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + generate-test-resources + + unpack + + + + + org.eclipse.jetty.toolchain + jetty-test-policy + ${jetty-test-policy-version} + jar + true + **/*.keystore,**/*.pem + ${jetty.test.policy.loc} + + + + + + + + + + + org.eclipse.jetty + jetty-server + ${project.version} + + + org.eclipse.jetty + jetty-webapp + ${project.version} + + + org.eclipse.jetty + jetty-client + ${project.version} + + + org.eclipse.jetty.tests + test-sessions-common + ${project.version} + + + org.eclipse.jetty + jetty-hazelcast + ${project.version} + + + org.eclipse.jetty + jetty-jmx + ${project.version} + true + + + org.eclipse.jetty.toolchain + jetty-test-helper + test + + + + + diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredLastAccessTimeTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredLastAccessTimeTest.java new file mode 100644 index 00000000000..aabffb8dfda --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredLastAccessTimeTest.java @@ -0,0 +1,38 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractClusteredLastAccessTimeTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +public class ClusteredLastAccessTimeTest + extends AbstractClusteredLastAccessTimeTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java new file mode 100644 index 00000000000..e5a0be0a09a --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredOrphanedSessionTest.java @@ -0,0 +1,44 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractClusteredOrphanedSessionTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +/** + * ClusteredOrphanedSessionTest + */ +public class ClusteredOrphanedSessionTest + extends AbstractClusteredOrphanedSessionTest +{ + + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } + + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionMigrationTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionMigrationTest.java new file mode 100644 index 00000000000..b6a310f22ff --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionMigrationTest.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractClusteredSessionMigrationTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +/** + * ClusteredSessionMigrationTest + */ +public class ClusteredSessionMigrationTest + extends AbstractClusteredSessionMigrationTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java new file mode 100644 index 00000000000..0d626c33fa7 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ClusteredSessionScavengingTest.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractClusteredSessionScavengingTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +/** + * ClusteredSessionScavengingTest + */ +public class ClusteredSessionScavengingTest + extends AbstractClusteredSessionScavengingTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ModifyMaxInactiveIntervalTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ModifyMaxInactiveIntervalTest.java new file mode 100644 index 00000000000..5570d0946ba --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/ModifyMaxInactiveIntervalTest.java @@ -0,0 +1,42 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +/** + * ModifyMaxInactiveIntervalTest + */ +public class ModifyMaxInactiveIntervalTest + extends AbstractModifyMaxInactiveIntervalTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/NonClusteredSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/NonClusteredSessionScavengingTest.java new file mode 100644 index 00000000000..8c024268b0f --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/NonClusteredSessionScavengingTest.java @@ -0,0 +1,69 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +import static org.junit.Assert.*; + +/** + * NonClusteredSessionScavengingTest + */ +public class NonClusteredSessionScavengingTest + extends AbstractNonClusteredSessionScavengingTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean) + */ + @Override + public void assertSession( String id, boolean exists ) + { + assertNotNull( _dataStore ); + + try + { + boolean inmap = _dataStore.exists( id ); + if ( exists ) + { + assertTrue( inmap ); + } + else + { + assertFalse( inmap ); + } + } + catch ( Exception e ) + { + fail( e.getMessage() ); + } + } + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionExpiryTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionExpiryTest.java new file mode 100644 index 00000000000..ae911a0614b --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionExpiryTest.java @@ -0,0 +1,40 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractSessionExpiryTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.Test; + +public class SessionExpiryTest + extends AbstractSessionExpiryTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionInvalidateCreateScavengeTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionInvalidateCreateScavengeTest.java new file mode 100644 index 00000000000..c958fb6e6c5 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/SessionInvalidateCreateScavengeTest.java @@ -0,0 +1,41 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session; + +import org.eclipse.jetty.server.session.AbstractSessionInvalidateCreateScavengeTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +/** + * SessionInvalidateCreateScavengeTest + */ +public class SessionInvalidateCreateScavengeTest + extends AbstractSessionInvalidateCreateScavengeTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java new file mode 100644 index 00000000000..57740fd92be --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java @@ -0,0 +1,68 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + +package org.eclipse.jetty.hazelcast.session.client; + +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractClusteredLastAccessTimeTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.After; +import org.junit.Before; + +public class ClientLastAccessTimeTest + extends AbstractClusteredLastAccessTimeTest +{ + + private static final String MAP_NAME = "jetty_foo_session"; + + private HazelcastInstance hazelcastInstance; + + @Before + public void startHazelcast() + throws Exception + { + Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) // + .setInstanceName( "beer" ); + // start Hazelcast instance + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); + } + + @After + public void stopHazelcast() + throws Exception + { + hazelcastInstance.shutdown(); + } + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + factory.setOnlyClient( true ); + factory.setJettySessionMapName( MAP_NAME ); + return factory; + } + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientModifyMaxInactiveIntervalTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientModifyMaxInactiveIntervalTest.java new file mode 100644 index 00000000000..f74d05746c9 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientModifyMaxInactiveIntervalTest.java @@ -0,0 +1,43 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session.client; + +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; + +/** + * ModifyMaxInactiveIntervalTest + */ +public class ClientModifyMaxInactiveIntervalTest + extends AbstractModifyMaxInactiveIntervalTest +{ + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + return factory; + } + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java new file mode 100644 index 00000000000..2e925837404 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java @@ -0,0 +1,96 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session.client; + +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.After; +import org.junit.Before; + +import static org.junit.Assert.*; + +public class ClientNonClusteredSessionScavengingTest + extends AbstractNonClusteredSessionScavengingTest +{ + + /** + * @see AbstractNonClusteredSessionScavengingTest#assertSession(String, boolean) + */ + @Override + public void assertSession( String id, boolean exists ) + { + assertNotNull( _dataStore ); + + try + { + boolean inmap = _dataStore.exists( id ); + if ( exists ) + { + assertTrue( inmap ); + } + else + { + assertFalse( inmap ); + } + } + catch ( Exception e ) + { + fail( e.getMessage() ); + } + } + private static final String MAP_NAME = "jetty_foo_session"; + + private HazelcastInstance hazelcastInstance; + + @Before + public void startHazelcast() + throws Exception + { + Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) // + .setInstanceName( "beer" ); + // start Hazelcast instance + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); + } + + @After + public void stopHazelcast() + throws Exception + { + hazelcastInstance.shutdown(); + } + + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + factory.setOnlyClient( true ); + factory.setJettySessionMapName( MAP_NAME ); + return factory; + } +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java new file mode 100644 index 00000000000..8ce86855918 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java @@ -0,0 +1,69 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session.client; + +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractClusteredOrphanedSessionTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.After; +import org.junit.Before; + +public class ClientOrphanedSessionTest + extends AbstractClusteredOrphanedSessionTest +{ + + private static final String MAP_NAME = "jetty_foo_session"; + + private HazelcastInstance hazelcastInstance; + + @Before + public void startHazelcast() + throws Exception + { + Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) // + .setInstanceName( "beer" ); + // start Hazelcast instance + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); + } + + @After + public void stopHazelcast() + throws Exception + { + hazelcastInstance.shutdown(); + } + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + factory.setOnlyClient( true ); + factory.setJettySessionMapName( MAP_NAME ); + return factory; + } + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java new file mode 100644 index 00000000000..57f0e4a7496 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java @@ -0,0 +1,71 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session.client; + +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractSessionExpiryTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +public class ClientSessionExpiryTest + extends AbstractSessionExpiryTest +{ + + private static final String MAP_NAME = "jetty_foo_session"; + + private HazelcastInstance hazelcastInstance; + + @Before + public void startHazelcast() + throws Exception + { + Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) // + .setInstanceName( "beer" ); + // start Hazelcast instance + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); + } + + @After + public void stopHazelcast() + throws Exception + { + hazelcastInstance.shutdown(); + } + + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + factory.setOnlyClient( true ); + factory.setJettySessionMapName( MAP_NAME ); + return factory; + } + +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java new file mode 100644 index 00000000000..b07e3f90d3e --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java @@ -0,0 +1,68 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session.client; + +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractSessionInvalidateCreateScavengeTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.After; +import org.junit.Before; + +public class ClientSessionInvalidateCreateScavengeTest + extends AbstractSessionInvalidateCreateScavengeTest +{ + private static final String MAP_NAME = "jetty_foo_session"; + + private HazelcastInstance hazelcastInstance; + + @Before + public void startHazelcast() + throws Exception + { + Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) // + .setInstanceName( "beer" ); + // start Hazelcast instance + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); + } + + @After + public void stopHazelcast() + throws Exception + { + hazelcastInstance.shutdown(); + } + + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + factory.setOnlyClient( true ); + factory.setJettySessionMapName( MAP_NAME ); + return factory; + } +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java new file mode 100644 index 00000000000..8780c879cbc --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java @@ -0,0 +1,71 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session.client; + +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractClusteredSessionMigrationTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.After; +import org.junit.Before; + +/** + * ClusteredSessionMigrationTest + */ +public class ClientSessionMigrationTest + extends AbstractClusteredSessionMigrationTest +{ + private static final String MAP_NAME = "jetty_foo_session"; + + private HazelcastInstance hazelcastInstance; + + @Before + public void startHazelcast() + throws Exception + { + Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) // + .setInstanceName( "beer" ); + // start Hazelcast instance + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); + } + + @After + public void stopHazelcast() + throws Exception + { + hazelcastInstance.shutdown(); + } + + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + factory.setOnlyClient( true ); + factory.setJettySessionMapName( MAP_NAME ); + return factory; + } +} diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java new file mode 100644 index 00000000000..a452278df03 --- /dev/null +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java @@ -0,0 +1,69 @@ +// +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ------------------------------------------------------------------------ +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== +// + + +package org.eclipse.jetty.hazelcast.session.client; + +import com.hazelcast.config.Config; +import com.hazelcast.config.MapConfig; +import com.hazelcast.core.Hazelcast; +import com.hazelcast.core.HazelcastInstance; +import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory; +import org.eclipse.jetty.server.session.AbstractClusteredSessionScavengingTest; +import org.eclipse.jetty.server.session.SessionDataStoreFactory; +import org.junit.After; +import org.junit.Before; + +public class ClientSessionScavengingTest + extends AbstractClusteredSessionScavengingTest +{ + + private static final String MAP_NAME = "jetty_foo_session"; + + private HazelcastInstance hazelcastInstance; + + @Before + public void startHazelcast() + throws Exception + { + Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) // + .setInstanceName( "beer" ); + // start Hazelcast instance + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); + } + + @After + public void stopHazelcast() + throws Exception + { + hazelcastInstance.shutdown(); + } + + + /** + * @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory() + */ + @Override + public SessionDataStoreFactory createSessionDataStoreFactory() + { + HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); + factory.setOnlyClient( true ); + factory.setJettySessionMapName( MAP_NAME ); + return factory; + } +} From fd972c084810efddde081716ba54bd396a9f629e Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Mon, 29 May 2017 21:42:54 +1000 Subject: [PATCH 02/12] Hazelcast session management #1571 fix modules configuration Signed-off-by: olivier lamy --- jetty-distribution/pom.xml | 2 +- jetty-hazelcast/pom.xml | 87 ++----------------- jetty-hazelcast/src/main/assembly/config.xml | 27 ------ .../etc/sessions/hazelcast/session-store.xml | 18 ---- .../modules/session-store-hazelcast.mod | 36 -------- .../config/etc/sessions/hazelcast/default.xml | 33 +++++++ .../config/etc/sessions/hazelcast/remote.xml | 33 +++++++ .../session-store-hazelcast-embedded.mod | 34 ++++++++ .../session-store-hazelcast-remote.mod | 34 ++++++++ .../HazelcastSessionDataStoreFactory.java | 1 - 10 files changed, 140 insertions(+), 165 deletions(-) delete mode 100644 jetty-hazelcast/src/main/assembly/config.xml delete mode 100644 jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml delete mode 100644 jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod create mode 100644 jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml create mode 100644 jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml create mode 100644 jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod create mode 100644 jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod diff --git a/jetty-distribution/pom.xml b/jetty-distribution/pom.xml index 85944abf063..3df837a0f44 100644 --- a/jetty-distribution/pom.xml +++ b/jetty-distribution/pom.xml @@ -51,7 +51,7 @@ maven-antrun-plugin - popluate distribution from home + populate distribution from home process-resources run diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index d5062f6d23b..bc24e821994 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -2,8 +2,8 @@ - jetty-project org.eclipse.jetty + jetty-project 9.4.6-SNAPSHOT @@ -13,7 +13,7 @@ 3.8.2 - ${project.groupId}.session + ${project.groupId}.hazelcast @@ -65,83 +65,6 @@ - - org.apache.felix - maven-bundle-plugin - true - - - - manifest - - - - - org.eclipse.jetty.hazelcast.session.*;version="${parsedVersion.majorVersion}.${parsedVersion.minorVersion}.${parsedVersion.incrementalVersion}"; - - - - - - - - org.apache.maven.plugins - maven-dependency-plugin - - - build-deps-file - generate-resources - - list - - - false - ${project.build.directory}/deps.txt - true - org.eclipse.jetty - true - runtime - - - - - - org.apache.maven.plugins - maven-antrun-plugin - - - process-deps - process-resources - - run - - - - - - - - - process-mod - process-resources - - run - - - - - - - - - - - - - org.apache.maven.plugins maven-assembly-plugin @@ -152,9 +75,9 @@ single - - src/main/assembly/config.xml - + + config + diff --git a/jetty-hazelcast/src/main/assembly/config.xml b/jetty-hazelcast/src/main/assembly/config.xml deleted file mode 100644 index 45e740841f1..00000000000 --- a/jetty-hazelcast/src/main/assembly/config.xml +++ /dev/null @@ -1,27 +0,0 @@ - - - config - false - - jar - - - - src/main/config-template - - - ** - - - **/session-store-hazelcast.mod - - - - target - modules - - session-store-hazelcast.mod - - - - diff --git a/jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml b/jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml deleted file mode 100644 index ecd6efb1ea0..00000000000 --- a/jetty-hazelcast/src/main/config-template/etc/sessions/hazelcast/session-store.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod b/jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod deleted file mode 100644 index 5b70060bf23..00000000000 --- a/jetty-hazelcast/src/main/config-template/modules/session-store-hazelcast.mod +++ /dev/null @@ -1,36 +0,0 @@ -[description] -Enables Hazelcast session management. - -[tags] -session -hazelcast - -[provides] -session-store - -[depends] -annotations -webapp -sessions - -[lib] -lib/hazelcast/*.jar -lib/jetty-hazelcast-session-manager-${jetty.version}.jar - -[xml] -etc/sessions/hazelcast/session-store.xml - -[license] -Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license. -http://hazelcast.org/ -http://www.apache.org/licenses/LICENSE-2.0.html - -[ini] -## Hide the hazelcast libraries from deployed webapps -jetty.webapp.addServerClasses+=,${jetty.base.uri}/lib/hazelcast/ - -[ini-template] - -## Hazelcast Session config -#jetty.session.gracePeriod.seconds=3600 -# FIXME add some configuration diff --git a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml new file mode 100644 index 00000000000..435b738c8c7 --- /dev/null +++ b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml new file mode 100644 index 00000000000..435b738c8c7 --- /dev/null +++ b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod new file mode 100644 index 00000000000..3d89eabbfc1 --- /dev/null +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod @@ -0,0 +1,34 @@ +[description] +Enables session data store in an embedded Hazelcast Map + +[tags] +session + +[provides] +session-store + +[depend] +sessions + +[files] +maven://com.hazelcast/hazelcast/3.8.2|lib/hazelcast/hazelcast-3.8.2.jar +maven://com.hazelcast/hazelcast-client/3.8.2|lib/hazelcast/hazelcast-client-3.8.2.jar + +[xml] +etc/sessions/hazelcast/default.xml + +[lib] +lib/jetty-hazelcast-${jetty.version}.jar +lib/hazelcast/*.jar + +[license] +Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license. +https://hazelcast.org/ +http://www.apache.org/licenses/LICENSE-2.0.html + + +[ini-template] +#jetty.session.hazelcast.jettySessionMapName=jetty_sessions +#jetty.session.hazelcast.configurationLocation= +#jetty.session.gracePeriod.seconds=3600 +#jetty.session.savePeriod.seconds=0 \ No newline at end of file diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod new file mode 100644 index 00000000000..cae1e561882 --- /dev/null +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod @@ -0,0 +1,34 @@ +[description] +Enables session data store in a remote Hazelcast Map + +[tags] +session + +[provides] +session-store + +[depend] +sessions + +[files] +maven://com.hazelcast/hazelcast/3.8.2|lib/hazelcast/hazelcast-3.8.2.jar +maven://com.hazelcast/hazelcast-client/3.8.2|lib/hazelcast/hazelcast-client-3.8.2.jar + +[xml] +etc/sessions/hazelcast/remote.xml + +[lib] +lib/jetty-hazelcast-${jetty.version}.jar +lib/hazelcast/*.jar + +[license] +Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license. + https://hazelcast.org/ +http://www.apache.org/licenses/LICENSE-2.0.html + + +[ini-template] +#jetty.session.hazelcast.jettySessionMapName=jetty_sessions +#jetty.session.hazelcast.onlyClient=true +#jetty.session.gracePeriod.seconds=3600 +#jetty.session.savePeriod.seconds=0 \ No newline at end of file diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java index 874ada29f1f..2dcbbb77a7c 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java @@ -27,7 +27,6 @@ import com.hazelcast.config.XmlConfigBuilder; import com.hazelcast.core.Hazelcast; import com.hazelcast.core.HazelcastInstance; import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory; -import org.eclipse.jetty.server.session.SessionDataMap; import org.eclipse.jetty.server.session.SessionDataStore; import org.eclipse.jetty.server.session.SessionDataStoreFactory; import org.eclipse.jetty.server.session.SessionHandler; From 98f8405771fc6f035b01347787c69229a75c8c03 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Wed, 31 May 2017 21:35:58 +1000 Subject: [PATCH 03/12] add documentation page for Hazelcast session management #1571 Signed-off-by: olivier lamy --- .../session-configuration-hazelcast.adoc | 184 ++++++++++++++++++ .../session-store-hazelcast-remote.mod | 1 + 2 files changed, 185 insertions(+) create mode 100644 jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc new file mode 100644 index 00000000000..f7dab8ede0a --- /dev/null +++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc @@ -0,0 +1,184 @@ +// ======================================================================== +// Copyright (c) 1995-2017 Mort Bay Consulting Pty. Ltd. +// ======================================================================== +// All rights reserved. This program and the accompanying materials +// are made available under the terms of the Eclipse Public License v1.0 +// and Apache License v2.0 which accompanies this distribution. +// +// The Eclipse Public License is available at +// http://www.eclipse.org/legal/epl-v10.html +// +// The Apache License v2.0 is available at +// http://www.opensource.org/licenses/apache2.0.php +// +// You may elect to redistribute this code under either of these licenses. +// ======================================================================== + +[[configuring-sessions-hazelcast]] + +=== Clustered Session Management: Hazelcast + +==== Enabling Hazelcast Sessions + +When using the Jetty distribution, you will first need to enable the `session-store-hazelcast-remote` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line. + +[source, screen, subs="{sub-order}"] +---- +mb-olamy:tmp-base olamy$ java -jar ../start.jar --create-startd +MKDIR : ${jetty.base}/start.d +INFO : Base directory was modified +mb-olamy:tmp-base olamy$ java -jar ../start.jar --add-to-start=session-store-hazelcast-remote + +ALERT: There are enabled module(s) with licenses. +The following 1 module(s): + + contains software not provided by the Eclipse Foundation! + + contains software not covered by the Eclipse Public License! + + has not been audited for compliance with its license + + Module: session-store-hazelcast-remote + + Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license. + + https://hazelcast.org/ + + http://www.apache.org/licenses/LICENSE-2.0.html + +Proceed (y/N)? y +INFO : server transitively enabled, ini template available with --add-to-start=server +INFO : sessions transitively enabled, ini template available with --add-to-start=sessions +INFO : session-store-hazelcast-remote initialized in ${jetty.base}/start.d/session-store-hazelcast-remote.ini +MKDIR : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2 +DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar +MKDIR : ${jetty.base}/lib/hazelcast +COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar +COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar +INFO : Base directory was modified +---- + +Doing this enables the remote Hazelcast Session module and any dependent modules or files needed for it to run on the server. +The example above is using a fresh `${jetty.base}` with nothing else enabled. +Because Hazelcast is not a technology provided by the Eclipse Foundation, users are prompted to assent to the licenses of the external vendor (Apache in this case). + +When the `--add-to-start` argument was added to the command line, it enabled the the `session-store-hazelcast-remote` module as well as the `sessions` and `server` modules, which are required for Hazelcast session management to operate. +It also downloaded the needed Hazelcast-specific jar files and created a directory named `${jetty.base}/lib/hazelcast/` to house them. + +In addition to adding these modules to the classpath of the server it also added several ini configuration files to the `${jetty.base}/start.d` directory. + +____ +[NOTE] +If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=` command line option to prevent errors when starting your server. +____ + +==== Configuring Hazelcast Remote Properties + +Opening the `start.d/session-store-hazelcast-remote.ini` will show a list of all the configurable options for the Hazelcast module: + +[source, screen, subs="{sub-order}"] +---- +# --------------------------------------- +# Module: session-store-hazelcast-remote +# Enables session data store in a remote Hazelcast Map +# --------------------------------------- +--module=session-store-hazelcast-remote + +#jetty.session.hazelcast.jettySessionMapName=jetty_sessions +#jetty.session.hazelcast.onlyClient=true +#jetty.session.hazelcast.configurationLocation= +#jetty.session.gracePeriod.seconds=3600 +#jetty.session.savePeriod.seconds=0 +---- + +jetty.session.hazelcast.jettySessionMapName:: +Name of the Map in Hazelcast where sessions will be stored. +jetty.session.hazelcast.idleTimeout.onlyClient:: +Hazelcast instance will be configured in client mode +jetty.session.hazelcast.configurationLocation:: +Path to an an Hazelcast xml configuration file +jetty.session.gracePeriod.seconds:: +Amount of time, in seconds, to wait for other nodes to be checked to verify an expired session is in fact expired throughout the cluster before closing it. +jetty.session.savePeriod.seconds=0:: +By default whenever the last concurrent request leaves a session, that session is always persisted via the `SessionDataStore`, even if the only thing that changed on the session is its updated last access time. +A non-zero value means that the `SessionDataStore` will skip persisting the session if only the access time changed, and it has been less than `savePeriod` seconds since the last time the session was written. ++ +____ +[NOTE] +Configuring `savePeriod` is useful if your persistence technology is very slow/costly for writes. +In a clustered environment, there is a risk of the last access time of the session being out-of-date in the shared store for up to `savePeriod` seconds. +This allows the possibility that a node may prematurely expire the session, even though it is in use by another node. +Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - there is no point in setting a `savePeriod` that is larger than the `maxIdleTime`. +____ + +==== Configuring Embedded Hazelcast Clustering + +During testing, it can be helpful to run an in-process instance of Hazelcast. +To enable this you will first need to enable the `session-store-hazelcast-embedded` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line. + +[source, screen, subs="{sub-order}"] +---- +mb-olamy:tmp-base olamy$ java -jar ../start.jar --create-startd +MKDIR : ${jetty.base}/start.d +INFO : Base directory was modified +mb-olamy:tmp-base olamy$ java -jar ../start.jar --add-to-start=session-store-hazelcast-embedded + +ALERT: There are enabled module(s) with licenses. +The following 1 module(s): + + contains software not provided by the Eclipse Foundation! + + contains software not covered by the Eclipse Public License! + + has not been audited for compliance with its license + + Module: session-store-hazelcast-embedded + + Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license. + + https://hazelcast.org/ + + http://www.apache.org/licenses/LICENSE-2.0.html + +Proceed (y/N)? y +INFO : server transitively enabled, ini template available with --add-to-start=server +INFO : sessions transitively enabled, ini template available with --add-to-start=sessions +INFO : session-store-hazelcast-embedded initialized in ${jetty.base}/start.d/session-store-hazelcast-embedded.ini +MKDIR : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2 +DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar +MKDIR : ${jetty.base}/lib/hazelcast +COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar +COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar +---- + +Doing this enables the embedded Hazelcast Session module and any dependent modules or files needed for it to run on the server. +The example above is using a fresh `${jetty.base}` with nothing else enabled. +Because Hazelcast is not a technology provided by the Eclipse Foundation, users are prompted to assent to the licenses of the external vendor (Apache in this case). + +When the `--add-to-start` argument was added to the command line, it enabled the the `session-store-hazelcast-embedded` module as well as the `sessions` and `server` modules, which are required for Hazelcast session management to operate. +It also downloaded the needed Hazelcast-specific jar files and created a directory named `${jetty.base}/lib/hazelcast/` to house them. + +In addition to adding these modules to the classpath of the server it also added several ini configuration files to the `${jetty.base}/start.d` directory. + +==== Configuring Hazelcast Embedded Properties + +Opening the `start.d/start.d/session-store-hazelcast-embedded.ini` will show a list of all the configurable options for the Hazelcast module: + +[source, screen, subs="{sub-order}"] +---- +# --------------------------------------- +# Module: session-store-hazelcast-embedded +# Enables session data store in an embedded Hazelcast Map +# --------------------------------------- +--module=session-store-hazelcast-embedded + +#jetty.session.hazelcast.jettySessionMapName=jetty_sessions +#jetty.session.hazelcast.configurationLocation= +#jetty.session.gracePeriod.seconds=3600 +#jetty.session.savePeriod.seconds=0 +---- +jetty.session.hazelcast.jettySessionMapName:: +Name of the Map in Hazelcast where sessions will be stored. +jetty.session.gracePeriod.seconds:: +Amount of time, in seconds, to wait for other nodes to be checked to verify an expired session is in fact expired throughout the cluster before closing it. +jetty.session.hazelcast.configurationLocation:: +Path to an an Hazelcast xml configuration file +jetty.session.savePeriod.seconds=0:: +By default whenever the last concurrent request leaves a session, that session is always persisted via the `SessionDataStore`, even if the only thing that changed on the session is its updated last access time. +A non-zero value means that the `SessionDataStore` will skip persisting the session if only the access time changed, and it has been less than `savePeriod` seconds since the last time the session was written. ++ +____ +[NOTE] +Configuring `savePeriod` is useful if your persistence technology is very slow/costly for writes. +In a clustered environment, there is a risk of the last access time of the session being out-of-date in the shared store for up to `savePeriod` seconds. +This allows the possibility that a node may prematurely expire the session, even though it is in use by another node. +Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - there is no point in setting a `savePeriod` that is larger than the `maxIdleTime`. +____ diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod index cae1e561882..e169f505824 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod @@ -30,5 +30,6 @@ http://www.apache.org/licenses/LICENSE-2.0.html [ini-template] #jetty.session.hazelcast.jettySessionMapName=jetty_sessions #jetty.session.hazelcast.onlyClient=true +#jetty.session.hazelcast.configurationLocation= #jetty.session.gracePeriod.seconds=3600 #jetty.session.savePeriod.seconds=0 \ No newline at end of file From d0ab06478998712db0486172d2db251ac5070811 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Thu, 1 Jun 2017 12:11:49 +1000 Subject: [PATCH 04/12] add entry in chapter.adoc for hazelcast session management #1571 Signed-off-by: olivier lamy --- .../src/main/asciidoc/administration/sessions/chapter.adoc | 1 + 1 file changed, 1 insertion(+) diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc index 88e99e4057f..6f36fb4d379 100644 --- a/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/sessions/chapter.adoc @@ -30,6 +30,7 @@ include::session-configuration-file-system.adoc[] include::session-configuration-jdbc.adoc[] include::session-configuration-mongodb.adoc[] include::session-configuration-infinispan.adoc[] +include::session-configuration-hazelcast.adoc[] include::session-configuration-gcloud.adoc[] //include::setting-session-characteristics.adoc[] //include::using-persistent-sessions.adoc[] From 0c3b3dffcefc845c1d0ca172b41c36e6e25c83a4 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Thu, 1 Jun 2017 14:11:12 +1000 Subject: [PATCH 05/12] revert change for session-configuration-infinispan.adoc. will be part of an other pr Signed-off-by: olivier lamy --- .../sessions/session-configuration-infinispan.adoc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc index f0d92edf3a9..c4cad1f7669 100644 --- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-infinispan.adoc @@ -16,7 +16,7 @@ [[configuring-sessions-infinispan]] -=== Clustered Session Management: Infinispan +=== Clustered Session Management: Inifinspan ==== Enabling Infinispan Sessions @@ -65,9 +65,9 @@ ____ If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=` command line option to prevent errors when starting your server. ____ -==== Configuring Infinispan Remote Properties +==== Configuring Inifinspan Remote Properties -Opening the `start.d/session-store-infinispan-remote.ini` will show a list of all the configurable options for the Infinispan module: +Opening the `start.d/session-store-infinispan-remote.ini` will show a list of all the configurable options for the JDBC module: [source, screen, subs="{sub-order}"] ---- @@ -101,7 +101,7 @@ This allows the possibility that a node may prematurely expire the session, even Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - there is no point in setting a `savePeriod` that is larger than the `maxIdleTime`. ____ -==== Configuring Embedded Infinispan Clustering +==== Configuring Embedded Inifinspan Clustering During testing, it can be helpful to run an in-process instance of Infinispan. To enable this you will first need to enable the `session-store-infinispan-embedded` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line. @@ -140,7 +140,7 @@ In addition to adding these modules to the classpath of the server it also added ==== Configuring Inifinspan Embedded Properties -Opening the `start.d/session-store-infinispan-embedded.ini` will show a list of all the configurable options for the Infinispan module: +Opening the `start.d/session-store-infinispan-remote.ini` will show a list of all the configurable options for the JDBC module: [source, screen, subs="{sub-order}"] ---- From a63e91d3243ba02bc019d71cec4231876fa5335f Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Thu, 1 Jun 2017 16:52:52 +1000 Subject: [PATCH 06/12] apply changes after review #1571 Signed-off-by: olivier lamy --- .../session-configuration-hazelcast.adoc | 10 +- .../config/etc/sessions/hazelcast/default.xml | 20 +--- .../config/etc/sessions/hazelcast/remote.xml | 22 +---- .../session-store-hazelcast-embedded.mod | 7 +- .../session-store-hazelcast-remote.mod | 9 +- .../session/HazelcastSessionDataStore.java | 98 +++++++++---------- .../HazelcastSessionDataStoreFactory.java | 49 +++++----- .../session/TestHazelcastSessions.java | 12 +-- .../client/ClientLastAccessTimeTest.java | 2 +- ...ientNonClusteredSessionScavengingTest.java | 2 +- .../client/ClientOrphanedSessionTest.java | 2 +- .../client/ClientSessionExpiryTest.java | 3 +- ...ntSessionInvalidateCreateScavengeTest.java | 2 +- .../client/ClientSessionMigrationTest.java | 2 +- .../client/ClientSessionScavengingTest.java | 2 +- 15 files changed, 105 insertions(+), 137 deletions(-) diff --git a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc index f7dab8ede0a..a424404e149 100644 --- a/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc +++ b/jetty-documentation/src/main/asciidoc/administration/sessions/session-configuration-hazelcast.adoc @@ -78,16 +78,16 @@ Opening the `start.d/session-store-hazelcast-remote.ini` will show a list of all # --------------------------------------- --module=session-store-hazelcast-remote -#jetty.session.hazelcast.jettySessionMapName=jetty_sessions +#jetty.session.hazelcast.mapName=jetty_sessions #jetty.session.hazelcast.onlyClient=true #jetty.session.hazelcast.configurationLocation= #jetty.session.gracePeriod.seconds=3600 #jetty.session.savePeriod.seconds=0 ---- -jetty.session.hazelcast.jettySessionMapName:: +jetty.session.hazelcast.mapName:: Name of the Map in Hazelcast where sessions will be stored. -jetty.session.hazelcast.idleTimeout.onlyClient:: +jetty.session.hazelcast.onlyClient:: Hazelcast instance will be configured in client mode jetty.session.hazelcast.configurationLocation:: Path to an an Hazelcast xml configuration file @@ -160,12 +160,12 @@ Opening the `start.d/start.d/session-store-hazelcast-embedded.ini` will show a l # --------------------------------------- --module=session-store-hazelcast-embedded -#jetty.session.hazelcast.jettySessionMapName=jetty_sessions +#jetty.session.hazelcast.mapName=jetty_sessions #jetty.session.hazelcast.configurationLocation= #jetty.session.gracePeriod.seconds=3600 #jetty.session.savePeriod.seconds=0 ---- -jetty.session.hazelcast.jettySessionMapName:: +jetty.session.hazelcast.mapName:: Name of the Map in Hazelcast where sessions will be stored. jetty.session.gracePeriod.seconds:: Amount of time, in seconds, to wait for other nodes to be checked to verify an expired session is in fact expired throughout the cluster before closing it. diff --git a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml index 435b738c8c7..680e6f07d3f 100644 --- a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml +++ b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/default.xml @@ -4,14 +4,6 @@ - - - - @@ -19,14 +11,10 @@ - - + + + + diff --git a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml index 435b738c8c7..ca32fcff21d 100644 --- a/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml +++ b/jetty-hazelcast/src/main/config/etc/sessions/hazelcast/remote.xml @@ -3,15 +3,6 @@ - - - - - @@ -19,14 +10,11 @@ - - + + + + + diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod index 3d89eabbfc1..7ce5a83b046 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod @@ -28,7 +28,8 @@ http://www.apache.org/licenses/LICENSE-2.0.html [ini-template] -#jetty.session.hazelcast.jettySessionMapName=jetty_sessions +jetty.session.hazelcast.mapName=jetty-distributed-session-map +jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE #jetty.session.hazelcast.configurationLocation= -#jetty.session.gracePeriod.seconds=3600 -#jetty.session.savePeriod.seconds=0 \ No newline at end of file +jetty.session.gracePeriod.seconds=3600 +jetty.session.savePeriod.seconds=0 \ No newline at end of file diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod index e169f505824..55baa0e3d68 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-remote.mod @@ -28,8 +28,9 @@ http://www.apache.org/licenses/LICENSE-2.0.html [ini-template] -#jetty.session.hazelcast.jettySessionMapName=jetty_sessions -#jetty.session.hazelcast.onlyClient=true +jetty.session.hazelcast.mapName=jetty-distributed-session-map +jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE +jetty.session.hazelcast.onlyClient=true #jetty.session.hazelcast.configurationLocation= -#jetty.session.gracePeriod.seconds=3600 -#jetty.session.savePeriod.seconds=0 \ No newline at end of file +jetty.session.gracePeriod.seconds=3600 +jetty.session.savePeriod.seconds=0 \ No newline at end of file diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java index 9aaccaf21b2..d6f738b98ad 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java @@ -18,21 +18,18 @@ package org.eclipse.jetty.hazelcast.session; -import com.hazelcast.core.HazelcastInstance; import com.hazelcast.core.IMap; import org.eclipse.jetty.server.session.AbstractSessionDataStore; import org.eclipse.jetty.server.session.SessionContext; import org.eclipse.jetty.server.session.SessionData; -import org.eclipse.jetty.server.session.SessionDataMap; import org.eclipse.jetty.server.session.SessionDataStore; import org.eclipse.jetty.util.annotation.ManagedObject; -import org.eclipse.jetty.util.component.AbstractLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; import java.util.Collections; import java.util.Set; -import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import java.util.stream.Collectors; /** @@ -46,10 +43,6 @@ public class HazelcastSessionDataStore private final static Logger LOG = Log.getLogger( "org.eclipse.jetty.server.session"); - private HazelcastInstance hazelcastInstance; - - private String jettySessionMapName; - private IMap sessionDataMap; public HazelcastSessionDataStore() @@ -57,46 +50,53 @@ public class HazelcastSessionDataStore // no op } - public HazelcastSessionDataStore( HazelcastInstance hazelcastInstance, String jettySessionMapName ) - { - this.hazelcastInstance = hazelcastInstance; - this.jettySessionMapName = jettySessionMapName; - this.sessionDataMap = hazelcastInstance.getMap( getJettySessionMapName() ); - } - - public HazelcastInstance getHazelcastInstance() - { - return hazelcastInstance; - } - - public void setHazelcastInstance( HazelcastInstance hazelcastInstance ) - { - this.hazelcastInstance = hazelcastInstance; - } - - public String getJettySessionMapName() - { - return jettySessionMapName; - } - - public void setJettySessionMapName( String jettySessionMapName ) - { - this.jettySessionMapName = jettySessionMapName; - } - - @Override public SessionData load( String id ) throws Exception { - return sessionDataMap == null ? null : sessionDataMap.get( id ); + + final AtomicReference reference = new AtomicReference(); + final AtomicReference exception = new AtomicReference(); + + //ensure the load runs in the context classloader scope + _context.run( () -> { + try + { + if (LOG.isDebugEnabled()) + { + LOG.debug( "Loading session {} from hazelcast", id ); + } + SessionData sd = sessionDataMap.get( getCacheKey( id ) ); + reference.set(sd); + } + catch (Exception e) + { + exception.set(e); + } + } ); + + if (exception.get() != null) + { + throw exception.get(); + } + return reference.get(); } @Override public boolean delete( String id ) throws Exception { - return sessionDataMap == null ? false : sessionDataMap.remove( id ) != null; + return sessionDataMap == null ? false : sessionDataMap.remove( getCacheKey( id ) ) != null; + } + + public IMap getSessionDataMap() + { + return sessionDataMap; + } + + public void setSessionDataMap( IMap sessionDataMap ) + { + this.sessionDataMap = sessionDataMap; } @Override @@ -104,30 +104,19 @@ public class HazelcastSessionDataStore throws Exception { _context = context; - if (this.sessionDataMap == null) - { - this.sessionDataMap = getHazelcastInstance().getMap( getJettySessionMapName() ); - } - } - - @Override - public void store( String id, SessionData data ) - throws Exception - { - this.sessionDataMap.put( id, data ); } @Override public void doStore( String id, SessionData data, long lastSaveTime ) throws Exception { - this.sessionDataMap.put( id, data); + this.sessionDataMap.put( getCacheKey( id ), data); } @Override public boolean isPassivating() { - return false; + return true; } @Override @@ -206,6 +195,11 @@ public class HazelcastSessionDataStore public boolean exists( String id ) throws Exception { - return this.sessionDataMap.containsKey( id ); + return this.sessionDataMap.containsKey( getCacheKey( id ) ); + } + + public String getCacheKey( String id ) + { + return _context.getCanonicalContextPath() + "_" + _context.getVhost() + "_" + id; } } diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java index 2dcbbb77a7c..7959f8a5072 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreFactory.java @@ -41,15 +41,13 @@ public class HazelcastSessionDataStoreFactory implements SessionDataStoreFactory { - public static final String DEFAULT_HAZELCAST_INSTANCE_NAME = "JETTY_DISTRIBUTED_SESSION_INSTANCE"; - - public static final String DEFAULT_HAZELCAST_MAP_NAME = "jetty-distributed-session-map"; + private String hazelcastInstanceName = "JETTY_DISTRIBUTED_SESSION_INSTANCE"; private boolean onlyClient; private String configurationLocation; - private String jettySessionMapName = DEFAULT_HAZELCAST_MAP_NAME; + private String mapName = "jetty-distributed-session-map"; private HazelcastInstance hazelcastInstance; @@ -70,13 +68,12 @@ public class HazelcastSessionDataStoreFactory { if ( configurationLocation == null ) { - hazelcastSessionDataStore.setHazelcastInstance( - HazelcastClient.newHazelcastClient( new ClientConfig() ) ); + hazelcastInstance = HazelcastClient.newHazelcastClient( new ClientConfig() ); } else { - hazelcastSessionDataStore.setHazelcastInstance( HazelcastClient.newHazelcastClient( - new XmlClientConfigBuilder( configurationLocation ).build() ) ); + hazelcastInstance = HazelcastClient.newHazelcastClient( + new XmlClientConfigBuilder( configurationLocation ).build() ); } } @@ -90,12 +87,12 @@ public class HazelcastSessionDataStoreFactory if ( mapConfig == null ) { mapConfig = new MapConfig(); - mapConfig.setName( jettySessionMapName ); + mapConfig.setName( mapName ); } else { // otherwise we reuse the name - jettySessionMapName = mapConfig.getName(); + mapName = mapConfig.getName(); } config.addMapConfig( mapConfig ); } @@ -103,8 +100,8 @@ public class HazelcastSessionDataStoreFactory { config = new XmlConfigBuilder( configurationLocation ).build(); } - config.setInstanceName( DEFAULT_HAZELCAST_INSTANCE_NAME ); - hazelcastSessionDataStore.setHazelcastInstance( Hazelcast.getOrCreateHazelcastInstance( config ) ); + config.setInstanceName( hazelcastInstanceName ); + hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config ); } } catch ( IOException e ) @@ -112,14 +109,10 @@ public class HazelcastSessionDataStoreFactory throw new RuntimeException( e.getMessage(), e ); } } - else - { - hazelcastSessionDataStore.setHazelcastInstance( hazelcastInstance ); - } - hazelcastSessionDataStore.setJettySessionMapName( jettySessionMapName ); // initialize the map - hazelcastSessionDataStore.getHazelcastInstance().getMap( jettySessionMapName ); - + hazelcastSessionDataStore.setSessionDataMap(hazelcastInstance.getMap( mapName ) ); + hazelcastSessionDataStore.setGracePeriodSec( getGracePeriodSec() ); + hazelcastSessionDataStore.setSavePeriodSec( getSavePeriodSec() ); return hazelcastSessionDataStore; } @@ -143,14 +136,14 @@ public class HazelcastSessionDataStoreFactory this.configurationLocation = configurationLocation; } - public String getJettySessionMapName() + public String getMapName() { - return jettySessionMapName; + return mapName; } - public void setJettySessionMapName( String jettySessionMapName ) + public void setMapName( String mapName ) { - this.jettySessionMapName = jettySessionMapName; + this.mapName = mapName; } public HazelcastInstance getHazelcastInstance() @@ -172,4 +165,14 @@ public class HazelcastSessionDataStoreFactory { this.mapConfig = mapConfig; } + + public String getHazelcastInstanceName() + { + return hazelcastInstanceName; + } + + public void setHazelcastInstanceName( String hazelcastInstanceName ) + { + this.hazelcastInstanceName = hazelcastInstanceName; + } } diff --git a/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java b/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java index 0435d391ae2..8164892b070 100644 --- a/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java +++ b/jetty-hazelcast/src/test/java/org/eclipse/jetty/hazelcast/session/TestHazelcastSessions.java @@ -25,15 +25,8 @@ import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.session.AbstractSessionCache; -import org.eclipse.jetty.server.session.CachingSessionDataStore; import org.eclipse.jetty.server.session.DefaultSessionCache; -import org.eclipse.jetty.server.session.NullSessionDataStore; -import org.eclipse.jetty.server.session.Session; import org.eclipse.jetty.server.session.SessionContext; -import org.eclipse.jetty.server.session.SessionData; -import org.eclipse.jetty.server.session.SessionDataMap; -import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.junit.After; @@ -100,6 +93,7 @@ public class TestHazelcastSessions } private HazelcastSessionDataStore hazelcastSessionDataStore; + private HazelcastSessionDataStoreFactory hazelcastSessionDataStoreFactory; private Server server; @@ -123,7 +117,7 @@ public class TestHazelcastSessions SessionContext sessionContext = new SessionContext( "foo", null ); - HazelcastSessionDataStoreFactory hazelcastSessionDataStoreFactory = new HazelcastSessionDataStoreFactory(); + hazelcastSessionDataStoreFactory = new HazelcastSessionDataStoreFactory(); hazelcastSessionDataStore = (HazelcastSessionDataStore) hazelcastSessionDataStoreFactory.getSessionDataStore( context.getSessionHandler() ); hazelcastSessionDataStore.initialize( sessionContext ); @@ -141,7 +135,7 @@ public class TestHazelcastSessions public void shutdown() throws Exception { - hazelcastSessionDataStore.getHazelcastInstance().shutdown(); + hazelcastSessionDataStoreFactory.getHazelcastInstance().shutdown(); server.stop(); } diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java index 57740fd92be..2078882ee21 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientLastAccessTimeTest.java @@ -61,7 +61,7 @@ public class ClientLastAccessTimeTest { HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); factory.setOnlyClient( true ); - factory.setJettySessionMapName( MAP_NAME ); + factory.setMapName( MAP_NAME ); return factory; } diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java index 2e925837404..e9b00f20433 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientNonClusteredSessionScavengingTest.java @@ -90,7 +90,7 @@ public class ClientNonClusteredSessionScavengingTest { HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); factory.setOnlyClient( true ); - factory.setJettySessionMapName( MAP_NAME ); + factory.setMapName( MAP_NAME ); return factory; } } diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java index 8ce86855918..00943a5f036 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientOrphanedSessionTest.java @@ -62,7 +62,7 @@ public class ClientOrphanedSessionTest { HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); factory.setOnlyClient( true ); - factory.setJettySessionMapName( MAP_NAME ); + factory.setMapName( MAP_NAME ); return factory; } diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java index 57f0e4a7496..4533b980d8a 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionExpiryTest.java @@ -28,7 +28,6 @@ import org.eclipse.jetty.server.session.AbstractSessionExpiryTest; import org.eclipse.jetty.server.session.SessionDataStoreFactory; import org.junit.After; import org.junit.Before; -import org.junit.Test; public class ClientSessionExpiryTest extends AbstractSessionExpiryTest @@ -64,7 +63,7 @@ public class ClientSessionExpiryTest { HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); factory.setOnlyClient( true ); - factory.setJettySessionMapName( MAP_NAME ); + factory.setMapName( MAP_NAME ); return factory; } diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java index b07e3f90d3e..1219907e689 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionInvalidateCreateScavengeTest.java @@ -62,7 +62,7 @@ public class ClientSessionInvalidateCreateScavengeTest { HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); factory.setOnlyClient( true ); - factory.setJettySessionMapName( MAP_NAME ); + factory.setMapName( MAP_NAME ); return factory; } } diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java index 8780c879cbc..e5dc2cc1a9a 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionMigrationTest.java @@ -65,7 +65,7 @@ public class ClientSessionMigrationTest { HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); factory.setOnlyClient( true ); - factory.setJettySessionMapName( MAP_NAME ); + factory.setMapName( MAP_NAME ); return factory; } } diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java index a452278df03..06a34569462 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/ClientSessionScavengingTest.java @@ -63,7 +63,7 @@ public class ClientSessionScavengingTest { HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory(); factory.setOnlyClient( true ); - factory.setJettySessionMapName( MAP_NAME ); + factory.setMapName( MAP_NAME ); return factory; } } From 2d787cb1ff180ca76eee2ff21f94b284f568a6b6 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Fri, 2 Jun 2017 10:07:26 +1000 Subject: [PATCH 07/12] fix typo Signed-off-by: olivier lamy --- .../jetty/hazelcast/session/HazelcastSessionDataStore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java index d6f738b98ad..d557835f7b6 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java @@ -141,7 +141,7 @@ public class HazelcastSessionDataStore { if (LOG.isDebugEnabled()) { - LOG.debug( "Session {} does not exist in infinispan", candidate ); + LOG.debug( "Session {} does not exist in Hazelcast", candidate ); } return true; } From 08c3255a571d2845f5e385838defa2c6aeb52dfd Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Thu, 8 Jun 2017 12:27:25 +1000 Subject: [PATCH 08/12] do not include hazelcast-client for embedded mode Signed-off-by: olivier lamy --- .../src/main/config/modules/session-store-hazelcast-embedded.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod index 7ce5a83b046..daa55012162 100644 --- a/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod +++ b/jetty-hazelcast/src/main/config/modules/session-store-hazelcast-embedded.mod @@ -12,7 +12,6 @@ sessions [files] maven://com.hazelcast/hazelcast/3.8.2|lib/hazelcast/hazelcast-3.8.2.jar -maven://com.hazelcast/hazelcast-client/3.8.2|lib/hazelcast/hazelcast-client-3.8.2.jar [xml] etc/sessions/hazelcast/default.xml From 90e8f6620e79d9ca4d85581acd7091e3ce901f2a Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Thu, 8 Jun 2017 12:54:47 +1000 Subject: [PATCH 09/12] use set rather than put, recommendation from hazelcast Signed-off-by: olivier lamy --- .../jetty/hazelcast/session/HazelcastSessionDataStore.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java index d557835f7b6..607ede676b4 100644 --- a/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java +++ b/jetty-hazelcast/src/main/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStore.java @@ -110,7 +110,7 @@ public class HazelcastSessionDataStore public void doStore( String id, SessionData data, long lastSaveTime ) throws Exception { - this.sessionDataMap.put( getCacheKey( id ), data); + this.sessionDataMap.set( getCacheKey( id ), data); } @Override From 3f5b61ab1ccfa70776d5a24190e5ce320560e519 Mon Sep 17 00:00:00 2001 From: olivier lamy Date: Thu, 8 Jun 2017 13:03:56 +1000 Subject: [PATCH 10/12] update versions for new modules Signed-off-by: olivier lamy --- jetty-hazelcast/pom.xml | 2 +- tests/test-sessions/test-hazelcast-sessions/pom.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jetty-hazelcast/pom.xml b/jetty-hazelcast/pom.xml index bc24e821994..3732b0a9b6e 100644 --- a/jetty-hazelcast/pom.xml +++ b/jetty-hazelcast/pom.xml @@ -4,7 +4,7 @@ org.eclipse.jetty jetty-project - 9.4.6-SNAPSHOT + 9.4.7-SNAPSHOT 4.0.0 diff --git a/tests/test-sessions/test-hazelcast-sessions/pom.xml b/tests/test-sessions/test-hazelcast-sessions/pom.xml index 8f357e30ba4..732cf4a5257 100644 --- a/tests/test-sessions/test-hazelcast-sessions/pom.xml +++ b/tests/test-sessions/test-hazelcast-sessions/pom.xml @@ -5,7 +5,7 @@ org.eclipse.jetty.tests test-sessions-parent - 9.4.6-SNAPSHOT + 9.4.7-SNAPSHOT test-hazelcast-sessions Jetty Tests :: Sessions :: Hazelcast From 67022482e581edf7618847cad3cc5d31067b27c4 Mon Sep 17 00:00:00 2001 From: Joakim Erdfelt Date: Mon, 12 Jun 2017 09:23:23 -0700 Subject: [PATCH 11/12] Issue #1605 - common executor and bufferpool for jsr356 client --- .../jsr356/JettyClientContainerProvider.java | 28 +++++++++++-- .../DelayedStartClientOnServerTest.java | 2 +- .../common/scopes/SimpleContainerScope.java | 41 ++++++++++++++----- 3 files changed, 57 insertions(+), 14 deletions(-) diff --git a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java index 0d79cec5276..251d214abf0 100644 --- a/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java +++ b/jetty-websocket/javax-websocket-client-impl/src/main/java/org/eclipse/jetty/websocket/jsr356/JettyClientContainerProvider.java @@ -19,14 +19,20 @@ package org.eclipse.jetty.websocket.jsr356; import java.lang.reflect.Method; +import java.util.concurrent.Executor; import javax.websocket.ContainerProvider; import javax.websocket.WebSocketContainer; +import org.eclipse.jetty.io.ByteBufferPool; +import org.eclipse.jetty.io.MappedByteBufferPool; import org.eclipse.jetty.util.component.ContainerLifeCycle; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.log.Logger; +import org.eclipse.jetty.util.thread.QueuedThreadPool; import org.eclipse.jetty.util.thread.ShutdownThread; +import org.eclipse.jetty.websocket.api.WebSocketPolicy; +import org.eclipse.jetty.websocket.common.scopes.SimpleContainerScope; /** * Client {@link ContainerProvider} implementation. @@ -43,6 +49,8 @@ public class JettyClientContainerProvider extends ContainerProvider private static boolean useSingleton = false; private static WebSocketContainer INSTANCE; private static boolean useServerContainer = false; + private static Executor commonExecutor; + private static ByteBufferPool commonBufferPool; private static Object lock = new Object(); @@ -177,8 +185,22 @@ public class JettyClientContainerProvider extends ContainerProvider // Still no instance? if (webSocketContainer == null) { - // TODO: use cached Executor, ByteBufferPool, and HttpClient here - ClientContainer clientContainer = new ClientContainer(); + if (commonExecutor == null) + { + QueuedThreadPool threadPool = new QueuedThreadPool(); + String name = "Jsr356Client@" + hashCode(); + threadPool.setName(name); + threadPool.setDaemon(true); + commonExecutor = threadPool; + } + + if (commonBufferPool == null) + { + commonBufferPool = new MappedByteBufferPool(); + } + + SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(), commonBufferPool, commonExecutor, null); + ClientContainer clientContainer = new ClientContainer(containerScope); if (contextHandler != null && contextHandler instanceof ContainerLifeCycle) { @@ -192,7 +214,7 @@ public class JettyClientContainerProvider extends ContainerProvider // register JVM wide shutdown thread ShutdownThread.register(clientContainer); } - + if (!clientContainer.isStarted()) { try diff --git a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java index 9a0282e4788..ac43e595d7d 100644 --- a/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java +++ b/jetty-websocket/javax-websocket-server-impl/src/test/java/org/eclipse/jetty/websocket/jsr356/server/DelayedStartClientOnServerTest.java @@ -247,7 +247,7 @@ public class DelayedStartClientOnServerTest assertThat("Response", response, startsWith("Connected to ws://")); List threadNames = getThreadNames(server); assertNoHttpClientPoolThreads(threadNames); - assertThat("Threads", threadNames, hasItem(containsString("WebSocketContainer@"))); + assertThat("Threads", threadNames, hasItem(containsString("Jsr356Client@"))); } finally { diff --git a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java index a82a7565584..5a8403022e3 100644 --- a/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java +++ b/jetty-websocket/websocket-common/src/main/java/org/eclipse/jetty/websocket/common/scopes/SimpleContainerScope.java @@ -34,31 +34,52 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke private final ByteBufferPool bufferPool; private final DecoratedObjectFactory objectFactory; private final WebSocketPolicy policy; - private Executor executor; + private final Executor executor; private SslContextFactory sslContextFactory; public SimpleContainerScope(WebSocketPolicy policy) { - this(policy,new MappedByteBufferPool(),new DecoratedObjectFactory()); + this(policy, new MappedByteBufferPool(), new DecoratedObjectFactory()); this.sslContextFactory = new SslContextFactory(); } public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool) { - this(policy,bufferPool,new DecoratedObjectFactory()); + this(policy, bufferPool, new DecoratedObjectFactory()); } public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory) + { + this(policy, bufferPool, (Executor) null, objectFactory); + } + + public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, Executor executor, DecoratedObjectFactory objectFactory) { this.policy = policy; this.bufferPool = bufferPool; - this.objectFactory = objectFactory; - - QueuedThreadPool threadPool = new QueuedThreadPool(); - String name = "WebSocketContainer@" + hashCode(); - threadPool.setName(name); - threadPool.setDaemon(true); - this.executor = threadPool; + + if (objectFactory == null) + { + this.objectFactory = new DecoratedObjectFactory(); + } + else + { + this.objectFactory = objectFactory; + } + + if (executor == null) + { + QueuedThreadPool threadPool = new QueuedThreadPool(); + String name = "WebSocketContainer@" + hashCode(); + threadPool.setName(name); + threadPool.setDaemon(true); + this.executor = threadPool; + addBean(this.executor); + } + else + { + this.executor = executor; + } } @Override From 4f1e583b85a23c04cc6cbc88375ee8cc26e99e0e Mon Sep 17 00:00:00 2001 From: stephane martin Date: Tue, 13 Jun 2017 19:26:19 +0200 Subject: [PATCH 12/12] HTTP/2 :authority: declaration should omit default ports in jetty-client (#1611) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: I2b4f8e8373e3ba16361a37fd1f6549a4a2d97d60 Signed-off-by: Stéphane Martin --- .../eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java index 6092fe324cd..da53f7a39be 100644 --- a/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java +++ b/jetty-http2/http2-http-client-transport/src/main/java/org/eclipse/jetty/http2/client/http/HttpSenderOverHTTP2.java @@ -51,7 +51,7 @@ public class HttpSenderOverHTTP2 extends HttpSender { Request request = exchange.getRequest(); String path = relativize(request.getPath()); - HttpURI uri = new HttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null); + HttpURI uri = HttpURI.createHttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null); MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders()); HeadersFrame headersFrame = new HeadersFrame(metaData, null, !content.hasContent()); HttpChannelOverHTTP2 channel = getHttpChannel();