From add04e8fba2f0d1baddd15127048612bf8e3e4dc Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Thu, 17 Mar 2016 12:27:52 +1100 Subject: [PATCH] Remove necessity for SessionIdManager specializations. --- .../main/config/etc/jetty-gcloud-sessions.xml | 28 +- .../main/config/modules/gcloud-sessions.mod | 11 +- .../main/example/gcloud-example-context.xml | 42 ++ .../session/GCloudSessionDataStore.java | 28 ++ .../session/GCloudSessionIdManager.java | 231 ----------- .../gcloud/session/GCloudSessionManager.java | 237 +---------- .../gcloud/session/GCloudSessionTester.java | 5 +- .../src/main/config/modules/infinispan.mod | 8 - .../infinispan-example-context.xml} | 33 +- .../InfinispanSessionDataStore.java | 68 ++- .../InfinispanSessionIdManager.java | 291 ------------- .../src/main/config/etc/jetty-nosql.xml | 19 - jetty-nosql/src/main/config/modules/nosql.mod | 11 - .../main/example/mongo-example-context.xml | 37 ++ .../nosql/mongodb/MongoSessionDataStore.java | 29 ++ .../nosql/mongodb/MongoSessionIdManager.java | 177 -------- .../nosql/mongodb/MongoSessionManager.java | 14 +- .../jetty/proxy/BalancerServletTest.java | 5 +- .../main/config/etc/jetty-jdbc-sessions.xml | 38 -- .../src/main/config/etc/jetty-sessions.xml | 27 ++ .../src/main/config/modules/jdbc-sessions.mod | 25 -- .../src/main/config/modules/server.mod | 5 + .../src/main/config/modules/sessions.mod | 13 + .../example/filestore-example-context.xml | 23 ++ .../src/main/example/jdbc-example-context.xml | 50 +++ .../jetty/server/SessionIdManager.java | 21 +- .../eclipse/jetty/server/SessionManager.java | 10 + .../session/AbstractSessionDataStore.java | 1 + .../server/session/AbstractSessionStore.java | 58 ++- .../session/CachingSessionDataStore.java | 11 +- ...ager.java => DefaultSessionIdManager.java} | 78 ++-- .../server/session/FileSessionDataStore.java | 42 +- .../server/session/HashSessionIdManager.java | 77 ---- .../server/session/JDBCSessionDataStore.java | 38 ++ .../server/session/JDBCSessionIdManager.java | 391 ------------------ .../server/session/JDBCSessionManager.java | 12 +- .../server/session/MemorySessionStore.java | 9 +- .../server/session/NullSessionDataStore.java | 10 + .../session/PeriodicSessionInspector.java | 6 +- .../eclipse/jetty/server/session/Session.java | 10 +- .../server/session/SessionDataStore.java | 11 + .../jetty/server/session/SessionManager.java | 70 ++-- .../jetty/server/session/SessionStore.java | 1 + .../eclipse/jetty/server/ResponseTest.java | 6 +- .../session/FileSessionManagerTest.java | 6 +- .../server/session/SessionCookieTest.java | 31 +- .../jetty/server/session/FileTestServer.java | 2 +- .../server/session/SessionRenewTest.java | 3 +- .../gcloud/session/GCloudTestServer.java | 21 +- .../gcloud/session/SessionRenewTest.java | 4 +- .../jetty/server/session/HashTestServer.java | 7 - .../server/session/SessionRenewTest.java | 3 +- .../session/InfinispanTestSessionServer.java | 39 +- .../server/session/SessionRenewTest.java | 11 +- .../remote/RemoteSessionRenewTest.java | 5 +- .../jetty/server/session/JdbcTestServer.java | 52 +-- .../ReloadedSessionMissingClassTest.java | 4 +- .../server/session/SessionRenewTest.java | 4 +- .../jetty/nosql/mongodb/MongoTestServer.java | 15 +- .../mongodb/PurgeInvalidSessionTest.java | 260 ------------ .../nosql/mongodb/PurgeValidSessionTest.java | 232 ----------- .../nosql/mongodb/SessionExpiryTest.java | 6 +- .../jetty/nosql/mongodb/SessionRenewTest.java | 3 +- .../session/AbstractSessionRenewTest.java | 6 +- .../server/session/AbstractTestServer.java | 26 +- 65 files changed, 690 insertions(+), 2367 deletions(-) create mode 100644 jetty-gcloud/jetty-gcloud-session-manager/src/main/example/gcloud-example-context.xml delete mode 100644 jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java rename jetty-infinispan/src/main/{config/etc/jetty-infinispan.xml => example/infinispan-example-context.xml} (58%) delete mode 100644 jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java delete mode 100644 jetty-nosql/src/main/config/etc/jetty-nosql.xml create mode 100644 jetty-nosql/src/main/example/mongo-example-context.xml delete mode 100644 jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java delete mode 100644 jetty-server/src/main/config/etc/jetty-jdbc-sessions.xml create mode 100644 jetty-server/src/main/config/etc/jetty-sessions.xml delete mode 100644 jetty-server/src/main/config/modules/jdbc-sessions.mod create mode 100644 jetty-server/src/main/config/modules/sessions.mod create mode 100644 jetty-server/src/main/example/filestore-example-context.xml create mode 100644 jetty-server/src/main/example/jdbc-example-context.xml rename jetty-server/src/main/java/org/eclipse/jetty/server/session/{AbstractSessionIdManager.java => DefaultSessionIdManager.java} (89%) delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java delete mode 100644 jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java delete mode 100644 tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java delete mode 100644 tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/jetty-gcloud-sessions.xml b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/jetty-gcloud-sessions.xml index 26408bb9cc2..d4bbbab8d49 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/jetty-gcloud-sessions.xml +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/etc/jetty-gcloud-sessions.xml @@ -3,33 +3,11 @@ - - - - - - - - - - - - - - - - - - - - - - node - - - + + node + diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud-sessions.mod b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud-sessions.mod index 067537e56e5..1f31ca4c130 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud-sessions.mod +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/config/modules/gcloud-sessions.mod @@ -1,5 +1,5 @@ [description] -Enables the GCloudDatastore Session Mananger module. +Enables GCloudDatastore session management. [depend] annotations @@ -43,18 +43,17 @@ maven://com.google.apis/google-api-services-datastore/v1beta2-rev23-1.19.0|lib/g lib/jetty-gcloud-session-manager-${jetty.version}.jar lib/gcloud/*.jar -[xml] -etc/jetty-gcloud-sessions.xml [license] GCloudDatastore is an open source project hosted on Github and released under the Apache 2.0 license. https://github.com/GoogleCloudPlatform/gcloud-java http://www.apache.org/licenses/LICENSE-2.0.html +[xml] +etc/jetty-gcloud-sessions.xml + + [ini-template] -## Unique identifier to force the workername for this node in the cluster -## If not set, will default to the string "node" plus the Env variable $GAE_MODULE_INSTANCE -# jetty.gcloudSession.workerName=node1 ## GCloudDatastore Session config diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/example/gcloud-example-context.xml b/jetty-gcloud/jetty-gcloud-session-manager/src/main/example/gcloud-example-context.xml new file mode 100644 index 00000000000..e205f8594a0 --- /dev/null +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/example/gcloud-example-context.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + seconds + + + + + integer + + + seconds + seconds + + + + + + diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java index eec6f303a64..00cc016e4f5 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStore.java @@ -273,6 +273,34 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore + + + /** + * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) + */ + @Override + public boolean exists(String id) throws Exception + { + ProjectionEntityQueryBuilder pbuilder = Query.projectionEntityQueryBuilder(); + pbuilder.addProjection(Projection.property(EXPIRY)); + pbuilder.filter(PropertyFilter.eq(ID, id)); + pbuilder.kind(KIND); + StructuredQuery pquery = pbuilder.build(); + QueryResults presults = _datastore.run(pquery); + + if (presults.hasNext()) + { + ProjectionEntity pe = presults.next(); + long expiry = pe.getLong(EXPIRY); + if (expiry <= 0) + return true; //never expires + else + return (expiry > System.currentTimeMillis()); //not expired yet + } + else + return false; + } + /** * @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long) */ diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java deleted file mode 100644 index 2f8da7af1d8..00000000000 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java +++ /dev/null @@ -1,231 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 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.gcloud.session; - -import java.util.Random; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.session.AbstractSessionIdManager; -import org.eclipse.jetty.server.session.Session; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -import com.google.gcloud.datastore.Datastore; -import com.google.gcloud.datastore.DatastoreFactory; -import com.google.gcloud.datastore.Entity; -import com.google.gcloud.datastore.Key; -import com.google.gcloud.datastore.KeyFactory; - - - -/** - * GCloudSessionIdManager - * - * - * - */ -public class GCloudSessionIdManager extends AbstractSessionIdManager -{ - private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); - public static final int DEFAULT_IDLE_EXPIRY_MULTIPLE = 2; - public static final String KIND = "GCloudSessionId"; - private Datastore _datastore; - private KeyFactory _keyFactory; - private GCloudConfiguration _config; - - - - - /** - * @param server - */ - public GCloudSessionIdManager(Server server) - { - super(server); - } - - /** - * @param server - * @param random - */ - public GCloudSessionIdManager(Server server, Random random) - { - super(server,random); - } - - - - /** - * Start the id manager. - * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#doStart() - */ - @Override - protected void doStart() throws Exception - { - if (_config == null) - throw new IllegalStateException("No gcloud configuration specified"); - - - _datastore = DatastoreFactory.instance().get(_config.getDatastoreOptions()); - _keyFactory = _datastore.newKeyFactory().kind(KIND); - - super.doStart(); - } - - - - /** - * Stop the id manager - * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#doStop() - */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - } - - - - - - - public GCloudConfiguration getConfig() - { - return _config; - } - - public void setConfig(GCloudConfiguration config) - { - _config = config; - } - - - - - - - /** - * Ask the datastore if a particular id exists. - * - * @param id - * @return - */ - protected boolean exists (String id) - { - if (_datastore == null) - throw new IllegalStateException ("No DataStore"); - Key key = _keyFactory.newKey(id); - return _datastore.get(key) != null; - } - - - /** - * Put a session id into the cluster. - * - * @param id - */ - protected void insert (String id) - { - if (_datastore == null) - throw new IllegalStateException ("No DataStore"); - - Entity entity = Entity.builder(makeKey(id)) - .set("id", id).build(); - _datastore.put(entity); - } - - - - - /** - * Remove a session id from the cluster. - * - * @param id - */ - protected boolean delete (String id) - { - if (_datastore == null) - throw new IllegalStateException ("No DataStore"); - - _datastore.delete(makeKey(id)); - return true; //gcloud does not distinguish between first and subsequent removes - } - - - - /** - * Generate a unique key from the session id. - * - * @param id - * @return - */ - protected Key makeKey (String id) - { - return _keyFactory.newKey(id); - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String) - */ - @Override - public boolean isIdInUse(String id) - { - if (id == null) - return false; - - - //ask the cluster - this should also tickle the idle expiration timer on the sessionid entry - //keeping it valid - try - { - return exists(id); - } - catch (Exception e) - { - LOG.warn("Problem checking inUse for id="+id, e); - return false; - } - - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#useId(org.eclipse.jetty.server.session.Session) - */ - @Override - public void useId(Session session) - { - if (session == null) - return; - - //insert into the store - insert (session.getId()); - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String) - */ - @Override - public boolean removeId(String id) - { - if (id == null) - return false; - - return delete(id); - } -} diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java index 03c778f3672..d029ab9bbfb 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionManager.java @@ -29,238 +29,16 @@ import org.eclipse.jetty.util.log.Logger; /** * GCloudSessionManager * - * + * Convenience class to link up a MemorySessionStore with the GCloudSessionDataStore. + * */ public class GCloudSessionManager extends SessionManager { private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); - - - private GCloudSessionDataStore _sessionDataStore = null; - - - - /* * - * Session - * - * Representation of a session in local memory. - *//* - public class Session extends MemSession - { - - private ReentrantLock _lock = new ReentrantLock(); - - - private long _lastSyncTime; - - private AtomicInteger _activeThreads = new AtomicInteger(0); - - - - protected Session (HttpServletRequest request) - { - _activeThreads.incrementAndGet(); //access will not be called on a freshly created session so increment here - } - - - - */ - /* * - * Called on entry to the session. - * - * @see org.eclipse.jetty.server.session.AbstractSession#access(long) - *//* - @Override - protected boolean access(long time) - { - if (LOG.isDebugEnabled()) - LOG.debug("Access session({}) for context {} on worker {}", getId(), getContextPath(), getSessionIdManager().getWorkerName()); - try - { - - long now = System.currentTimeMillis(); - //lock so that no other thread can call access or complete until the first one has refreshed the session object if necessary - _lock.lock(); - //a request thread is entering - if (_activeThreads.incrementAndGet() == 1) - { - //if the first thread, check that the session in memory is not stale, if we're checking for stale sessions - if (getStaleIntervalSec() > 0 && (now - getLastSyncTime()) >= (getStaleIntervalSec() * 1000L)) - { - if (LOG.isDebugEnabled()) - LOG.debug("Acess session({}) for context {} on worker {} stale session. Reloading.", getId(), getContextPath(), getSessionIdManager().getWorkerName()); - refresh(); - } - } - } - catch (Exception e) - { - LOG.warn(e); - } - finally - { - _lock.unlock(); - } - - if (super.access(time)) - { - int maxInterval=getMaxInactiveInterval(); - _expiryTime = (maxInterval <= 0 ? 0 : (time + maxInterval*1000L)); - return true; - } - return false; - } - - - *//* * - * Exit from session - * @see org.eclipse.jetty.server.session.AbstractSession#complete() - *//* - @Override - protected void complete() - { - super.complete(); - - //lock so that no other thread that might be calling access can proceed until this complete is done - _lock.lock(); - - try - { - //if this is the last request thread to be in the session - if (_activeThreads.decrementAndGet() == 0) - { - try - { - //an invalid session will already have been removed from the - //local session map and deleted from the cluster. If its valid save - //it to the cluster. - //TODO consider doing only periodic saves if only the last access - //time to the session changes - if (isValid()) - { - //if session still valid && its dirty or stale or never been synced, write it to the cluster - //otherwise, we just keep the updated last access time in memory - if (_dirty || getLastSyncTime() == 0 || isStale(System.currentTimeMillis())) - { - willPassivate(); - save(this); - didActivate(); - } - } - } - catch (Exception e) - { - LOG.warn("Problem saving session({})",getId(), e); - } - finally - { - _dirty = false; - } - } - } - finally - { - _lock.unlock(); - } - } - - *//* * Test if the session is stale - * @param atTime - * @return - *//* - protected boolean isStale (long atTime) - { - return (getStaleIntervalSec() > 0) && (atTime - getLastSyncTime() >= (getStaleIntervalSec()*1000L)); - } - - - *//* * - * Reload the session from the cluster. If the node that - * last managed the session from the cluster is ourself, - * then the session does not need refreshing. - * NOTE: this method MUST be called with sufficient locks - * in place to prevent 2 or more concurrent threads from - * simultaneously updating the session. - *//* - private void refresh () - throws Exception - { - //get fresh copy from the cluster - Session fresh = load(makeKey(getClusterId(), _context)); - - //if the session no longer exists, invalidate - if (fresh == null) - { - invalidate(); - return; - } - - //cluster copy assumed to be the same as we were the last - //node to manage it - if (fresh.getLastNode().equals(getLastNode())) - return; - - setLastNode(getSessionIdManager().getWorkerName()); - - //prepare for refresh - willPassivate(); - - //if fresh has no attributes, remove them - if (fresh.getAttributes() == 0) - this.clearAttributes(); - else - { - //reconcile attributes - for (String key:fresh.getAttributeMap().keySet()) - { - Object freshvalue = fresh.getAttribute(key); - - //session does not already contain this attribute, so bind it - if (getAttribute(key) == null) - { - doPutOrRemove(key,freshvalue); - bindValue(key,freshvalue); - } - else //session already contains this attribute, update its value - { - doPutOrRemove(key,freshvalue); - } - - } - // cleanup, remove values from session, that don't exist in data anymore: - for (String key : getNames()) - { - if (fresh.getAttribute(key) == null) - { - Object oldvalue = getAttribute(key); - doPutOrRemove(key,null); - unbindValue(key,oldvalue); - } - } - } - //finish refresh - didActivate(); - } - - - public void swapId (String newId, String newNodeId) - { - //TODO probably synchronize rather than use the access/complete lock? - _lock.lock(); - setClusterId(newId); - setNodeId(newNodeId); - _lock.unlock(); - } - - - } - -*/ - /** * @@ -309,15 +87,4 @@ public class GCloudSessionManager extends SessionManager { super.doStop(); } - - - - - - protected void scavengeGCloudDataStore() - throws Exception - { - - - } } diff --git a/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java b/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java index ac58dd4b4c4..c4152381dbe 100644 --- a/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java +++ b/jetty-gcloud/jetty-gcloud-session-manager/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionTester.java @@ -24,6 +24,7 @@ package org.eclipse.jetty.gcloud.session; import org.eclipse.jetty.security.HashLoginService; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker; +import org.eclipse.jetty.server.session.DefaultSessionIdManager; import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.webapp.WebAppContext; @@ -48,8 +49,7 @@ public class GCloudSessionTester config.setPassword(args[2]); config.setServiceAccount(args[3]); - GCloudSessionIdManager idmgr = new GCloudSessionIdManager(server); - idmgr.setConfig(config); + DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server); idmgr.setWorkerName("w1"); server.setSessionIdManager(idmgr); @@ -59,6 +59,7 @@ public class GCloudSessionTester webapp.setWar("../../jetty-distribution/target/distribution/demo-base/webapps/test.war"); webapp.addAliasCheck(new AllowSymLinkAliasChecker()); GCloudSessionManager mgr = new GCloudSessionManager(); + mgr.getSessionDataStore().setGCloudConfiguration(config); mgr.setSessionIdManager(idmgr); webapp.setSessionHandler(new SessionHandler(mgr)); diff --git a/jetty-infinispan/src/main/config/modules/infinispan.mod b/jetty-infinispan/src/main/config/modules/infinispan.mod index 9a1e0b27dfd..ba2f4976932 100644 --- a/jetty-infinispan/src/main/config/modules/infinispan.mod +++ b/jetty-infinispan/src/main/config/modules/infinispan.mod @@ -17,17 +17,9 @@ maven://org.jboss.logging/jboss-logging/3.1.2.GA|lib/infinispan/jboss-logging-3. lib/jetty-infinispan-${jetty.version}.jar lib/infinispan/*.jar -[xml] -etc/jetty-infinispan.xml [license] Infinispan is an open source project hosted on Github and released under the Apache 2.0 license. http://infinispan.org/ http://www.apache.org/licenses/LICENSE-2.0.html -[ini-template] -## Infinispan Session config - -## Unique identifier for this node in the cluster -# jetty.infinispanSession.workerName=node1 - diff --git a/jetty-infinispan/src/main/config/etc/jetty-infinispan.xml b/jetty-infinispan/src/main/example/infinispan-example-context.xml similarity index 58% rename from jetty-infinispan/src/main/config/etc/jetty-infinispan.xml rename to jetty-infinispan/src/main/example/infinispan-example-context.xml index 49d7ab63b9a..81656ae2119 100644 --- a/jetty-infinispan/src/main/config/etc/jetty-infinispan.xml +++ b/jetty-infinispan/src/main/example/infinispan-example-context.xml @@ -1,7 +1,8 @@ - + - + + @@ -23,17 +24,21 @@ --> - - - - - - - - - - - - + + + + seconds + + + + + + + seconds + seconds + + + + diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java index 62e98eb79bf..e8db3b1a32c 100644 --- a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java +++ b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java @@ -100,7 +100,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore if (LOG.isDebugEnabled()) LOG.debug("Loading session {} from infinispan", id); - SessionData sd = (SessionData)_cache.get(getCacheKey(id, _context)); + SessionData sd = (SessionData)_cache.get(getCacheKey(id)); reference.set(sd); } catch (Exception e) @@ -127,7 +127,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore { if (LOG.isDebugEnabled()) LOG.debug("Deleting session with id {} from infinispan", id); - return (_cache.remove(getCacheKey(id, _context)) != null); + return (_cache.remove(getCacheKey(id)) != null); } /** @@ -143,8 +143,8 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore Set expired = new HashSet(); - //TODO if there is NOT an idle timeout set, need to check other sessions that - //might have expired + //TODO if there is NOT an idle timeout set on entries in infinispan, need to check other sessions + //that are not currently in the SessionStore (eg they've been passivated) for (String candidate:candidates) { @@ -212,18 +212,13 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore //scavenges the session before this timeout occurs, the session will be removed. //NOTE: that no session listeners can be called for this. if (data.getMaxInactiveMs() > 0 && getInfinispanIdleTimeoutSec() > 0) - _cache.put(getCacheKey(id, _context), data, -1, TimeUnit.MILLISECONDS, getInfinispanIdleTimeoutSec(), TimeUnit.SECONDS); + _cache.put(getCacheKey(id), data, -1, TimeUnit.MILLISECONDS, getInfinispanIdleTimeoutSec(), TimeUnit.SECONDS); else - _cache.put(getCacheKey(id, _context), data); + _cache.put(getCacheKey(id), data); if (LOG.isDebugEnabled()) LOG.debug("Session {} saved to infinispan, expires {} ", id, data.getExpiry()); - //tickle the session id manager to keep the sessionid entry for this session up-to-date - if (_idMgr != null && _idMgr instanceof InfinispanSessionIdManager) - { - ((InfinispanSessionIdManager)_idMgr).touch(id); - } } @@ -232,9 +227,9 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore * @param context * @return */ - public static String getCacheKey (String id, SessionContext context) + public String getCacheKey (String id) { - return context.getCanonicalContextPath()+"_"+context.getVhost()+"_"+id; + return _context.getCanonicalContextPath()+"_"+_context.getVhost()+"_"+id; } @@ -263,6 +258,53 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore + /** + * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) + */ + @Override + public boolean exists(String id) throws Exception + { + // TODO find a better way to do this that does not pull into memory the + // whole session object + final AtomicReference reference = new AtomicReference(); + final AtomicReference exception = new AtomicReference(); + + Runnable load = new Runnable() + { + public void run () + { + try + { + SessionData sd = load(id); + if (sd == null) + { + reference.set(Boolean.FALSE); + return; + } + + if (sd.getExpiry() <= 0) + reference.set(Boolean.TRUE); //never expires + else + reference.set(Boolean.valueOf(sd.getExpiry() > System.currentTimeMillis())); //not expired yet + } + catch (Exception e) + { + exception.set(e); + } + } + }; + + //ensure the load runs in the context classloader scope + _context.run(load); + + if (exception.get() != null) + throw exception.get(); + + return reference.get(); + } + + + /** * @param sec the infinispan-specific idle timeout in sec or 0 if not set */ diff --git a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java b/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java deleted file mode 100644 index 7ba9c75d63d..00000000000 --- a/jetty-infinispan/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionIdManager.java +++ /dev/null @@ -1,291 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 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.session.infinispan; - -import java.util.Random; -import java.util.concurrent.TimeUnit; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.session.AbstractSessionIdManager; -import org.eclipse.jetty.server.session.Session; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; -import org.infinispan.commons.api.BasicCache; - - - - -/** - * InfinispanSessionIdManager - * - * Maintain a set of in-use session ids. This session id manager does NOT locally store - * a list of in-use sesssion ids, but rather stores them in the cluster cache. Thus, - * all operations to this session manager involve interaction with a possibly remote - * cache. - * - * For each session id that is in-use, an entry of the following form is put into - * the cluster cache: - *
- *   ("__o.e.j.s.infinispanIdMgr__"+[id], [id])
- * 
- * where [id] is the id of the session. - * - * If the first session to be added is not immortal (ie it has a timeout on it) then - * the corresponding session id is entered into infinispan with an idle expiry timeout - * equivalent to double the session's timeout (the multiplier is configurable). - * - * - * Having one entry per in-use session id means that there is no contention on - * cache entries (as would be the case if a single entry was kept containing a - * list of in-use session ids). - * - * - */ -public class InfinispanSessionIdManager extends AbstractSessionIdManager -{ - private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); - public final static String ID_KEY = "__o.e.j.s.infinispanIdMgr__"; - protected BasicCache _cache; - private int _infinispanIdleTimeoutSec = 0; - - - - - - public InfinispanSessionIdManager(Server server) - { - super(server); - } - - public InfinispanSessionIdManager(Server server, Random random) - { - super(server, random); - } - - - - /** - * Start the id manager. - * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#doStart() - */ - @Override - protected void doStart() throws Exception - { - super.doStart(); - } - - - - /** - * Stop the id manager - * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#doStop() - */ - @Override - protected void doStop() throws Exception - { - super.doStop(); - } - - - - - - /** - * Check to see if the given session id is being - * used by a session in any context. - * - * This method will consult the cluster. - * - * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String) - */ - @Override - public boolean isIdInUse(String id) - { - if (id == null) - return false; - - String clusterId = getId(id); - - //ask the cluster - this should also tickle the idle expiration timer on the sessionid entry - //keeping it valid - try - { - return exists(clusterId); - } - catch (Exception e) - { - LOG.warn("Problem checking inUse for id="+clusterId, e); - return false; - } - - } - - - public void setInfinispanIdleTimeoutSec (int sec) - { - if (sec <= 1) - { - LOG.warn("Idle expiry multiple of {} for session ids set to less than minimum. Using value of {} instead.", sec, 0); - _infinispanIdleTimeoutSec = 0; - } - else - _infinispanIdleTimeoutSec = sec; - } - - - - - public int getInfinispanIdleTimeoutSec() - { - return _infinispanIdleTimeoutSec; - } - - - - - /** - * Get the cache. - * @return the cache - */ - public BasicCache getCache() - { - return _cache; - } - - /** - * Set the cache. - * @param cache the cache - */ - public void setCache(BasicCache cache) - { - this._cache = cache; - } - - - - /** - * Do any operation to the session id in the cache to - * ensure its idle expiry time moves forward - * @param id the session id - */ - public void touch (String id) - { - exists(id); - } - - - - /** - * Ask the cluster if a particular id exists. - * - * @param id the session id - * @return true if exists - */ - protected boolean exists (String id) - { - if (_cache == null) - throw new IllegalStateException ("No cache"); - - return _cache.containsKey(makeKey(id)); - } - - - /** - * Put a session id into the cluster. - * - * @param id the session id - */ - protected void insert (String id) - { - if (_cache == null) - throw new IllegalStateException ("No cache"); - - _cache.putIfAbsent(makeKey(id), id); - } - - - /** - * Put a session id into the cluster with an idle expiry. - * - * @param id the session id - * @param idleTimeOutSec idle timeout in seconds - */ - protected void insert (String id, long idleTimeOutSec) - { - if (_cache == null) - throw new IllegalStateException ("No cache"); - - _cache.putIfAbsent(makeKey(id),id,-1L, TimeUnit.SECONDS, idleTimeOutSec, TimeUnit.SECONDS); - } - - - /** - * Remove a session id from the cluster. - * - * @param id the session id - */ - protected boolean delete (String id) - { - if (_cache == null) - throw new IllegalStateException ("No cache"); - - return _cache.remove(makeKey(id)) != null; - } - - - - /** - * Generate a unique cache key from the session id. - * - * @param id the session id - * @return unique cache id - */ - public String makeKey (String id) - { - return ID_KEY+id; - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#useId(Session) - */ - @Override - public void useId(Session session) - { - if (session == null) - return; - - if (session.getMaxInactiveInterval() > 0 && getInfinispanIdleTimeoutSec() > 0) - insert (session.getId(), getInfinispanIdleTimeoutSec()); - else - insert (session.getId()); - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String) - */ - @Override - public boolean removeId(String id) - { - return delete (id); - } - - - - -} diff --git a/jetty-nosql/src/main/config/etc/jetty-nosql.xml b/jetty-nosql/src/main/config/etc/jetty-nosql.xml deleted file mode 100644 index ee1ebd14bf2..00000000000 --- a/jetty-nosql/src/main/config/etc/jetty-nosql.xml +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - - - - - - - - - diff --git a/jetty-nosql/src/main/config/modules/nosql.mod b/jetty-nosql/src/main/config/modules/nosql.mod index fb4ed66f690..20f35b68f27 100644 --- a/jetty-nosql/src/main/config/modules/nosql.mod +++ b/jetty-nosql/src/main/config/modules/nosql.mod @@ -11,20 +11,9 @@ maven://org.mongodb/mongo-java-driver/2.6.1|lib/nosql/mongo-java-driver-2.6.1.ja lib/jetty-nosql-${jetty.version}.jar lib/nosql/*.jar -[xml] -etc/jetty-nosql.xml [license] The java driver for the MongoDB document-based database system is hosted on GitHub and released under the Apache 2.0 license. http://www.mongodb.org/ http://www.apache.org/licenses/LICENSE-2.0.html -[ini-template] -## MongoDB SessionIdManager config - -## Unique identifier for this node in the cluster -# jetty.nosqlSession.workerName=node1 - -## Interval in seconds between scavenging expired sessions -# jetty.nosqlSession.scavenge=1800 - diff --git a/jetty-nosql/src/main/example/mongo-example-context.xml b/jetty-nosql/src/main/example/mongo-example-context.xml new file mode 100644 index 00000000000..b296273ede6 --- /dev/null +++ b/jetty-nosql/src/main/example/mongo-example-context.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + HttpSessions + + sessions + + + + + + + + + seconds + + + + + + + seconds + seconds + + + + + + diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java index fbd7aca7538..47b20f281a7 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStore.java @@ -314,6 +314,35 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore } } + + + + /** + * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) + */ + @Override + public boolean exists(String id) throws Exception + { + DBObject fields = new BasicDBObject(); + fields.put(__EXPIRY, 1); + fields.put(__VALID, 1); + + DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id), fields); + + if (sessionDocument == null) + return false; //doesn't exist + + Boolean valid = (Boolean)sessionDocument.get(__VALID); + if (!valid) + return false; //invalid - nb should not happen + + Long expiry = (Long)sessionDocument.get(__EXPIRY); + + if (expiry.longValue() <= 0) + return false; //never expires, its good + return (expiry.longValue() > System.currentTimeMillis()); //expires later + } + /** * @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set, int) diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java deleted file mode 100644 index ca5040c8ad6..00000000000 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionIdManager.java +++ /dev/null @@ -1,177 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 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.nosql.mongodb; - - -import java.net.UnknownHostException; -import java.util.Random; -import java.util.Set; - -import javax.servlet.http.HttpServletRequest; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.session.AbstractSessionIdManager; -import org.eclipse.jetty.server.session.Session; -import org.eclipse.jetty.util.ConcurrentHashSet; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - -import com.mongodb.BasicDBObject; -import com.mongodb.BasicDBObjectBuilder; -import com.mongodb.DBCollection; -import com.mongodb.DBObject; -import com.mongodb.Mongo; -import com.mongodb.MongoException; - -/** - * Manager of session ids based on sessions stored in Mongo. - * - */ -public class MongoSessionIdManager extends AbstractSessionIdManager -{ - private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); - - final static DBObject __version_1 = new BasicDBObject(MongoSessionDataStore.__VERSION,1); - final static DBObject __valid_false = new BasicDBObject(MongoSessionDataStore.__VALID,false); - final static DBObject __valid_true = new BasicDBObject(MongoSessionDataStore.__VALID,true); - final static DBObject __expiry = new BasicDBObject(MongoSessionDataStore.__EXPIRY, 1); - - - final DBCollection _sessions; - - - /** - * the collection of session ids known to this manager - */ - protected final Set _sessionsIds = new ConcurrentHashSet<>(); - - - - - - /* ------------------------------------------------------------ */ - public MongoSessionIdManager(Server server) throws UnknownHostException, MongoException - { - this(server, new Mongo().getDB("HttpSessions").getCollection("sessions")); - } - - /* ------------------------------------------------------------ */ - public MongoSessionIdManager(Server server, DBCollection sessions) - { - super(server, new Random()); - - _sessions = sessions; - - _sessions.ensureIndex( - BasicDBObjectBuilder.start().add("id",1).get(), - BasicDBObjectBuilder.start().add("unique",true).add("sparse",false).get()); - _sessions.ensureIndex( - BasicDBObjectBuilder.start().add("id",1).add("version",1).get(), - BasicDBObjectBuilder.start().add("unique",true).add("sparse",false).get()); - - // index our accessed and valid fields so that purges are faster, note that the "valid" field is first - // so that we can take advantage of index prefixes - // http://docs.mongodb.org/manual/core/index-compound/#compound-index-prefix - _sessions.ensureIndex( - BasicDBObjectBuilder.start().add(MongoSessionDataStore.__VALID, 1).add(MongoSessionDataStore.__ACCESSED, 1).get(), - BasicDBObjectBuilder.start().add("sparse", false).add("background", true).get()); - } - - - - /* ------------------------------------------------------------ */ - public DBCollection getSessions() - { - return _sessions; - } - - - /* ------------------------------------------------------------ */ - @Override - protected void doStart() throws Exception - { - if (LOG.isDebugEnabled()) LOG.debug("MongoSessionIdManager:starting"); - super.doStart(); - } - - /* ------------------------------------------------------------ */ - @Override - protected void doStop() throws Exception - { - if (LOG.isDebugEnabled()) LOG.debug("MongoSessionIdManager:stopping"); - super.doStop(); - } - - /* ------------------------------------------------------------ */ - /** - * Searches database to find if the session id known to mongo, and is it valid - */ - @Override - public boolean isIdInUse(String sessionId) - { - /* - * optimize this query to only return the valid and expiry - */ - DBObject fields = new BasicDBObject(); - fields.put(MongoSessionDataStore.__VALID, new Long(1)); - fields.put(MongoSessionDataStore.__EXPIRY, new Long(1)); - - DBObject o = _sessions.findOne(new BasicDBObject(MongoSessionDataStore.__ID,sessionId), fields); - - if ( o != null ) - { - Boolean valid = (Boolean)o.get(MongoSessionDataStore.__VALID); - if ( valid == null ) - return false; - - Long expiry = (Long)o.get(MongoSessionDataStore.__EXPIRY); - if (expiry < System.currentTimeMillis()) - return false; - return valid; - } - - return false; - } - - /* ------------------------------------------------------------ */ - @Override - public void useId(Session session) - { - if (session == null) - return; - - /* - * already a part of the index in mongo... - */ - - LOG.debug("MongoSessionIdManager:addSession {}", session.getId()); - } - - - /* ------------------------------------------------------------ */ - @Override - public boolean removeId(String id) - { - //The corresponding session document will be marked as expired or invalid? - return true; //can't distinguish first remove vs subsequent removes - } - - - -} diff --git a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java index 5fc15d0ff03..74c83c1e11b 100644 --- a/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java +++ b/jetty-nosql/src/main/java/org/eclipse/jetty/nosql/mongodb/MongoSessionManager.java @@ -110,22 +110,10 @@ public class MongoSessionManager extends SessionManager public void doStart() throws Exception { ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore); - _sessionDataStore.setDBCollection(_dbSessions); super.doStart(); } - /* ------------------------------------------------------------ */ - @Override - public void setSessionIdManager(SessionIdManager metaManager) - { - MongoSessionIdManager msim = (MongoSessionIdManager)metaManager; - _dbSessions=msim.getSessions(); - super.setSessionIdManager(metaManager); - - } - - { - } + public MongoSessionDataStore getSessionDataStore() { diff --git a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java index 1d0ae2dc927..960b0542ef9 100644 --- a/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java +++ b/jetty-proxy/src/test/java/org/eclipse/jetty/proxy/BalancerServletTest.java @@ -34,8 +34,7 @@ import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.ContentResponse; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; -import org.eclipse.jetty.server.session.AbstractSessionIdManager; -import org.eclipse.jetty.server.session.HashSessionIdManager; +import org.eclipse.jetty.server.session.DefaultSessionIdManager; import org.eclipse.jetty.servlet.ServletContextHandler; import org.eclipse.jetty.servlet.ServletHolder; import org.junit.After; @@ -99,7 +98,7 @@ public class BalancerServletTest if (nodeName != null) { - AbstractSessionIdManager sessionIdManager = new HashSessionIdManager(server); + DefaultSessionIdManager sessionIdManager = new DefaultSessionIdManager(server); sessionIdManager.setWorkerName(nodeName); server.setSessionIdManager(sessionIdManager); } diff --git a/jetty-server/src/main/config/etc/jetty-jdbc-sessions.xml b/jetty-server/src/main/config/etc/jetty-jdbc-sessions.xml deleted file mode 100644 index 8bb571c9e5b..00000000000 --- a/jetty-server/src/main/config/etc/jetty-jdbc-sessions.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jetty-server/src/main/config/etc/jetty-sessions.xml b/jetty-server/src/main/config/etc/jetty-sessions.xml new file mode 100644 index 00000000000..f23e0f72889 --- /dev/null +++ b/jetty-server/src/main/config/etc/jetty-sessions.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/jetty-server/src/main/config/modules/jdbc-sessions.mod b/jetty-server/src/main/config/modules/jdbc-sessions.mod deleted file mode 100644 index 9fe2beba153..00000000000 --- a/jetty-server/src/main/config/modules/jdbc-sessions.mod +++ /dev/null @@ -1,25 +0,0 @@ -[description] -Enables JDBC Session management. - -[depend] -annotations -webapp - -[xml] -etc/jetty-jdbc-sessions.xml - -[ini-template] -## JDBC Session config - -## Unique identifier for this node in the cluster -# jetty.jdbcSession.workerName=node1 - -## The interval in seconds between sweeps of the scavenger -# jetty.jdbcSession.scavenge=600 - -## Uncomment either the datasource name or driverClass and connectionURL -# jetty.jdbcSession.datasource=sessions -# jetty.jdbcSession.driverClass=changeme -# jetty.jdbcSession.connectionURL=changeme - - diff --git a/jetty-server/src/main/config/modules/server.mod b/jetty-server/src/main/config/modules/server.mod index 19e21c56fe4..fde5d631bde 100644 --- a/jetty-server/src/main/config/modules/server.mod +++ b/jetty-server/src/main/config/modules/server.mod @@ -76,3 +76,8 @@ etc/jetty.xml ## Dump the state of the Jetty server, components, and webapps before shutdown # jetty.server.dumpBeforeStop=false +## The name to uniquely identify this server instance +#jetty.defaultSessionIdManager.workerName=node1 + +## How frequently sessions are inspected +#jetty.sessionInspectionInterval.seconds=60 diff --git a/jetty-server/src/main/config/modules/sessions.mod b/jetty-server/src/main/config/modules/sessions.mod new file mode 100644 index 00000000000..7c28a124e0e --- /dev/null +++ b/jetty-server/src/main/config/modules/sessions.mod @@ -0,0 +1,13 @@ +[description] +Enables basic sessions. + +[xml] +etc/jetty-sessions.xml + +[ini-template] + +## The name to uniquely identify this server instance +#jetty.sssionIdManager.workerName=node1 + +## How frequently sessions are inspected +#jetty.sessionInspectionInterval.seconds=60 diff --git a/jetty-server/src/main/example/filestore-example-context.xml b/jetty-server/src/main/example/filestore-example-context.xml new file mode 100644 index 00000000000..311807c9e13 --- /dev/null +++ b/jetty-server/src/main/example/filestore-example-context.xml @@ -0,0 +1,23 @@ + + + + + + + + + + seconds + + filename + boolean + + + seconds + seconds + + + + + + diff --git a/jetty-server/src/main/example/jdbc-example-context.xml b/jetty-server/src/main/example/jdbc-example-context.xml new file mode 100644 index 00000000000..fc075fd3e69 --- /dev/null +++ b/jetty-server/src/main/example/jdbc-example-context.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + seconds + + seconds + integer + boolean + + + + + driver class + URL + + + + + + JettySessions + sessionId + accessTime + contextPath + cookieTime + createTime + expiryTime + lastAccessTime + lastNode + lastSavedTime + map + maxInterval + virtualHost + + + + seconds + seconds + + + + + + diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java index e4b545e7e88..849000940ea 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionIdManager.java @@ -34,30 +34,25 @@ public interface SessionIdManager extends LifeCycle * @return True if the session ID is in use by at least one context. */ public boolean isIdInUse(String id); + /* ------------------------------------------------------------ */ /** - * Notify the sessionid manager that a particular session id is in use - * @param session the session whose id is being used + * Expire all sessions on all contexts that share the same id. + * + * @param id The session ID without any cluster node extension */ - public void useId (Session session); - - /* ------------------------------------------------------------ */ - /** - * Remove id - * @param id the plain session id (no workername extension) of the session to remove - * @return true if the id was removed, false otherwise - */ - public boolean removeId (String id); + public void expireAll(String id); /* ------------------------------------------------------------ */ /** * Invalidate all sessions on all contexts that share the same id. * - * @param id The session ID without any cluster node extension + * @param id */ - public void expireAll(String id); + public void invalidateAll (String id); + /* ------------------------------------------------------------ */ /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java index 071ed64340a..d227ab2c76a 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SessionManager.java @@ -312,4 +312,14 @@ public interface SessionManager extends LifeCycle public SessionStore getSessionStore(); + /** + * Check if id is in use by this manager + * + * @param id identity of session to check + * + * @return true if this manager knows about this id + */ + public boolean isIdInUse (String id) throws Exception; + + } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java index afa542f0fed..a0f02c36325 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStore.java @@ -146,4 +146,5 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme { _gracePeriodSec = sec; } + } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionStore.java index 8139a36f92c..415be8df4e4 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionStore.java @@ -90,16 +90,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements */ public abstract boolean doReplace (String id, Session oldValue, Session newValue); - - - /** - * Check to see if the session exists in the store - * @param id the id - * @return true if the Session object exists in the session store - */ - public abstract boolean doExists (String id); - - + /** * Remove the session with this identity from the store @@ -348,7 +339,6 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements catch (Exception e) { ex = e; //remember a problem happened loading the session - LOG.warn(e); doDelete(id); //remove the placeholder phsLock.close(); session = null; @@ -411,15 +401,24 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements if (_sessionDataStore == null) return null; //can't load it - - data =_sessionDataStore.load(id); - if (data == null) //session doesn't exist - return null; + try + { + data =_sessionDataStore.load(id); - session = newSession(data); - session.setSessionManager(_manager); - return session; + if (data == null) //session doesn't exist + return null; + + session = newSession(data); + session.setSessionManager(_manager); + return session; + } + catch (UnreadableSessionDataException e) + { + //can't load the session, delete it + _sessionDataStore.delete(id); + throw e; + } } /** @@ -512,14 +511,31 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements } /** - * Check to see if the session object exists in this store. + * Check to see if a session corresponding to the id exists. + * + * This method will first check with the object store. If it + * doesn't exist in the object store (might be passivated etc), + * it will check with the data store. + * @throws Exception * * @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String) */ @Override - public boolean exists(String id) + public boolean exists(String id) throws Exception { - return doExists(id); + //try the object store first + Session s = doGet(id); + if (s != null) + { + try (Lock lock = s.lock()) + { + //wait for the lock and check the validity of the session + return s.isValid(); + } + } + + //not there, so find out if session data exists for it + return _sessionDataStore.exists (id); } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java index 5248fd3be9a..7a252911f9f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/CachingSessionDataStore.java @@ -167,6 +167,13 @@ public class CachingSessionDataStore extends AbstractSessionDataStore return true; } - - + /** + * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) + */ + @Override + public boolean exists(String id) throws Exception + { + // TODO Auto-generated method stub + return false; + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java similarity index 89% rename from jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java rename to jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java index 5710059861f..7a2235b9a1c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/AbstractSessionIdManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java @@ -22,6 +22,7 @@ import java.security.SecureRandom; import java.util.HashSet; import java.util.Random; import java.util.Set; +import java.util.concurrent.atomic.AtomicLong; import javax.servlet.http.HttpServletRequest; @@ -43,11 +44,13 @@ import org.eclipse.jetty.util.log.Logger; * * There is only 1 session id manager per Server instance. */ -public abstract class AbstractSessionIdManager extends AbstractLifeCycle implements SessionIdManager +public class DefaultSessionIdManager extends AbstractLifeCycle implements SessionIdManager { private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); private final static String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId"; + + protected static final AtomicLong COUNTER = new AtomicLong(); protected Random _random; protected boolean _weakRandom; @@ -56,12 +59,13 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme protected long _reseed=100000L; protected Server _server; protected PeriodicSessionInspector _inspector; + /* ------------------------------------------------------------ */ /** * @param server the server associated with the id manager */ - public AbstractSessionIdManager(Server server) + public DefaultSessionIdManager(Server server) { _server = server; } @@ -71,7 +75,7 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme * @param server the server associated with the id manager * @param random a random number generator to use for ids */ - public AbstractSessionIdManager(Server server, Random random) + public DefaultSessionIdManager(Server server, Random random) { this(server); _random=random; @@ -226,7 +230,7 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme { // pick a new unique ID! String id=null; - while (id==null||id.length()==0||isIdInUse(id)) + while (id==null||id.length()==0) { long r0=_weakRandom ?(hashCode()^Runtime.getRuntime().freeMemory()^_random.nextInt()^((seedTerm)<<32)) @@ -262,6 +266,8 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme //NOTE this is different to the node suffix which denotes which node the request was received on if (_workerName!=null) id=_workerName + id; + + id = id+Long.toString(COUNTER.getAndIncrement()); } return id; @@ -269,7 +275,46 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String) + */ + @Override + public boolean isIdInUse(String id) + { + if (id == null) + return false; + + boolean inUse = false; + if (LOG.isDebugEnabled()) + LOG.debug("Checking {} is in use by at least one context",id); + + try + { + for (SessionManager manager:getSessionManagers()) + { + if (manager.isIdInUse(id)) + { + if (LOG.isDebugEnabled()) + LOG.debug("Context {} reports id in use", manager.getContext()); + inUse = true; + break; + } + } + + if (LOG.isDebugEnabled()) + LOG.debug("Checked {}, in use:", id, inUse); + return inUse; + } + catch (Exception e) + { + LOG.warn("Problem checking if id {} is in use", e); + return false; + } + } + + /* ------------------------------------------------------------ */ /** * @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart() @@ -379,19 +424,6 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme if (LOG.isDebugEnabled()) LOG.debug("Expiring {}",id); - //TODO handle cases: - //1. infinispan session id manager may not be able to remove id because it has timed out in infinispan but yet - //we want to remove a session object from the session store (session data store probably ok because it has same timeout as session id mgr entries) - //2. a session id manager may not know all session ids (ie subset in memory only) and therefore won't remove - //it, but it should be removed from the session data store (could it be in session store?) - //3. old sessions that no node is handling, eg after all restarted, but need to be removed from - //session data store, AND have listeners called on them. - //BUT want to avoid loading into memory sessions that this node is not managing (eg have 3 nodes all running session mgrs, - //all 3 find the expired session and load it into memory and expire it - removeId(id); - - //tell all contexts that may have a session object with this id to - //get rid of them for (SessionManager manager:getSessionManagers()) { manager.invalidate(id); @@ -399,11 +431,11 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme } /* ------------------------------------------------------------ */ + /** + * @param id + */ public void invalidateAll (String id) - { - //take the id out of the list of known sessionids for this node - removeId(id); - + { //tell all contexts that may have a session object with this id to //get rid of them for (SessionManager manager:getSessionManagers()) @@ -425,8 +457,8 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme //generate a new id String newClusterId = newSessionId(request.hashCode()); - removeId(oldClusterId);//remove the old one from the list - + //TODO how to handle request for old id whilst id change is happening? + //tell all contexts to update the id for (SessionManager manager:getSessionManagers()) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java index 68c6985055f..a00206d54fc 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/FileSessionDataStore.java @@ -117,9 +117,6 @@ public class FileSessionDataStore extends AbstractSessionDataStore @Override public Set doGetExpired(final Set candidates, final int expiryTimeoutSec) { - //we don't want to open up each file and check, so just leave it up to the SessionStore - //TODO as the session manager is likely to be a lazy loader, if a session is never requested, its - //file will stay forever after a restart final long now = System.currentTimeMillis(); HashSet expired = new HashSet(); @@ -273,6 +270,27 @@ public class FileSessionDataStore extends AbstractSessionDataStore return true; } + + + + /** + * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) + */ + @Override + public boolean exists(String id) throws Exception + { + File sessionFile = getFile(_storeDir, id); + if (sessionFile == null || !sessionFile.exists()) + return false; + + //check the expiry + long expiry = getExpiryFromFile(sessionFile); + if (expiry <= 0) + return true; //never expires + else + return (expiry > System.currentTimeMillis()); //hasn't yet expired + } + /* ------------------------------------------------------------ */ /** * @param os the output stream to save to @@ -318,6 +336,10 @@ public class FileSessionDataStore extends AbstractSessionDataStore return ""+data.getExpiry()+"_"+getFileName(data.getId()); } + /** + * @param file + * @return + */ private String getIdFromFile (File file) { if (file == null) @@ -326,6 +348,20 @@ public class FileSessionDataStore extends AbstractSessionDataStore return name.substring(name.lastIndexOf('_')+1); } + + /** + * @param file + * @return + */ + private long getExpiryFromFile (File file) + { + if (file == null) + return 0; + + String name = file.getName(); + String s = name.substring(0, name.indexOf('_')); + return (s==null?0:Long.parseLong(s)); + } /** diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java deleted file mode 100644 index a6948dc5e7f..00000000000 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/HashSessionIdManager.java +++ /dev/null @@ -1,77 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 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.server.session; - -import java.util.Set; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.ConcurrentHashSet; - -/** - * HashSessionIdManager - * - * - */ -public class HashSessionIdManager extends AbstractSessionIdManager -{ - /** - * @param server the server - */ - public HashSessionIdManager(Server server) - { - super(server); - } - - private final Set _ids = new ConcurrentHashSet(); - - - /** - * @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String) - */ - @Override - public boolean isIdInUse(String id) - { - return _ids.contains(id); - } - - - - /** - * @see org.eclipse.jetty.server.SessionIdManager#useId(org.eclipse.jetty.server.session.Session) - */ - @Override - public void useId(Session session) - { - if (session == null) - return; - - _ids.add(session.getId()); - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String) - */ - @Override - public boolean removeId(String id) - { - return _ids.remove(id); - } - -} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java index cb67d5de33d..8f5329b427c 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionDataStore.java @@ -1090,6 +1090,44 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore { return true; } + + + + + + /** + * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) + */ + @Override + public boolean exists(String id) + throws Exception + { + try (Connection connection = _dbAdaptor.getConnection()) + { + connection.setAutoCommit(true); + + //non-expired session exists? + try (PreparedStatement checkSessionExists = _sessionTableSchema.getCheckSessionExistsStatement(connection, _context.getCanonicalContextPath())) + { + _sessionTableSchema.fillCheckSessionExistsStatement (checkSessionExists, id, _context); + try (ResultSet result = checkSessionExists.executeQuery()) + { + if (!result.next()) + { + return false; //no such session + } + else + { + long expiry = result.getLong(_sessionTableSchema.getExpiryTimeColumn()); + if (expiry <= 0) //never expires + return true; + else + return (expiry > System.currentTimeMillis()); //hasn't already expired + } + } + } + } + } } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java deleted file mode 100644 index ebce29c1c29..00000000000 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionIdManager.java +++ /dev/null @@ -1,391 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 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.server.session; - -import java.sql.Connection; -import java.sql.DatabaseMetaData; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.HashSet; -import java.util.Random; - -import javax.servlet.http.HttpServletRequest; - -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.util.log.Log; -import org.eclipse.jetty.util.log.Logger; - - - -/** - * JDBCSessionIdManager - * - * SessionIdManager implementation that uses a database to store in-use session ids, - * to support distributed sessions. - * - */ -public class JDBCSessionIdManager extends org.eclipse.jetty.server.session.AbstractSessionIdManager -{ - private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session"); - - public final static int MAX_INTERVAL_NOT_SET = -999; - - protected final HashSet _sessionIds = new HashSet(); - protected Server _server; - protected PeriodicSessionInspector _scavenger; - - private DatabaseAdaptor _dbAdaptor = new DatabaseAdaptor(); - - protected SessionIdTableSchema _sessionIdTableSchema = new SessionIdTableSchema(); - - /** - * SessionIdTableSchema - * - */ - public static class SessionIdTableSchema - { - protected String _tableName = "JettySessionIds"; - protected String _idColumn = "id"; - protected DatabaseAdaptor _jdbc; - - public String getIdColumn() - { - return _idColumn; - } - - public void setIdColumn(String idColumn) - { - checkNotNull(idColumn); - _idColumn = idColumn; - } - - public String getTableName() - { - return _tableName; - } - - public void setTableName(String tableName) - { - checkNotNull(tableName); - _tableName = tableName; - } - - public String getInsertStatementAsString () - { - return "insert into "+_tableName+" ("+_idColumn+") values (?)"; - } - - public String getDeleteStatementAsString () - { - return "delete from "+_tableName+" where "+_idColumn+" = ?"; - } - - public String getSelectStatementAsString () - { - return "select * from "+_tableName+" where "+_idColumn+" = ?"; - } - - public String getCreateStatementAsString () - { - return "create table "+_tableName+" ("+_idColumn+" varchar(120), primary key("+_idColumn+"))"; - } - - protected void prepareTables (DatabaseAdaptor jdbc) - throws Exception - { - _jdbc = jdbc; - try (Connection connection = _jdbc.getConnection(); - Statement statement = connection.createStatement()) - { - //make the id table - connection.setAutoCommit(true); - DatabaseMetaData metaData = connection.getMetaData(); - _jdbc.adaptTo(metaData); - - - //checking for table existence is case-sensitive, but table creation is not - String tableName = _jdbc.convertIdentifier(getTableName()); - try (ResultSet result = metaData.getTables(null, null, tableName, null)) - { - if (!result.next()) - { - //table does not exist, so create it - statement.executeUpdate(getCreateStatementAsString()); - } - } - } - } - - private void checkNotNull(String s) - { - if (s == null) - throw new IllegalArgumentException(s); - } - } - - - public JDBCSessionIdManager(Server server) - { - super(server); - } - - public JDBCSessionIdManager(Server server, Random random) - { - super(server,random); - } - - public SessionIdTableSchema getSessionIdTableSchema() - { - return _sessionIdTableSchema; - } - - - - - - /** - * @see org.eclipse.jetty.server.SessionIdManager#useId(org.eclipse.jetty.server.session.Session) - */ - @Override - public void useId (Session session) - { - if (session == null) - return; - - synchronized (_sessionIds) - { - String id = session.getId(); - try - { - insert(id); - _sessionIds.add(id); - } - catch (Exception e) - { - LOG.warn("Problem storing session id="+id, e); - } - } - } - - - - - /** - * Remove the id from in-use set - * - * Prevents another context from using this id - * - * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String) - */ - @Override - public boolean removeId (String id) - { - - if (id == null) - return false; - - synchronized (_sessionIds) - { - if (LOG.isDebugEnabled()) - LOG.debug("Removing sessionid="+id); - try - { - boolean remove = _sessionIds.remove(id); - boolean dbremove = delete(id); - return remove || dbremove; - } - catch (Exception e) - { - LOG.warn("Problem removing session id="+id, e); - return false; - } - } - - } - - /** - * Insert a new used session id into the table. - * - * @param id the id to put into the table - * @throws SQLException - */ - private void insert (String id) - throws SQLException - { - try (Connection connection = _dbAdaptor.getConnection(); - PreparedStatement query = connection.prepareStatement(_sessionIdTableSchema.getSelectStatementAsString())) - { - connection.setAutoCommit(true); - query.setString(1, id); - try (ResultSet result = query.executeQuery()) - { - //only insert the id if it isn't in the db already - if (!result.next()) - { - try (PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getInsertStatementAsString())) - { - statement.setString(1, id); - statement.executeUpdate(); - } - } - } - } - } - - /** - * Remove a session id from the table. - * - * @param id the id to remove from the table - * @throws SQLException - */ - private boolean delete (String id) - throws SQLException - { - try (Connection connection = _dbAdaptor.getConnection(); - PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getDeleteStatementAsString())) - { - connection.setAutoCommit(true); - statement.setString(1, id); - return (statement.executeUpdate() > 0); - } - } - - - /** - * Check if a session id exists. - * - * @param id the id to check - * @return true if the id exists in the table, false otherwise - * @throws SQLException - */ - private boolean exists (String id) - throws SQLException - { - try (Connection connection = _dbAdaptor.getConnection(); - PreparedStatement statement = connection.prepareStatement(_sessionIdTableSchema.getSelectStatementAsString())) - { - connection.setAutoCommit(true); - statement.setString(1, id); - try (ResultSet result = statement.executeQuery()) - { - return result.next(); - } - } - } - - - @Override - public boolean isIdInUse(String id) - { - if (id == null) - return false; - - String sessionId = getId(id); - boolean inUse = false; - synchronized (_sessionIds) - { - inUse = _sessionIds.contains(sessionId); - } - - - if (inUse) - return true; //optimisation - if this session is one we've been managing, we can check locally - - //otherwise, we need to go to the database to check - try - { - return exists(sessionId); - } - catch (Exception e) - { - LOG.warn("Problem checking inUse for id="+sessionId, e); - return false; - } - } - - - /** - * Invalidate the session matching the id on all contexts. - * - * @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String) - */ - @Override - public void expireAll(String id) - { - synchronized (_sessionIds) - { - super.expireAll(id); - } - } - - - - @Override - public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request) - { - synchronized (_sessionIds) - { - super.renewSessionId(oldClusterId, oldNodeId, request); - } - } - - /** - * Get the database adaptor in order to configure it - * @return the database adpator - */ - public DatabaseAdaptor getDatabaseAdaptor () - { - return _dbAdaptor; - } - - - - - /** - * Start up the id manager. - * - * Makes necessary database tables and starts a Session - * scavenger thread. - */ - @Override - public void doStart() - throws Exception - { - _dbAdaptor.initialize(); - _sessionIdTableSchema.prepareTables(_dbAdaptor); - - super.doStart(); - - } - - /** - * Stop - */ - @Override - public void doStop () - throws Exception - { - _sessionIds.clear(); - - super.doStop(); - } - -} diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java index 83b6c9ee600..8395d99a47e 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/JDBCSessionManager.java @@ -26,13 +26,11 @@ package org.eclipse.jetty.server.session; public class JDBCSessionManager extends SessionManager { - protected DatabaseAdaptor _db; protected JDBCSessionDataStore _sessionDataStore; public JDBCSessionManager() { - _db = new DatabaseAdaptor(); _sessionStore = new MemorySessionStore(); _sessionDataStore = new JDBCSessionDataStore(); } @@ -40,7 +38,6 @@ public class JDBCSessionManager extends SessionManager @Override public void doStart() throws Exception { - _sessionDataStore.setDatabaseAdaptor(_db); ((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore); super.doStart(); @@ -53,14 +50,7 @@ public class JDBCSessionManager extends SessionManager } - /** - * Get the db adaptor to configure jdbc settings - * @return the database adaptor - */ - public DatabaseAdaptor getDatabaseAdaptor() - { - return _db; - } + /** * Get the SessionDataStore to configure it diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemorySessionStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemorySessionStore.java index 046f228d8ee..de307fb53ed 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemorySessionStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/MemorySessionStore.java @@ -129,14 +129,7 @@ public class MemorySessionStore extends AbstractSessionStore return s; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionStore#doExists(java.lang.String) - */ - @Override - public boolean doExists(String id) - { - return _sessions.containsKey(id); - } + /** * @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(java.lang.String) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java index 9b0e1144cfd..b03516a8d45 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/NullSessionDataStore.java @@ -87,4 +87,14 @@ public class NullSessionDataStore extends AbstractSessionDataStore return false; } + + /** + * @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String) + */ + @Override + public boolean exists(String id) + { + return false; + } + } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/PeriodicSessionInspector.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/PeriodicSessionInspector.java index afc40674d30..bf1254c189f 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/PeriodicSessionInspector.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/PeriodicSessionInspector.java @@ -93,12 +93,12 @@ public class PeriodicSessionInspector extends AbstractLifeCycle if (_sessionIdManager == null) throw new IllegalStateException ("No SessionIdManager for Scavenger"); - if (!(_sessionIdManager instanceof AbstractSessionIdManager)) + if (!(_sessionIdManager instanceof DefaultSessionIdManager)) throw new IllegalStateException ("SessionIdManager is not an AbstractSessionIdManager"); //try and use a common scheduler, fallback to own - _scheduler = ((AbstractSessionIdManager)_sessionIdManager).getServer().getBean(Scheduler.class); + _scheduler = ((DefaultSessionIdManager)_sessionIdManager).getServer().getBean(Scheduler.class); if (_scheduler == null) { @@ -199,7 +199,7 @@ public class PeriodicSessionInspector extends AbstractLifeCycle LOG.debug("Inspecting sessions"); //find the session managers - for (SessionManager manager:((AbstractSessionIdManager)_sessionIdManager).getSessionManagers()) + for (SessionManager manager:((DefaultSessionIdManager)_sessionIdManager).getSessionManagers()) { if (manager != null) { diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java index 2c260a92364..bf0593116e2 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/Session.java @@ -452,10 +452,10 @@ public class Session implements SessionManager.SessionIf checkLocked(); if (_state != State.VALID) - throw new IllegalStateException(); + throw new IllegalStateException("Not valid for write: id="+_sessionData.getId()+" created="+_sessionData.getCreated()+" accessed="+_sessionData.getAccessed()+" lastaccessed="+_sessionData.getLastAccessed()+" maxInactiveMs="+_sessionData.getMaxInactiveMs()+" expiry="+_sessionData.getExpiry()); if (_passivationState == PassivationState.PASSIVATED) - throw new IllegalStateException("Passivated"); + throw new IllegalStateException("Not valid for write: id="+_sessionData.getId()+" passivated"); } @@ -469,10 +469,10 @@ public class Session implements SessionManager.SessionIf checkLocked(); if (_state == State.INVALID) - throw new IllegalStateException("Invalid"); + throw new IllegalStateException("Invalid for read: id="+_sessionData.getId()+" created="+_sessionData.getCreated()+" accessed="+_sessionData.getAccessed()+" lastaccessed="+_sessionData.getLastAccessed()+" maxInactiveMs="+_sessionData.getMaxInactiveMs()+" expiry="+_sessionData.getExpiry()); if (_passivationState == PassivationState.PASSIVATED) - throw new IllegalStateException("Passivated"); + throw new IllegalStateException("Invalid for read: id="+_sessionData.getId()+" passivated"); } @@ -723,7 +723,7 @@ public class Session implements SessionManager.SessionIf if (result) { //tell id mgr to remove session from all other contexts - ((AbstractSessionIdManager)_manager.getSessionIdManager()).invalidateAll(_sessionData.getId()); + ((DefaultSessionIdManager)_manager.getSessionIdManager()).invalidateAll(_sessionData.getId()); } } catch (Exception e) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java index b7ffd1edd95..57944f9bcdd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionDataStore.java @@ -106,4 +106,15 @@ public interface SessionDataStore extends LifeCycle */ public boolean isPassivating (); + + /** + * Test if data exists for a given session id. + * + * @param id Identity of session whose existance should be checked + * + * @return true if valid, non-expired session exists + * @throws Exception if problem checking existance with persistence layer + */ + public boolean exists (String id) throws Exception; + } diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionManager.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionManager.java index 31052aad4d1..7aa280ab5a1 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionManager.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionManager.java @@ -267,7 +267,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je try { Thread.currentThread().setContextClassLoader(serverLoader); - _sessionIdManager=new HashSessionIdManager(server); + _sessionIdManager=new DefaultSessionIdManager(server); server.setSessionIdManager(_sessionIdManager); server.manage(_sessionIdManager); _sessionIdManager.start(); @@ -595,7 +595,6 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je { _sessionStore.put(id, session); _sessionsCreatedStats.increment(); - _sessionIdManager.useId(session); if (_sessionListeners!=null) { @@ -749,9 +748,15 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je catch (UnreadableSessionDataException e) { LOG.warn(e); - //Could not retrieve the session with the given id - //Tell the session id manager that the session id is not to be used by any other threads/contexts - _sessionIdManager.removeId(id); + try + { + //tell id mgr to remove session from all other contexts + getSessionIdManager().invalidateAll(id); + } + catch (Exception x) + { + LOG.warn("Error cross-context invalidating unreadable session {}", id, x); + } return null; } catch (Exception other) @@ -967,7 +972,6 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je } session.setExtendedId(newExtendedId); //remember the extended id - _sessionIdManager.useId(session); //tell id manager new id is in use //inform the listeners if (!_sessionIdListeners.isEmpty()) @@ -978,36 +982,6 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je l.sessionIdChanged(event, oldId); } } - - /* Session session =_sessionStore.get(oldId); - if (session == null) - { - LOG.warn("Unable to renew id to "+newId+" for non-existant session "+oldId); - return; - } - - try (Lock lock = session.lock()) - { - //swap the ids - session.renewId(oldId, oldExtendedId, newId, newExtendedId); - - _sessionStore.put(newId, session); - - //tell session id manager the id is in use - _sessionIdManager.useId(session); - - //inform the listeners - if (!_sessionIdListeners.isEmpty()) - { - HttpSessionEvent event = new HttpSessionEvent(session); - for (HttpSessionIdListener l:_sessionIdListeners) - { - l.sessionIdChanged(event, oldId); - } - } - - - }*/ } catch (Exception e) { @@ -1048,6 +1022,9 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je /* ------------------------------------------------------------ */ + /** + * + */ public void inspect () { //don't attempt to scavenge if we are shutting down @@ -1057,7 +1034,26 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je _sessionStore.inspect(); } - + + + + + /* ------------------------------------------------------------ */ + /** + * @see org.eclipse.jetty.server.SessionManager#isIdInUse(java.lang.String) + */ + @Override + public boolean isIdInUse(String id) throws Exception + { + //Ask the session store + return _sessionStore.exists(id); + } + + + + + + /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ /* ------------------------------------------------------------ */ diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionStore.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionStore.java index 137fe41ae25..9c281b416dd 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionStore.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionStore.java @@ -52,4 +52,5 @@ public interface SessionStore extends LifeCycle int getExpiryTimeoutSec(); void setExpiryTimeoutSec(int sec); Stream getStream(); + SessionDataStore getSessionDataStore(); } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java index 911608abf65..f11a55fff8e 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ResponseTest.java @@ -54,7 +54,7 @@ import org.eclipse.jetty.io.RuntimeIOException; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.ContextHandler; import org.eclipse.jetty.server.handler.ErrorHandler; -import org.eclipse.jetty.server.session.HashSessionIdManager; +import org.eclipse.jetty.server.session.DefaultSessionIdManager; import org.eclipse.jetty.server.session.HashSessionManager; import org.eclipse.jetty.server.session.Session; import org.eclipse.jetty.server.session.SessionData; @@ -511,7 +511,7 @@ public class ResponseTest request.setRequestedSessionId("12345"); request.setRequestedSessionIdFromCookie(false); HashSessionManager manager = new HashSessionManager(); - manager.setSessionIdManager(new HashSessionIdManager(_server)); + manager.setSessionIdManager(new DefaultSessionIdManager(_server)); request.setSessionManager(manager); TestSession tsession = new TestSession(manager, "12345"); tsession.setExtendedId(manager.getSessionIdManager().getExtendedId("12345", null)); @@ -588,7 +588,7 @@ public class ResponseTest request.setRequestedSessionId("12345"); request.setRequestedSessionIdFromCookie(i>2); HashSessionManager manager = new HashSessionManager(); - manager.setSessionIdManager(new HashSessionIdManager(_server)); + manager.setSessionIdManager(new DefaultSessionIdManager(_server)); request.setSessionManager(manager); request.setSession(new TestSession(manager, "12345")); manager.setCheckingRemoteSessionIdEncoding(false); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/FileSessionManagerTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/FileSessionManagerTest.java index fd87221bad6..94ec11c86a8 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/FileSessionManagerTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/FileSessionManagerTest.java @@ -61,7 +61,7 @@ public class FileSessionManagerTest Server server = new Server(); SessionHandler handler = new SessionHandler(); handler.setServer(server); - final HashSessionIdManager idmgr = new HashSessionIdManager(server); + final DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server); idmgr.setServer(server); server.setSessionIdManager(idmgr); @@ -94,7 +94,7 @@ public class FileSessionManagerTest Server server = new Server(); SessionHandler handler = new SessionHandler(); handler.setServer(server); - final HashSessionIdManager idmgr = new HashSessionIdManager(server); + final DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server); idmgr.setServer(server); server.setSessionIdManager(idmgr); final FileSessionManager manager = new FileSessionManager(); @@ -135,7 +135,7 @@ public class FileSessionManagerTest Assert.assertTrue(testDir.canWrite()); handler.setSessionManager(manager); - AbstractSessionIdManager idManager = new HashSessionIdManager(server); + DefaultSessionIdManager idManager = new DefaultSessionIdManager(server); idManager.setServer(server); idManager.setWorkerName("foo"); manager.setSessionIdManager(idManager); diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java index f7ab4636360..1f56697704f 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/session/SessionCookieTest.java @@ -90,15 +90,7 @@ public class SessionCookieTest return null; } - /** - * @see org.eclipse.jetty.server.session.AbstractSessionStore#doExists(String) - */ - @Override - public boolean doExists(String key) - { - // TODO Auto-generated method stub - return false; - } + /** * @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(String) @@ -134,7 +126,7 @@ public class SessionCookieTest - public class MockSessionIdManager extends AbstractSessionIdManager + public class MockSessionIdManager extends DefaultSessionIdManager { public MockSessionIdManager(Server server) { @@ -165,25 +157,6 @@ public class SessionCookieTest // TODO Auto-generated method stub } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#useId(Session) - */ - @Override - public void useId(Session session) - { - // TODO Auto-generated method stub - - } - - /** - * @see org.eclipse.jetty.server.SessionIdManager#removeId(java.lang.String) - */ - @Override - public boolean removeId(String id) - { - return true; - } } public class MockSessionManager extends SessionManager diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestServer.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestServer.java index ab97a547324..2b7abb69d63 100644 --- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestServer.java +++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileTestServer.java @@ -133,7 +133,7 @@ public class FileTestServer extends AbstractTestServer public SessionIdManager newSessionIdManager(Object config) { - HashSessionIdManager mgr = new HashSessionIdManager(_server); + DefaultSessionIdManager mgr = new DefaultSessionIdManager(_server); mgr.setWorkerName("worker"+(__workers++)); return mgr; } diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java index 09d072e64b0..470db440198 100644 --- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java +++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java @@ -22,6 +22,7 @@ import java.io.File; import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.webapp.WebAppContext; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -58,7 +59,7 @@ public class SessionRenewTest extends AbstractSessionRenewTest * @see org.eclipse.jetty.server.session.AbstractSessionRenewTest#verifyChange(java.lang.String, java.lang.String) */ @Override - public boolean verifyChange(String oldSessionId, String newSessionId) + public boolean verifyChange(WebAppContext context, String oldSessionId, String newSessionId) { ((FileTestServer)_server).assertFileExists(oldSessionId, false); ((FileTestServer)_server).assertFileExists(newSessionId, true); diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java index ec9d79ca988..d983bd7d87b 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudTestServer.java @@ -23,6 +23,7 @@ import org.eclipse.jetty.server.SessionIdManager; import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.server.session.AbstractSessionStore; import org.eclipse.jetty.server.session.AbstractTestServer; +import org.eclipse.jetty.server.session.DefaultSessionIdManager; import org.eclipse.jetty.server.session.SessionHandler; import org.eclipse.jetty.server.session.StalePeriodStrategy; @@ -36,14 +37,12 @@ import com.google.gcloud.datastore.DatastoreFactory; */ public class GCloudTestServer extends AbstractTestServer { - static int __workers=0; - static protected int __maxInactivePeriod = 30; static protected int __scavengePeriod = 10; static protected int __inspectPeriod = 1; static protected int __idlePeriod = 2; - + /** * @param port @@ -65,17 +64,7 @@ public class GCloudTestServer extends AbstractTestServer super(port, 30,10, __inspectPeriod, __idlePeriod, configuration); } - /** - * @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionIdManager(java.lang.Object) - */ - @Override - public SessionIdManager newSessionIdManager(Object config) - { - GCloudSessionIdManager idManager = new GCloudSessionIdManager(getServer()); - idManager.setWorkerName("w"+(__workers++)); - idManager.setConfig((GCloudConfiguration)config); - return idManager; - } + /** * @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionManager() @@ -84,8 +73,8 @@ public class GCloudTestServer extends AbstractTestServer public SessionManager newSessionManager() { GCloudSessionManager sessionManager = new GCloudSessionManager(); - sessionManager.setSessionIdManager((GCloudSessionIdManager)_sessionIdManager); - sessionManager.getSessionDataStore().setGCloudConfiguration(((GCloudSessionIdManager)_sessionIdManager).getConfig()); + sessionManager.setSessionIdManager(_sessionIdManager); + sessionManager.getSessionDataStore().setGCloudConfiguration((GCloudConfiguration)_config); return sessionManager; } diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionRenewTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionRenewTest.java index 8cae9174aac..f152038e000 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionRenewTest.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/SessionRenewTest.java @@ -23,6 +23,8 @@ import java.util.Set; import org.eclipse.jetty.server.session.AbstractSessionRenewTest; import org.eclipse.jetty.server.session.AbstractTestServer; +import org.eclipse.jetty.webapp.WebAppContext; + import static org.junit.Assert.fail; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -70,7 +72,7 @@ public class SessionRenewTest extends AbstractSessionRenewTest * @see org.eclipse.jetty.server.session.AbstractSessionRenewTest#verifyChange(java.lang.String, java.lang.String) */ @Override - public boolean verifyChange(String oldSessionId, String newSessionId) + public boolean verifyChange(WebAppContext context, String oldSessionId, String newSessionId) { try { diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java index fe811a4c1e5..1a761633a14 100644 --- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java +++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/HashTestServer.java @@ -39,13 +39,6 @@ public class HashTestServer extends AbstractTestServer } - public SessionIdManager newSessionIdManager(Object config) - { - HashSessionIdManager mgr = new HashSessionIdManager(_server); - mgr.setWorkerName("worker"+(__workers++)); - return mgr; - } - public SessionManager newSessionManager() { HashSessionManager manager = new HashSessionManager(); diff --git a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java index 03b39629d43..f61321a0e18 100644 --- a/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java +++ b/tests/test-sessions/test-hash-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java @@ -22,6 +22,7 @@ import java.io.File; import org.eclipse.jetty.server.SessionManager; import org.eclipse.jetty.util.IO; +import org.eclipse.jetty.webapp.WebAppContext; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -45,7 +46,7 @@ public class SessionRenewTest extends AbstractSessionRenewTest * @see org.eclipse.jetty.server.session.AbstractSessionRenewTest#verifyChange(java.lang.String, java.lang.String) */ @Override - public boolean verifyChange(String oldSessionId, String newSessionId) + public boolean verifyChange(WebAppContext context ,String oldSessionId, String newSessionId) { return true; //no other tests possible, sessions only in memory } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java index cd2170743c6..a17f44bae19 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSessionServer.java @@ -21,18 +21,15 @@ package org.eclipse.jetty.server.session; import org.eclipse.jetty.server.SessionIdManager; import org.eclipse.jetty.server.SessionManager; -import org.eclipse.jetty.session.infinispan.InfinispanSessionIdManager; +import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStore; import org.eclipse.jetty.session.infinispan.InfinispanSessionManager; +import org.eclipse.jetty.webapp.WebAppContext; import org.infinispan.Cache; import org.infinispan.commons.api.BasicCache; import org.infinispan.commons.util.CloseableIteratorSet; public class InfinispanTestSessionServer extends AbstractTestServer { - static int __workers=0; - - - public InfinispanTestSessionServer(int port, BasicCache config) @@ -49,22 +46,11 @@ public class InfinispanTestSessionServer extends AbstractTestServer - @Override - public SessionIdManager newSessionIdManager(Object config) - { - InfinispanSessionIdManager idManager = new InfinispanSessionIdManager(getServer()); - idManager.setWorkerName("w"+(__workers++)); - idManager.setCache((BasicCache)config); - idManager.setInfinispanIdleTimeoutSec(0); - return idManager; - } - @Override public SessionManager newSessionManager() { InfinispanSessionManager sessionManager = new InfinispanSessionManager(); - sessionManager.setSessionIdManager((InfinispanSessionIdManager)_sessionIdManager); - sessionManager.getSessionDataStore().setCache(((InfinispanSessionIdManager)_sessionIdManager).getCache()); + sessionManager.getSessionDataStore().setCache((BasicCache)_config); return sessionManager; } @@ -74,23 +60,23 @@ public class InfinispanTestSessionServer extends AbstractTestServer return new SessionHandler(sessionManager); } - public boolean exists (String id) + public boolean exists (WebAppContext context, String id) { - BasicCache cache = ((InfinispanSessionIdManager)_sessionIdManager).getCache(); + BasicCache cache = (BasicCache)_config; if (cache != null) { - return cache.containsKey(((InfinispanSessionIdManager)_sessionIdManager).makeKey(id)); + return cache.containsKey(((InfinispanSessionDataStore)(context.getSessionHandler().getSessionManager().getSessionStore().getSessionDataStore())).getCacheKey(id)); } return false; } - public Object get (String id) + public Object get (WebAppContext context, String id) { - BasicCache cache = ((InfinispanSessionIdManager)_sessionIdManager).getCache(); + BasicCache cache = (BasicCache)_config; if (cache != null) { - return cache.get(((InfinispanSessionIdManager)_sessionIdManager).makeKey(id)); + return cache.get(((InfinispanSessionDataStore)(context.getSessionHandler().getSessionManager().getSessionStore().getSessionDataStore())).getCacheKey(id)); } return null; @@ -98,7 +84,7 @@ public class InfinispanTestSessionServer extends AbstractTestServer public void dumpCache () { - BasicCache cache = ((InfinispanSessionIdManager)_sessionIdManager).getCache(); + BasicCache cache = (BasicCache)_config; if (cache != null) { System.err.println(cache.getName()+" contains "+cache.size()+" entries"); @@ -106,8 +92,9 @@ public class InfinispanTestSessionServer extends AbstractTestServer } public void clearCache () - { - BasicCache cache = ((InfinispanSessionIdManager)_sessionIdManager).getCache(); + { + BasicCache cache = (BasicCache)_config; + if (cache != null) cache.clear(); } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java index fee15c4b523..b34b341c02a 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java @@ -20,6 +20,9 @@ package org.eclipse.jetty.server.session; import static org.junit.Assert.assertTrue; + +import org.eclipse.jetty.webapp.WebAppContext; + import static org.junit.Assert.assertFalse; import org.junit.AfterClass; import org.junit.BeforeClass; @@ -69,11 +72,11 @@ public class SessionRenewTest extends AbstractSessionRenewTest * @see org.eclipse.jetty.server.session.AbstractSessionRenewTest#verifyChange(java.lang.String, java.lang.String) */ @Override - public boolean verifyChange(String oldSessionId, String newSessionId) + public boolean verifyChange(WebAppContext context, String oldSessionId, String newSessionId) { - assertTrue(((InfinispanTestSessionServer)_server).exists(newSessionId)); - assertFalse(((InfinispanTestSessionServer)_server).exists(oldSessionId)); - return (!((InfinispanTestSessionServer)_server).exists(oldSessionId)) && ((InfinispanTestSessionServer)_server).exists(newSessionId); + assertTrue(((InfinispanTestSessionServer)_server).exists(context, newSessionId)); + assertFalse(((InfinispanTestSessionServer)_server).exists(context, oldSessionId)); + return (!((InfinispanTestSessionServer)_server).exists(context, oldSessionId)) && ((InfinispanTestSessionServer)_server).exists(context, newSessionId); } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteSessionRenewTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteSessionRenewTest.java index 09bb75acb2f..f5bed51fb98 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteSessionRenewTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteSessionRenewTest.java @@ -22,6 +22,7 @@ package org.eclipse.jetty.server.session.remote; import org.eclipse.jetty.server.session.AbstractSessionRenewTest; import org.eclipse.jetty.server.session.AbstractTestServer; import org.eclipse.jetty.server.session.InfinispanTestSessionServer; +import org.eclipse.jetty.webapp.WebAppContext; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.Test; @@ -70,8 +71,8 @@ public class RemoteSessionRenewTest extends AbstractSessionRenewTest * @see org.eclipse.jetty.server.session.AbstractSessionRenewTest#verifyChange(java.lang.String, java.lang.String) */ @Override - public boolean verifyChange(String oldSessionId, String newSessionId) + public boolean verifyChange(WebAppContext context, String oldSessionId, String newSessionId) { - return !((InfinispanTestSessionServer)_server).exists(oldSessionId) && ((InfinispanTestSessionServer)_server).exists(newSessionId); + return !((InfinispanTestSessionServer)_server).exists(context, oldSessionId) && ((InfinispanTestSessionServer)_server).exists(context, newSessionId); } } diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java index 8dd17af8565..5ec0ac44dda 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JdbcTestServer.java @@ -105,26 +105,7 @@ public class JdbcTestServer extends AbstractTestServer return new SessionHandler(sessionManager); } - static int __workers=0; - - /** - * @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionIdManager(String) - */ - @Override - public SessionIdManager newSessionIdManager(Object config) - { - synchronized(JdbcTestServer.class) - { - JDBCSessionIdManager idManager = new JDBCSessionIdManager(_server); - idManager.setWorkerName("w"+(__workers++)); - idManager.getDatabaseAdaptor().setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:(String)config)); - JDBCSessionIdManager.SessionIdTableSchema idTableSchema = idManager.getSessionIdTableSchema(); - idTableSchema.setTableName("mysessionids"); - idTableSchema.setIdColumn("myid"); - return idManager; - } - } - + /** * @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionManager() */ @@ -135,10 +116,11 @@ public class JdbcTestServer extends AbstractTestServer public SessionManager newSessionManager() { JDBCSessionManager manager = new JDBCSessionManager(); - manager.setSessionIdManager((JDBCSessionIdManager)_sessionIdManager); JDBCSessionDataStore ds = manager.getSessionDataStore(); ds.setGracePeriodSec(_inspectionPeriod); - manager.getDatabaseAdaptor().setDriverInfo(DRIVER_CLASS, DEFAULT_CONNECTION_URL); + DatabaseAdaptor da = new DatabaseAdaptor(); + da.setDriverInfo(DRIVER_CLASS, (_config==null?DEFAULT_CONNECTION_URL:(String)_config)); + ds.setDatabaseAdaptor(da); JDBCSessionDataStore.SessionTableSchema sessionTableSchema = new JDBCSessionDataStore.SessionTableSchema(); sessionTableSchema.setTableName(TABLE); sessionTableSchema.setIdColumn(ID_COL); @@ -156,28 +138,7 @@ public class JdbcTestServer extends AbstractTestServer return manager; } - - public boolean existsInSessionIdTable(String id) - throws Exception - { - Class.forName(DRIVER_CLASS); - Connection con = null; - try - { - con = DriverManager.getConnection(DEFAULT_CONNECTION_URL); - PreparedStatement statement = con.prepareStatement("select * from "+ - ((JDBCSessionIdManager)_sessionIdManager)._sessionIdTableSchema.getTableName()+ - " where "+((JDBCSessionIdManager)_sessionIdManager)._sessionIdTableSchema.getIdColumn()+" = ?"); - statement.setString(1, id); - ResultSet result = statement.executeQuery(); - return result.next(); - } - finally - { - if (con != null) - con.close(); - } - } + public boolean existsInSessionTable(String id, boolean verbose) @@ -223,8 +184,7 @@ public class JdbcTestServer extends AbstractTestServer try { con = DriverManager.getConnection(DEFAULT_CONNECTION_URL); - PreparedStatement statement = con.prepareStatement("select * from "+((JDBCSessionIdManager)_sessionIdManager)._sessionIdTableSchema.getTableName()); - + PreparedStatement statement = con.prepareStatement("select "+ID_COL+" from "+TABLE); ResultSet result = statement.executeQuery(); while (result.next()) { diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java index eb916b3f394..95919d3521b 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/ReloadedSessionMissingClassTest.java @@ -122,12 +122,12 @@ public class ReloadedSessionMissingClassTest Request request = client.newRequest("http://localhost:" + port1 + contextPath + "/bar?action=get"); request.header("Cookie", sessionCookie); response = request.send(); - assertEquals(HttpServletResponse.SC_OK,response.getStatus()); + assertEquals(HttpServletResponse.SC_OK,response.getStatus()); + String afterStopSessionId = (String)webApp.getServletContext().getAttribute("foo.session"); Boolean fooPresent = (Boolean)webApp.getServletContext().getAttribute("foo.present"); assertFalse(fooPresent); assertNotNull(afterStopSessionId); - assertFalse(fooPresent); assertTrue(!afterStopSessionId.equals(sessionId)); } diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java index 26c3caea491..c891464d2c1 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionRenewTest.java @@ -21,6 +21,8 @@ package org.eclipse.jetty.server.session; import static org.junit.Assert.assertTrue; import static org.junit.Assert.assertFalse; import static org.junit.Assert.fail; + +import org.eclipse.jetty.webapp.WebAppContext; import org.junit.After; import org.junit.Test; @@ -39,7 +41,7 @@ public class SessionRenewTest extends AbstractSessionRenewTest * @see org.eclipse.jetty.server.session.AbstractSessionRenewTest#verifyChange(java.lang.String, java.lang.String) */ @Override - public boolean verifyChange(String oldSessionId, String newSessionId) + public boolean verifyChange(WebAppContext context, String oldSessionId, String newSessionId) { try { diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java index 25298f933aa..db8d1ebced2 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoTestServer.java @@ -79,20 +79,6 @@ public class MongoTestServer extends AbstractTestServer super(port, maxInactivePeriod, scavengePeriod, inspectionPeriod, idlePassivatePeriod); } - public SessionIdManager newSessionIdManager(Object config) - { - try - { - MongoSessionIdManager idManager = new MongoSessionIdManager(_server, getCollection()); - idManager.setWorkerName("w"+(__workers++)); - - return idManager; - } - catch (Exception e) - { - throw new RuntimeException(e); - } - } public SessionManager newSessionManager() { @@ -100,6 +86,7 @@ public class MongoTestServer extends AbstractTestServer try { manager = new MongoSessionManager(); + ((MongoSessionManager)manager).getSessionDataStore().setDBCollection(getCollection()); manager.getSessionDataStore().setGracePeriodSec(_inspectionPeriod); } catch (Exception e) diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java deleted file mode 100644 index a80506583ee..00000000000 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeInvalidSessionTest.java +++ /dev/null @@ -1,260 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 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.nosql.mongodb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.UnknownHostException; - -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 org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.junit.Ignore; - -import com.mongodb.BasicDBObject; -import com.mongodb.DBCollection; -import com.mongodb.DBObject; -import com.mongodb.Mongo; -import com.mongodb.MongoException; - -/** - * PurgeInvalidSessionTest - * - * - * - */ -public class PurgeInvalidSessionTest -{ - public MongoTestServer createServer(int port, int max, int scavenge) - { - MongoTestServer server = new MongoTestServer(port,max,scavenge); - - return server; - } - - - - @Ignore - public void testPurgeInvalidSession() throws Exception - { - String contextPath = ""; - String servletMapping = "/server"; - long purgeDelay = 1000; //1 sec - long purgeInvalidAge = 1000; //1 sec - long purgeValidAge = 1000; - - //ensure scavenging is turned off so the purger gets a chance to find the session - MongoTestServer server = createServer(0, 1, 0); - ServletContextHandler context = server.addContext(contextPath); - context.addServlet(TestServlet.class, servletMapping); - - MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager(); - MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager(); - /* idManager.setPurge(true); - idManager.setPurgeDelay(purgeDelay); - idManager.setPurgeInvalidAge(purgeInvalidAge); //purge invalid sessions older than - idManager.setPurgeValidAge(purgeValidAge); //purge valid sessions older than - */ - - - server.start(); - int port=server.getPort(); - try - { - HttpClient client = new HttpClient(); - client.start(); - try - { - //Create a session - ContentResponse response = client.GET("http://localhost:" + port + contextPath + servletMapping + "?action=create"); - 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="); - - //make a request to invalidate the session - Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=invalidate"); - request.header("Cookie", sessionCookie); - response = request.send(); - assertEquals(HttpServletResponse.SC_OK,response.getStatus()); - - Thread.currentThread().sleep(3*purgeDelay); //sleep long enough for purger to have run - - //make a request using previous session to test if its still there - request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=test"); - request.header("Cookie", sessionCookie); - response = request.send(); - assertEquals(HttpServletResponse.SC_OK,response.getStatus()); - } - finally - { - client.stop(); - } - } - finally - { - server.stop(); - } - - } - - - @Ignore - public void testPurgeInvalidSessionsWithLimit() throws Exception - { - String contextPath = ""; - String servletMapping = "/server"; - long purgeInvalidAge = 1000; //1 sec - int purgeLimit = 5; // only purge 5 sessions for each purge run - - //ensure scavenging is turned off so the purger gets a chance to find the session - MongoTestServer server = createServer(0, 1, 0); - ServletContextHandler context = server.addContext(contextPath); - context.addServlet(TestServlet.class, servletMapping); - - // disable purging so we can call it manually below - MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager(); - MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager(); - /* idManager.setPurge(false); - idManager.setPurgeLimit(purgeLimit); - idManager.setPurgeInvalidAge(purgeInvalidAge); - // don't purge valid sessions - idManager.setPurgeValidAge(0);*/ - - - server.start(); - int port=server.getPort(); - try - { - // cleanup any previous sessions that are invalid so that we are starting fresh - /* idManager.purgeFully();*/ - long sessionCountAtTestStart = sessionManager.getSessionStoreCount(); - - HttpClient client = new HttpClient(); - client.start(); - try - { - // create double the purge limit of sessions, and make them all invalid - for (int i = 0; i < purgeLimit * 2; i++) - { - ContentResponse response = client.GET("http://localhost:" + port + contextPath + servletMapping + "?action=create"); - 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="); - - - Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=invalidate"); - request.header("Cookie", sessionCookie); - response = request.send(); - assertEquals(HttpServletResponse.SC_OK, response.getStatus()); - } - - // sleep for our invalid age period so that the purge below does something - Thread.sleep(purgeInvalidAge * 2); - - // validate that we have the right number of sessions before we purge - assertEquals("Expected to find right number of sessions before purge", sessionCountAtTestStart + (purgeLimit * 2), sessionManager.getSessionStoreCount()); - - // run our purge we should still have items in the DB - /* idManager.purge();*/ - assertEquals("Expected to find sessions remaining in db after purge run with limit set", - sessionCountAtTestStart + purgeLimit, sessionManager.getSessionStoreCount()); - } - finally - { - client.stop(); - } - } - finally - { - server.stop(); - } - } - - - public static class TestServlet extends HttpServlet - { - DBCollection _sessions; - - - public TestServlet() throws UnknownHostException, MongoException - { - super(); - _sessions = new Mongo().getDB("HttpSessions").getCollection("sessions"); - } - - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException - { - String action = request.getParameter("action"); - if ("create".equals(action)) - { - HttpSession session = request.getSession(true); - session.setAttribute("foo", "bar"); - assertTrue(session.isNew()); - } - else if ("invalidate".equals(action)) - { - HttpSession existingSession = request.getSession(false); - assertNotNull(existingSession); - String id = existingSession.getId(); - id = (id.indexOf(".") > 0?id.substring(0, id.indexOf(".")):id); - DBObject dbSession = _sessions.findOne(new BasicDBObject("id",id)); - assertNotNull(dbSession); - - existingSession.invalidate(); - - //still in db, just marked as invalid - dbSession = _sessions.findOne(new BasicDBObject("id", id)); - assertNotNull(dbSession); - /* assertTrue(dbSession.containsField(MongoSessionManager.__INVALIDATED));*/ - assertTrue(dbSession.containsField(MongoSessionDataStore.__VALID)); - assertTrue(dbSession.get(MongoSessionDataStore.__VALID).equals(false)); - } - else if ("test".equals(action)) - { - String id = request.getRequestedSessionId(); - assertNotNull(id); - - id = (id.indexOf(".") > 0?id.substring(0, id.indexOf(".")):id); - - HttpSession existingSession = request.getSession(false); - assertTrue(existingSession == null); - - //not in db any more - DBObject dbSession = _sessions.findOne(new BasicDBObject("id", id)); - assertTrue(dbSession == null); - } - } - } -} diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java deleted file mode 100644 index a4e37eb80f1..00000000000 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/PurgeValidSessionTest.java +++ /dev/null @@ -1,232 +0,0 @@ -// -// ======================================================================== -// Copyright (c) 1995-2016 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.nosql.mongodb; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertTrue; - -import java.io.IOException; -import java.net.UnknownHostException; - -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 org.eclipse.jetty.client.HttpClient; -import org.eclipse.jetty.client.api.ContentResponse; -import org.eclipse.jetty.client.api.Request; -import org.eclipse.jetty.servlet.ServletContextHandler; -import org.junit.Ignore; - -import com.mongodb.BasicDBObject; -import com.mongodb.DBCollection; -import com.mongodb.DBObject; -import com.mongodb.Mongo; -import com.mongodb.MongoException; - -/** - * PurgeValidSessionTest - * - * - * - */ -public class PurgeValidSessionTest -{ - - - - public MongoTestServer createServer(int port, int max, int scavenge) - { - MongoTestServer server = new MongoTestServer(port,max,scavenge); - - return server; - } - - - - @Ignore - public void testPurgeValidSession() throws Exception - { - String contextPath = ""; - String servletMapping = "/server"; - long purgeDelay = 1000; //1 sec - long purgeValidAge = 1000; - - //ensure scavenging is turned off so the purger gets a chance to find the session - MongoTestServer server = createServer(0, 1, 0); - ServletContextHandler context = server.addContext(contextPath); - context.addServlet(TestServlet.class, servletMapping); - - MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager(); - MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager(); - /* idManager.setPurge(true); - idManager.setPurgeDelay(purgeDelay); - - idManager.setPurgeValidAge(purgeValidAge); //purge valid sessions older than -*/ - - - server.start(); - int port=server.getPort(); - try - { - HttpClient client = new HttpClient(); - client.start(); - try - { - //Create a session - ContentResponse response = client.GET("http://localhost:" + port + contextPath + servletMapping + "?action=create"); - 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="); - - - Thread.currentThread().sleep(3*purgeDelay); //sleep long enough for purger to have run - - //make a request using previous session to test if its still there - Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=test"); - request.header("Cookie", sessionCookie); - ContentResponse response2 = request.send(); - assertEquals(HttpServletResponse.SC_OK,response2.getStatus()); - } - finally - { - client.stop(); - } - } - finally - { - server.stop(); - } - - } - - - @Ignore - public void testPurgeValidSessionWithPurgeLimitSet() throws Exception - { - String contextPath = ""; - String servletMapping = "/server"; - long purgeDelay = 1000; //1 sec - long purgeValidAge = 1000; // 1 sec - int purgeLimit = 5; // only purge 5 items in each purge run - - //ensure scavenging is turned off so the purger gets a chance to find the session - MongoTestServer server = createServer(0, 1, 0); - ServletContextHandler context = server.addContext(contextPath); - context.addServlet(TestServlet.class, servletMapping); - - MongoSessionManager sessionManager = (MongoSessionManager)context.getSessionHandler().getSessionManager(); - MongoSessionIdManager idManager = (MongoSessionIdManager)server.getServer().getSessionIdManager(); - // disable purging we will run it manually below - /* idManager.setPurge(false); - idManager.setPurgeLimit(purgeLimit); - idManager.setPurgeDelay(purgeDelay); - idManager.setPurgeValidAge(purgeValidAge); //purge valid sessions older than -*/ - server.start(); - int port=server.getPort(); - - try - { - // start with no sessions - //((TestMongoSessionIdManager)idManager).deleteAll(); - - HttpClient client = new HttpClient(); - client.start(); - try - { - // create double our purgeLmit number of sessions - for (int i = 0; i < purgeLimit * 2; i++) - { - ContentResponse response = client.GET("http://localhost:" + port + contextPath + servletMapping + "?action=create"); - assertEquals(HttpServletResponse.SC_OK, response.getStatus()); - String sessionCookie = response.getHeaders().get("Set-Cookie"); - assertTrue(sessionCookie != null); - // don't remember our cookies from call to call - client.getCookieStore().removeAll(); - } - - // delay long enough for purgeValidAge to apply - Thread.sleep(2* purgeValidAge); - - // validate that we have the right number of sessions before we purge - assertEquals("Expected to find right number of sessions before purge", purgeLimit * 2, sessionManager.getSessionStoreCount()); - - // run our purge - /* idManager.purge();*/ - - assertEquals("Expected to find sessions remaining in db after purge run with limit set", - purgeLimit, sessionManager.getSessionStoreCount()); - } - finally - { - client.stop(); - } - } - finally - { - server.stop(); - } - - } - - public static class TestServlet extends HttpServlet - { - DBCollection _sessions; - - - public TestServlet() throws UnknownHostException, MongoException - { - super(); - _sessions = new Mongo().getDB("HttpSessions").getCollection("sessions"); - } - - - @Override - protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException - { - String action = request.getParameter("action"); - if ("create".equals(action)) - { - HttpSession session = request.getSession(true); - assertTrue(session.isNew()); - } - else if ("test".equals(action)) - { - String id = request.getRequestedSessionId(); - assertNotNull(id); - id = id.substring(0, id.indexOf(".")); - - HttpSession existingSession = request.getSession(false); - assertTrue(existingSession == null); - - //not in db any more - DBObject dbSession = _sessions.findOne(new BasicDBObject("id", id)); - assertTrue(dbSession == null); - } - } - } - -} diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java index 0cc431a67f2..29bf9557d67 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionExpiryTest.java @@ -123,7 +123,7 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest String sessionId = AbstractTestServer.extractSessionId(sessionCookie); - DBCollection sessions = ((MongoSessionIdManager)((MongoTestServer)server1).getServer().getSessionIdManager()).getSessions(); + DBCollection sessions = MongoTestServer.getCollection(); verifySessionCreated(listener,sessionId); //verify that the session timeout is set in mongo verifySessionTimeout(sessions, sessionId, -1); //SessionManager sets -1 if maxInactive < 0 @@ -176,7 +176,7 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest String sessionId = AbstractTestServer.extractSessionId(sessionCookie); - DBCollection sessions = ((MongoSessionIdManager)((MongoTestServer)server1).getServer().getSessionIdManager()).getSessions(); + DBCollection sessions = MongoTestServer.getCollection(); verifySessionCreated(listener,sessionId); //verify that the session timeout is set in mongo verifySessionTimeout(sessions, sessionId, inactivePeriod); @@ -254,7 +254,7 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest String sessionId = AbstractTestServer.extractSessionId(sessionCookie); - DBCollection sessions = ((MongoSessionIdManager)((MongoTestServer)server1).getServer().getSessionIdManager()).getSessions(); + DBCollection sessions = MongoTestServer.getCollection(); verifySessionCreated(listener,sessionId); //verify that the session timeout is the new value and not the default verifySessionTimeout(sessions, sessionId, inactivePeriod); diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java index 38b854090ba..98499d85291 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/SessionRenewTest.java @@ -20,6 +20,7 @@ package org.eclipse.jetty.nosql.mongodb; import org.eclipse.jetty.server.session.AbstractSessionRenewTest; import org.eclipse.jetty.server.session.AbstractTestServer; +import org.eclipse.jetty.webapp.WebAppContext; import static org.junit.Assert.assertNotNull; import org.junit.AfterClass; @@ -63,7 +64,7 @@ public class SessionRenewTest extends AbstractSessionRenewTest * @see org.eclipse.jetty.server.session.AbstractSessionRenewTest#verifyChange(java.lang.String, java.lang.String) */ @Override - public boolean verifyChange(String oldSessionId, String newSessionId) + public boolean verifyChange(WebAppContext context, String oldSessionId, String newSessionId) { try { diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java index 7ee39cbb3cd..8930f6de187 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionRenewTest.java @@ -52,7 +52,7 @@ public abstract class AbstractSessionRenewTest public abstract AbstractTestServer createServer(int port, int max, int scavenge, int inspectionPeriod, int idlePassivationPeriod); - public abstract boolean verifyChange (String oldSessionId, String newSessionId); + public abstract boolean verifyChange (WebAppContext context, String oldSessionId, String newSessionId); /** * @throws Exception @@ -101,7 +101,7 @@ public abstract class AbstractSessionRenewTest assertNotSame(sessionCookie, renewSessionCookie); assertTrue(testListener.isCalled()); - assertTrue(verifyChange(AbstractTestServer.extractSessionId(sessionCookie), AbstractTestServer.extractSessionId(renewSessionCookie))); + assertTrue(verifyChange(context, AbstractTestServer.extractSessionId(sessionCookie), AbstractTestServer.extractSessionId(renewSessionCookie))); } finally { @@ -160,7 +160,7 @@ public abstract class AbstractSessionRenewTest assertFalse(beforeSessionId.equals(afterSessionId)); //different id SessionManager sessionManager = ((Session)afterSession).getSessionManager(); - AbstractSessionIdManager sessionIdManager = (AbstractSessionIdManager)sessionManager.getSessionIdManager(); + DefaultSessionIdManager sessionIdManager = (DefaultSessionIdManager)sessionManager.getSessionIdManager(); assertTrue(sessionIdManager.isIdInUse(afterSessionId)); //new session id should be in use assertFalse(sessionIdManager.isIdInUse(beforeSessionId)); diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java index 98ac8f946c7..25734839d18 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractTestServer.java @@ -39,6 +39,8 @@ public abstract class AbstractTestServer public static int DEFAULT_SCAVENGE_SEC = 10; public static int DEFAULT_IDLE_PASSIVATE_SEC = 2; + protected static int __workers=0; + protected final Server _server; protected final int _maxInactivePeriod; protected final int _inspectionPeriod; @@ -47,6 +49,7 @@ public abstract class AbstractTestServer protected final ContextHandlerCollection _contexts; protected SessionIdManager _sessionIdManager; private PeriodicSessionInspector _inspector; + protected Object _config; @@ -78,7 +81,7 @@ public abstract class AbstractTestServer this (port, maxInactivePeriod, scavengePeriod, inspectionPeriod, idlePassivatePeriod, null); } - public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod, int inspectionPeriod, int idlePassivatePeriod, Object sessionIdMgrConfig) + public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod, int inspectionPeriod, int idlePassivatePeriod, Object cfg) { _server = new Server(port); _maxInactivePeriod = maxInactivePeriod; @@ -86,17 +89,28 @@ public abstract class AbstractTestServer _inspectionPeriod = inspectionPeriod; _idlePassivatePeriod = idlePassivatePeriod; _contexts = new ContextHandlerCollection(); - _sessionIdManager = newSessionIdManager(sessionIdMgrConfig); + _config = cfg; + _sessionIdManager = newSessionIdManager(); _server.setSessionIdManager(_sessionIdManager); - ((AbstractSessionIdManager) _sessionIdManager).setServer(_server); + ((DefaultSessionIdManager) _sessionIdManager).setServer(_server); _inspector = new PeriodicSessionInspector(); _inspector.setIntervalSec(_inspectionPeriod); - ((AbstractSessionIdManager)_sessionIdManager).setSessionInspector(_inspector); + ((DefaultSessionIdManager)_sessionIdManager).setSessionInspector(_inspector); } - - public abstract SessionIdManager newSessionIdManager(Object config); + + /** + * @return + */ + public SessionIdManager newSessionIdManager() + { + DefaultSessionIdManager idManager = new DefaultSessionIdManager(getServer()); + idManager.setWorkerName("w"+(__workers++)); + return idManager; + } + + public abstract SessionManager newSessionManager(); public abstract SessionHandler newSessionHandler(SessionManager sessionManager);