Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java')
-rw-r--r--jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java323
1 files changed, 323 insertions, 0 deletions
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
new file mode 100644
index 0000000000..7c2a81e107
--- /dev/null
+++ b/jetty-gcloud/jetty-gcloud-session-manager/src/main/java/org/eclipse/jetty/gcloud/session/GCloudSessionIdManager.java
@@ -0,0 +1,323 @@
+//
+// ========================================================================
+// 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 javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpSession;
+
+import org.eclipse.jetty.server.Handler;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.SessionManager;
+import org.eclipse.jetty.server.handler.ContextHandler;
+import org.eclipse.jetty.server.session.AbstractSession;
+import org.eclipse.jetty.server.session.AbstractSessionIdManager;
+import org.eclipse.jetty.server.session.SessionHandler;
+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 Server _server;
+ private Datastore _datastore;
+ private KeyFactory _keyFactory;
+ private GCloudConfiguration _config;
+
+
+
+
+ /**
+ * @param server
+ */
+ public GCloudSessionIdManager(Server server)
+ {
+ super();
+ _server = server;
+ }
+
+ /**
+ * @param server
+ * @param random
+ */
+ public GCloudSessionIdManager(Server server, Random random)
+ {
+ super(random);
+ _server = server;
+ }
+
+
+
+ /**
+ * 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();
+ }
+
+
+
+
+
+ /**
+ * 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#idInUse(java.lang.String)
+ */
+ @Override
+ public boolean idInUse(String id)
+ {
+ if (id == null)
+ return false;
+
+ String clusterId = getClusterId(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;
+ }
+
+ }
+
+ /**
+ * Remember a new in-use session id.
+ *
+ * This will save the in-use session id to the cluster.
+ *
+ * @see org.eclipse.jetty.server.SessionIdManager#addSession(javax.servlet.http.HttpSession)
+ */
+ @Override
+ public void addSession(HttpSession session)
+ {
+ if (session == null)
+ return;
+
+ //insert into the store
+ insert (((AbstractSession)session).getClusterId());
+ }
+
+
+
+
+ public GCloudConfiguration getConfig()
+ {
+ return _config;
+ }
+
+ public void setConfig(GCloudConfiguration config)
+ {
+ _config = config;
+ }
+
+
+
+ /**
+ * Remove a session id from the list of in-use ids.
+ *
+ * This will remvove the corresponding session id from the cluster.
+ *
+ * @see org.eclipse.jetty.server.SessionIdManager#removeSession(javax.servlet.http.HttpSession)
+ */
+ @Override
+ public void removeSession(HttpSession session)
+ {
+ if (session == null)
+ return;
+
+ //delete from the cache
+ delete (((AbstractSession)session).getClusterId());
+ }
+
+ /**
+ * Remove a session id. This compels all other contexts who have a session
+ * with the same id to also remove it.
+ *
+ * @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
+ */
+ @Override
+ public void invalidateAll(String id)
+ {
+ //delete the session id from list of in-use sessions
+ delete (id);
+
+
+ //tell all contexts that may have a session object with this id to
+ //get rid of them
+ Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
+ for (int i=0; contexts!=null && i<contexts.length; i++)
+ {
+ SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+ if (sessionHandler != null)
+ {
+ SessionManager manager = sessionHandler.getSessionManager();
+
+ if (manager != null && manager instanceof GCloudSessionManager)
+ {
+ ((GCloudSessionManager)manager).invalidateSession(id);
+ }
+ }
+ }
+
+ }
+
+ /**
+ * Change a session id.
+ *
+ * Typically this occurs when a previously existing session has passed through authentication.
+ *
+ * @see org.eclipse.jetty.server.session.AbstractSessionIdManager#renewSessionId(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
+ */
+ @Override
+ public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
+ {
+ //generate a new id
+ String newClusterId = newSessionId(request.hashCode());
+
+ delete(oldClusterId);
+ insert(newClusterId);
+
+
+ //tell all contexts to update the id
+ Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
+ for (int i=0; contexts!=null && i<contexts.length; i++)
+ {
+ SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
+ if (sessionHandler != null)
+ {
+ SessionManager manager = sessionHandler.getSessionManager();
+
+ if (manager != null && manager instanceof GCloudSessionManager)
+ {
+ ((GCloudSessionManager)manager).renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
+ }
+ }
+ }
+
+ }
+
+
+
+ /**
+ * 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 void delete (String id)
+ {
+ if (_datastore == null)
+ throw new IllegalStateException ("No DataStore");
+
+ _datastore.delete(makeKey(id));
+ }
+
+
+
+ /**
+ * Generate a unique key from the session id.
+ *
+ * @param id
+ * @return
+ */
+ protected Key makeKey (String id)
+ {
+ return _keyFactory.newKey(id);
+ }
+}

Back to the top