103928aee4356845252ac6b662d5c72c29903813eJake Slack// 203928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 303928aee4356845252ac6b662d5c72c29903813eJake Slack// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. 403928aee4356845252ac6b662d5c72c29903813eJake Slack// ------------------------------------------------------------------------ 503928aee4356845252ac6b662d5c72c29903813eJake Slack// All rights reserved. This program and the accompanying materials 603928aee4356845252ac6b662d5c72c29903813eJake Slack// are made available under the terms of the Eclipse Public License v1.0 703928aee4356845252ac6b662d5c72c29903813eJake Slack// and Apache License v2.0 which accompanies this distribution. 803928aee4356845252ac6b662d5c72c29903813eJake Slack// 903928aee4356845252ac6b662d5c72c29903813eJake Slack// The Eclipse Public License is available at 1003928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.eclipse.org/legal/epl-v10.html 1103928aee4356845252ac6b662d5c72c29903813eJake Slack// 1203928aee4356845252ac6b662d5c72c29903813eJake Slack// The Apache License v2.0 is available at 1303928aee4356845252ac6b662d5c72c29903813eJake Slack// http://www.opensource.org/licenses/apache2.0.php 1403928aee4356845252ac6b662d5c72c29903813eJake Slack// 1503928aee4356845252ac6b662d5c72c29903813eJake Slack// You may elect to redistribute this code under either of these licenses. 1603928aee4356845252ac6b662d5c72c29903813eJake Slack// ======================================================================== 1703928aee4356845252ac6b662d5c72c29903813eJake Slack// 1803928aee4356845252ac6b662d5c72c29903813eJake Slack 1903928aee4356845252ac6b662d5c72c29903813eJake Slack 2003928aee4356845252ac6b662d5c72c29903813eJake Slackpackage org.eclipse.jetty.server.session; 2103928aee4356845252ac6b662d5c72c29903813eJake Slack 2203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.ByteArrayInputStream; 2303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.ByteArrayOutputStream; 2403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.IOException; 2503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.InputStream; 2603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.ObjectInputStream; 2703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.io.ObjectOutputStream; 2803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.Connection; 2903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.PreparedStatement; 3003928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.ResultSet; 3103928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.SQLException; 3203928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.sql.Statement; 3303928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.HashMap; 3403928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.List; 3503928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.ListIterator; 3603928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Map; 3703928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.Set; 3803928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.ConcurrentHashMap; 3903928aee4356845252ac6b662d5c72c29903813eJake Slackimport java.util.concurrent.atomic.AtomicReference; 4003928aee4356845252ac6b662d5c72c29903813eJake Slack 4103928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.SessionTrackingMode; 4203928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpServletRequest; 4303928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpSessionEvent; 4403928aee4356845252ac6b662d5c72c29903813eJake Slackimport javax.servlet.http.HttpSessionListener; 4503928aee4356845252ac6b662d5c72c29903813eJake Slack 4603928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.SessionIdManager; 4703928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.server.handler.ContextHandler; 4803928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Log; 4903928aee4356845252ac6b662d5c72c29903813eJake Slackimport org.eclipse.jetty.util.log.Logger; 5003928aee4356845252ac6b662d5c72c29903813eJake Slack 5103928aee4356845252ac6b662d5c72c29903813eJake Slack/** 5203928aee4356845252ac6b662d5c72c29903813eJake Slack * JDBCSessionManager 5303928aee4356845252ac6b662d5c72c29903813eJake Slack * 5403928aee4356845252ac6b662d5c72c29903813eJake Slack * SessionManager that persists sessions to a database to enable clustering. 5503928aee4356845252ac6b662d5c72c29903813eJake Slack * 5603928aee4356845252ac6b662d5c72c29903813eJake Slack * Session data is persisted to the JettySessions table: 5703928aee4356845252ac6b662d5c72c29903813eJake Slack * 5803928aee4356845252ac6b662d5c72c29903813eJake Slack * rowId (unique in cluster: webapp name/path + virtualhost + sessionId) 5903928aee4356845252ac6b662d5c72c29903813eJake Slack * contextPath (of the context owning the session) 6003928aee4356845252ac6b662d5c72c29903813eJake Slack * sessionId (unique in a context) 6103928aee4356845252ac6b662d5c72c29903813eJake Slack * lastNode (name of node last handled session) 6203928aee4356845252ac6b662d5c72c29903813eJake Slack * accessTime (time in milliseconds session was accessed) 6303928aee4356845252ac6b662d5c72c29903813eJake Slack * lastAccessTime (previous time in milliseconds session was accessed) 6403928aee4356845252ac6b662d5c72c29903813eJake Slack * createTime (time in milliseconds session created) 6503928aee4356845252ac6b662d5c72c29903813eJake Slack * cookieTime (time in milliseconds session cookie created) 6603928aee4356845252ac6b662d5c72c29903813eJake Slack * lastSavedTime (last time in milliseconds session access times were saved) 6703928aee4356845252ac6b662d5c72c29903813eJake Slack * expiryTime (time in milliseconds that the session is due to expire) 6803928aee4356845252ac6b662d5c72c29903813eJake Slack * map (attribute map) 6903928aee4356845252ac6b662d5c72c29903813eJake Slack * 7003928aee4356845252ac6b662d5c72c29903813eJake Slack * As an optimization, to prevent thrashing the database, we do not persist 7103928aee4356845252ac6b662d5c72c29903813eJake Slack * the accessTime and lastAccessTime every time the session is accessed. Rather, 7203928aee4356845252ac6b662d5c72c29903813eJake Slack * we write it out every so often. The frequency is controlled by the saveIntervalSec 7303928aee4356845252ac6b662d5c72c29903813eJake Slack * field. 7403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 7503928aee4356845252ac6b662d5c72c29903813eJake Slackpublic class JDBCSessionManager extends AbstractSessionManager 7603928aee4356845252ac6b662d5c72c29903813eJake Slack{ 7703928aee4356845252ac6b662d5c72c29903813eJake Slack private static final Logger LOG = Log.getLogger(JDBCSessionManager.class); 7803928aee4356845252ac6b662d5c72c29903813eJake Slack 7903928aee4356845252ac6b662d5c72c29903813eJake Slack private ConcurrentHashMap<String, AbstractSession> _sessions; 8003928aee4356845252ac6b662d5c72c29903813eJake Slack protected JDBCSessionIdManager _jdbcSessionIdMgr = null; 8103928aee4356845252ac6b662d5c72c29903813eJake Slack protected long _saveIntervalSec = 60; //only persist changes to session access times every 60 secs 8203928aee4356845252ac6b662d5c72c29903813eJake Slack 8303928aee4356845252ac6b662d5c72c29903813eJake Slack 8403928aee4356845252ac6b662d5c72c29903813eJake Slack 8503928aee4356845252ac6b662d5c72c29903813eJake Slack 8603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 8703928aee4356845252ac6b662d5c72c29903813eJake Slack * Session 8803928aee4356845252ac6b662d5c72c29903813eJake Slack * 8903928aee4356845252ac6b662d5c72c29903813eJake Slack * Session instance. 9003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 9103928aee4356845252ac6b662d5c72c29903813eJake Slack public class Session extends AbstractSession 9203928aee4356845252ac6b662d5c72c29903813eJake Slack { 9303928aee4356845252ac6b662d5c72c29903813eJake Slack private static final long serialVersionUID = 5208464051134226143L; 9403928aee4356845252ac6b662d5c72c29903813eJake Slack 9503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 9603928aee4356845252ac6b662d5c72c29903813eJake Slack * If dirty, session needs to be (re)persisted 9703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 9803928aee4356845252ac6b662d5c72c29903813eJake Slack private boolean _dirty=false; 9903928aee4356845252ac6b662d5c72c29903813eJake Slack 10003928aee4356845252ac6b662d5c72c29903813eJake Slack 10103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 10203928aee4356845252ac6b662d5c72c29903813eJake Slack * Time in msec since the epoch that a session cookie was set for this session 10303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 10403928aee4356845252ac6b662d5c72c29903813eJake Slack private long _cookieSet; 10503928aee4356845252ac6b662d5c72c29903813eJake Slack 10603928aee4356845252ac6b662d5c72c29903813eJake Slack 10703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 10803928aee4356845252ac6b662d5c72c29903813eJake Slack * Time in msec since the epoch that the session will expire 10903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 11003928aee4356845252ac6b662d5c72c29903813eJake Slack private long _expiryTime; 11103928aee4356845252ac6b662d5c72c29903813eJake Slack 11203928aee4356845252ac6b662d5c72c29903813eJake Slack 11303928aee4356845252ac6b662d5c72c29903813eJake Slack /** 11403928aee4356845252ac6b662d5c72c29903813eJake Slack * Time in msec since the epoch that the session was last persisted 11503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 11603928aee4356845252ac6b662d5c72c29903813eJake Slack private long _lastSaved; 11703928aee4356845252ac6b662d5c72c29903813eJake Slack 11803928aee4356845252ac6b662d5c72c29903813eJake Slack 11903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 12003928aee4356845252ac6b662d5c72c29903813eJake Slack * Unique identifier of the last node to host the session 12103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 12203928aee4356845252ac6b662d5c72c29903813eJake Slack private String _lastNode; 12303928aee4356845252ac6b662d5c72c29903813eJake Slack 12403928aee4356845252ac6b662d5c72c29903813eJake Slack 12503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 12603928aee4356845252ac6b662d5c72c29903813eJake Slack * Virtual host for context (used to help distinguish 2 sessions with same id on different contexts) 12703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 12803928aee4356845252ac6b662d5c72c29903813eJake Slack private String _virtualHost; 12903928aee4356845252ac6b662d5c72c29903813eJake Slack 13003928aee4356845252ac6b662d5c72c29903813eJake Slack 13103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 13203928aee4356845252ac6b662d5c72c29903813eJake Slack * Unique row in db for session 13303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 13403928aee4356845252ac6b662d5c72c29903813eJake Slack private String _rowId; 13503928aee4356845252ac6b662d5c72c29903813eJake Slack 13603928aee4356845252ac6b662d5c72c29903813eJake Slack 13703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 13803928aee4356845252ac6b662d5c72c29903813eJake Slack * Mangled context name (used to help distinguish 2 sessions with same id on different contexts) 13903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 14003928aee4356845252ac6b662d5c72c29903813eJake Slack private String _canonicalContext; 14103928aee4356845252ac6b662d5c72c29903813eJake Slack 14203928aee4356845252ac6b662d5c72c29903813eJake Slack 14303928aee4356845252ac6b662d5c72c29903813eJake Slack /** 14403928aee4356845252ac6b662d5c72c29903813eJake Slack * Session from a request. 14503928aee4356845252ac6b662d5c72c29903813eJake Slack * 14603928aee4356845252ac6b662d5c72c29903813eJake Slack * @param request 14703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 14803928aee4356845252ac6b662d5c72c29903813eJake Slack protected Session (HttpServletRequest request) 14903928aee4356845252ac6b662d5c72c29903813eJake Slack { 15003928aee4356845252ac6b662d5c72c29903813eJake Slack super(JDBCSessionManager.this,request); 15103928aee4356845252ac6b662d5c72c29903813eJake Slack int maxInterval=getMaxInactiveInterval(); 15203928aee4356845252ac6b662d5c72c29903813eJake Slack _expiryTime = (maxInterval <= 0 ? 0 : (System.currentTimeMillis() + maxInterval*1000L)); 15303928aee4356845252ac6b662d5c72c29903813eJake Slack _virtualHost = JDBCSessionManager.getVirtualHost(_context); 15403928aee4356845252ac6b662d5c72c29903813eJake Slack _canonicalContext = canonicalize(_context.getContextPath()); 15503928aee4356845252ac6b662d5c72c29903813eJake Slack _lastNode = getSessionIdManager().getWorkerName(); 15603928aee4356845252ac6b662d5c72c29903813eJake Slack } 15703928aee4356845252ac6b662d5c72c29903813eJake Slack 15803928aee4356845252ac6b662d5c72c29903813eJake Slack 15903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 16003928aee4356845252ac6b662d5c72c29903813eJake Slack * Session restored from database 16103928aee4356845252ac6b662d5c72c29903813eJake Slack * @param sessionId 16203928aee4356845252ac6b662d5c72c29903813eJake Slack * @param rowId 16303928aee4356845252ac6b662d5c72c29903813eJake Slack * @param created 16403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param accessed 16503928aee4356845252ac6b662d5c72c29903813eJake Slack */ 16603928aee4356845252ac6b662d5c72c29903813eJake Slack protected Session (String sessionId, String rowId, long created, long accessed) 16703928aee4356845252ac6b662d5c72c29903813eJake Slack { 16803928aee4356845252ac6b662d5c72c29903813eJake Slack super(JDBCSessionManager.this, created, accessed, sessionId); 16903928aee4356845252ac6b662d5c72c29903813eJake Slack _rowId = rowId; 17003928aee4356845252ac6b662d5c72c29903813eJake Slack } 17103928aee4356845252ac6b662d5c72c29903813eJake Slack 17203928aee4356845252ac6b662d5c72c29903813eJake Slack 17303928aee4356845252ac6b662d5c72c29903813eJake Slack protected synchronized String getRowId() 17403928aee4356845252ac6b662d5c72c29903813eJake Slack { 17503928aee4356845252ac6b662d5c72c29903813eJake Slack return _rowId; 17603928aee4356845252ac6b662d5c72c29903813eJake Slack } 17703928aee4356845252ac6b662d5c72c29903813eJake Slack 17803928aee4356845252ac6b662d5c72c29903813eJake Slack protected synchronized void setRowId(String rowId) 17903928aee4356845252ac6b662d5c72c29903813eJake Slack { 18003928aee4356845252ac6b662d5c72c29903813eJake Slack _rowId = rowId; 18103928aee4356845252ac6b662d5c72c29903813eJake Slack } 18203928aee4356845252ac6b662d5c72c29903813eJake Slack 18303928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized void setVirtualHost (String vhost) 18403928aee4356845252ac6b662d5c72c29903813eJake Slack { 18503928aee4356845252ac6b662d5c72c29903813eJake Slack _virtualHost=vhost; 18603928aee4356845252ac6b662d5c72c29903813eJake Slack } 18703928aee4356845252ac6b662d5c72c29903813eJake Slack 18803928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized String getVirtualHost () 18903928aee4356845252ac6b662d5c72c29903813eJake Slack { 19003928aee4356845252ac6b662d5c72c29903813eJake Slack return _virtualHost; 19103928aee4356845252ac6b662d5c72c29903813eJake Slack } 19203928aee4356845252ac6b662d5c72c29903813eJake Slack 19303928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized long getLastSaved () 19403928aee4356845252ac6b662d5c72c29903813eJake Slack { 19503928aee4356845252ac6b662d5c72c29903813eJake Slack return _lastSaved; 19603928aee4356845252ac6b662d5c72c29903813eJake Slack } 19703928aee4356845252ac6b662d5c72c29903813eJake Slack 19803928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized void setLastSaved (long time) 19903928aee4356845252ac6b662d5c72c29903813eJake Slack { 20003928aee4356845252ac6b662d5c72c29903813eJake Slack _lastSaved=time; 20103928aee4356845252ac6b662d5c72c29903813eJake Slack } 20203928aee4356845252ac6b662d5c72c29903813eJake Slack 20303928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized void setExpiryTime (long time) 20403928aee4356845252ac6b662d5c72c29903813eJake Slack { 20503928aee4356845252ac6b662d5c72c29903813eJake Slack _expiryTime=time; 20603928aee4356845252ac6b662d5c72c29903813eJake Slack } 20703928aee4356845252ac6b662d5c72c29903813eJake Slack 20803928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized long getExpiryTime () 20903928aee4356845252ac6b662d5c72c29903813eJake Slack { 21003928aee4356845252ac6b662d5c72c29903813eJake Slack return _expiryTime; 21103928aee4356845252ac6b662d5c72c29903813eJake Slack } 21203928aee4356845252ac6b662d5c72c29903813eJake Slack 21303928aee4356845252ac6b662d5c72c29903813eJake Slack 21403928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized void setCanonicalContext(String str) 21503928aee4356845252ac6b662d5c72c29903813eJake Slack { 21603928aee4356845252ac6b662d5c72c29903813eJake Slack _canonicalContext=str; 21703928aee4356845252ac6b662d5c72c29903813eJake Slack } 21803928aee4356845252ac6b662d5c72c29903813eJake Slack 21903928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized String getCanonicalContext () 22003928aee4356845252ac6b662d5c72c29903813eJake Slack { 22103928aee4356845252ac6b662d5c72c29903813eJake Slack return _canonicalContext; 22203928aee4356845252ac6b662d5c72c29903813eJake Slack } 22303928aee4356845252ac6b662d5c72c29903813eJake Slack 22403928aee4356845252ac6b662d5c72c29903813eJake Slack public void setCookieSet (long ms) 22503928aee4356845252ac6b662d5c72c29903813eJake Slack { 22603928aee4356845252ac6b662d5c72c29903813eJake Slack _cookieSet = ms; 22703928aee4356845252ac6b662d5c72c29903813eJake Slack } 22803928aee4356845252ac6b662d5c72c29903813eJake Slack 22903928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized long getCookieSet () 23003928aee4356845252ac6b662d5c72c29903813eJake Slack { 23103928aee4356845252ac6b662d5c72c29903813eJake Slack return _cookieSet; 23203928aee4356845252ac6b662d5c72c29903813eJake Slack } 23303928aee4356845252ac6b662d5c72c29903813eJake Slack 23403928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized void setLastNode (String node) 23503928aee4356845252ac6b662d5c72c29903813eJake Slack { 23603928aee4356845252ac6b662d5c72c29903813eJake Slack _lastNode=node; 23703928aee4356845252ac6b662d5c72c29903813eJake Slack } 23803928aee4356845252ac6b662d5c72c29903813eJake Slack 23903928aee4356845252ac6b662d5c72c29903813eJake Slack public synchronized String getLastNode () 24003928aee4356845252ac6b662d5c72c29903813eJake Slack { 24103928aee4356845252ac6b662d5c72c29903813eJake Slack return _lastNode; 24203928aee4356845252ac6b662d5c72c29903813eJake Slack } 24303928aee4356845252ac6b662d5c72c29903813eJake Slack 24403928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 24503928aee4356845252ac6b662d5c72c29903813eJake Slack public void setAttribute (String name, Object value) 24603928aee4356845252ac6b662d5c72c29903813eJake Slack { 24703928aee4356845252ac6b662d5c72c29903813eJake Slack super.setAttribute(name, value); 24803928aee4356845252ac6b662d5c72c29903813eJake Slack _dirty=true; 24903928aee4356845252ac6b662d5c72c29903813eJake Slack } 25003928aee4356845252ac6b662d5c72c29903813eJake Slack 25103928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 25203928aee4356845252ac6b662d5c72c29903813eJake Slack public void removeAttribute (String name) 25303928aee4356845252ac6b662d5c72c29903813eJake Slack { 25403928aee4356845252ac6b662d5c72c29903813eJake Slack super.removeAttribute(name); 25503928aee4356845252ac6b662d5c72c29903813eJake Slack _dirty=true; 25603928aee4356845252ac6b662d5c72c29903813eJake Slack } 25703928aee4356845252ac6b662d5c72c29903813eJake Slack 25803928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 25903928aee4356845252ac6b662d5c72c29903813eJake Slack protected void cookieSet() 26003928aee4356845252ac6b662d5c72c29903813eJake Slack { 26103928aee4356845252ac6b662d5c72c29903813eJake Slack _cookieSet = getAccessed(); 26203928aee4356845252ac6b662d5c72c29903813eJake Slack } 26303928aee4356845252ac6b662d5c72c29903813eJake Slack 26403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 26503928aee4356845252ac6b662d5c72c29903813eJake Slack * Entry to session. 26603928aee4356845252ac6b662d5c72c29903813eJake Slack * Called by SessionHandler on inbound request and the session already exists in this node's memory. 26703928aee4356845252ac6b662d5c72c29903813eJake Slack * 26803928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSession#access(long) 26903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 27003928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 27103928aee4356845252ac6b662d5c72c29903813eJake Slack protected boolean access(long time) 27203928aee4356845252ac6b662d5c72c29903813eJake Slack { 27303928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 27403928aee4356845252ac6b662d5c72c29903813eJake Slack { 27503928aee4356845252ac6b662d5c72c29903813eJake Slack if (super.access(time)) 27603928aee4356845252ac6b662d5c72c29903813eJake Slack { 27703928aee4356845252ac6b662d5c72c29903813eJake Slack int maxInterval=getMaxInactiveInterval(); 27803928aee4356845252ac6b662d5c72c29903813eJake Slack _expiryTime = (maxInterval <= 0 ? 0 : (time + maxInterval*1000L)); 27903928aee4356845252ac6b662d5c72c29903813eJake Slack return true; 28003928aee4356845252ac6b662d5c72c29903813eJake Slack } 28103928aee4356845252ac6b662d5c72c29903813eJake Slack return false; 28203928aee4356845252ac6b662d5c72c29903813eJake Slack } 28303928aee4356845252ac6b662d5c72c29903813eJake Slack } 28403928aee4356845252ac6b662d5c72c29903813eJake Slack 28503928aee4356845252ac6b662d5c72c29903813eJake Slack 28603928aee4356845252ac6b662d5c72c29903813eJake Slack 28703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 28803928aee4356845252ac6b662d5c72c29903813eJake Slack * Exit from session 28903928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSession#complete() 29003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 29103928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 29203928aee4356845252ac6b662d5c72c29903813eJake Slack protected void complete() 29303928aee4356845252ac6b662d5c72c29903813eJake Slack { 29403928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 29503928aee4356845252ac6b662d5c72c29903813eJake Slack { 29603928aee4356845252ac6b662d5c72c29903813eJake Slack super.complete(); 29703928aee4356845252ac6b662d5c72c29903813eJake Slack try 29803928aee4356845252ac6b662d5c72c29903813eJake Slack { 29903928aee4356845252ac6b662d5c72c29903813eJake Slack if (isValid()) 30003928aee4356845252ac6b662d5c72c29903813eJake Slack { 30103928aee4356845252ac6b662d5c72c29903813eJake Slack if (_dirty) 30203928aee4356845252ac6b662d5c72c29903813eJake Slack { 30303928aee4356845252ac6b662d5c72c29903813eJake Slack //The session attributes have changed, write to the db, ensuring 30403928aee4356845252ac6b662d5c72c29903813eJake Slack //http passivation/activation listeners called 30503928aee4356845252ac6b662d5c72c29903813eJake Slack willPassivate(); 30603928aee4356845252ac6b662d5c72c29903813eJake Slack updateSession(this); 30703928aee4356845252ac6b662d5c72c29903813eJake Slack didActivate(); 30803928aee4356845252ac6b662d5c72c29903813eJake Slack } 30903928aee4356845252ac6b662d5c72c29903813eJake Slack else if ((getAccessed() - _lastSaved) >= (getSaveInterval() * 1000L)) 31003928aee4356845252ac6b662d5c72c29903813eJake Slack { 31103928aee4356845252ac6b662d5c72c29903813eJake Slack updateSessionAccessTime(this); 31203928aee4356845252ac6b662d5c72c29903813eJake Slack } 31303928aee4356845252ac6b662d5c72c29903813eJake Slack } 31403928aee4356845252ac6b662d5c72c29903813eJake Slack } 31503928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 31603928aee4356845252ac6b662d5c72c29903813eJake Slack { 31703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Problem persisting changed session data id="+getId(), e); 31803928aee4356845252ac6b662d5c72c29903813eJake Slack } 31903928aee4356845252ac6b662d5c72c29903813eJake Slack finally 32003928aee4356845252ac6b662d5c72c29903813eJake Slack { 32103928aee4356845252ac6b662d5c72c29903813eJake Slack _dirty=false; 32203928aee4356845252ac6b662d5c72c29903813eJake Slack } 32303928aee4356845252ac6b662d5c72c29903813eJake Slack } 32403928aee4356845252ac6b662d5c72c29903813eJake Slack } 32503928aee4356845252ac6b662d5c72c29903813eJake Slack 32603928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 32703928aee4356845252ac6b662d5c72c29903813eJake Slack protected void timeout() throws IllegalStateException 32803928aee4356845252ac6b662d5c72c29903813eJake Slack { 32903928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 33003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Timing out session id="+getClusterId()); 33103928aee4356845252ac6b662d5c72c29903813eJake Slack super.timeout(); 33203928aee4356845252ac6b662d5c72c29903813eJake Slack } 33303928aee4356845252ac6b662d5c72c29903813eJake Slack 33403928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 33503928aee4356845252ac6b662d5c72c29903813eJake Slack public String toString () 33603928aee4356845252ac6b662d5c72c29903813eJake Slack { 33703928aee4356845252ac6b662d5c72c29903813eJake Slack return "Session rowId="+_rowId+",id="+getId()+",lastNode="+_lastNode+ 33803928aee4356845252ac6b662d5c72c29903813eJake Slack ",created="+getCreationTime()+",accessed="+getAccessed()+ 33903928aee4356845252ac6b662d5c72c29903813eJake Slack ",lastAccessed="+getLastAccessedTime()+",cookieSet="+_cookieSet+ 34003928aee4356845252ac6b662d5c72c29903813eJake Slack ",lastSaved="+_lastSaved+",expiry="+_expiryTime; 34103928aee4356845252ac6b662d5c72c29903813eJake Slack } 34203928aee4356845252ac6b662d5c72c29903813eJake Slack } 34303928aee4356845252ac6b662d5c72c29903813eJake Slack 34403928aee4356845252ac6b662d5c72c29903813eJake Slack 34503928aee4356845252ac6b662d5c72c29903813eJake Slack 34603928aee4356845252ac6b662d5c72c29903813eJake Slack 34703928aee4356845252ac6b662d5c72c29903813eJake Slack /** 34803928aee4356845252ac6b662d5c72c29903813eJake Slack * ClassLoadingObjectInputStream 34903928aee4356845252ac6b662d5c72c29903813eJake Slack * 35003928aee4356845252ac6b662d5c72c29903813eJake Slack * Used to persist the session attribute map 35103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 35203928aee4356845252ac6b662d5c72c29903813eJake Slack protected class ClassLoadingObjectInputStream extends ObjectInputStream 35303928aee4356845252ac6b662d5c72c29903813eJake Slack { 35403928aee4356845252ac6b662d5c72c29903813eJake Slack public ClassLoadingObjectInputStream(java.io.InputStream in) throws IOException 35503928aee4356845252ac6b662d5c72c29903813eJake Slack { 35603928aee4356845252ac6b662d5c72c29903813eJake Slack super(in); 35703928aee4356845252ac6b662d5c72c29903813eJake Slack } 35803928aee4356845252ac6b662d5c72c29903813eJake Slack 35903928aee4356845252ac6b662d5c72c29903813eJake Slack public ClassLoadingObjectInputStream () throws IOException 36003928aee4356845252ac6b662d5c72c29903813eJake Slack { 36103928aee4356845252ac6b662d5c72c29903813eJake Slack super(); 36203928aee4356845252ac6b662d5c72c29903813eJake Slack } 36303928aee4356845252ac6b662d5c72c29903813eJake Slack 36403928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 36503928aee4356845252ac6b662d5c72c29903813eJake Slack public Class<?> resolveClass (java.io.ObjectStreamClass cl) throws IOException, ClassNotFoundException 36603928aee4356845252ac6b662d5c72c29903813eJake Slack { 36703928aee4356845252ac6b662d5c72c29903813eJake Slack try 36803928aee4356845252ac6b662d5c72c29903813eJake Slack { 36903928aee4356845252ac6b662d5c72c29903813eJake Slack return Class.forName(cl.getName(), false, Thread.currentThread().getContextClassLoader()); 37003928aee4356845252ac6b662d5c72c29903813eJake Slack } 37103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (ClassNotFoundException e) 37203928aee4356845252ac6b662d5c72c29903813eJake Slack { 37303928aee4356845252ac6b662d5c72c29903813eJake Slack return super.resolveClass(cl); 37403928aee4356845252ac6b662d5c72c29903813eJake Slack } 37503928aee4356845252ac6b662d5c72c29903813eJake Slack } 37603928aee4356845252ac6b662d5c72c29903813eJake Slack } 37703928aee4356845252ac6b662d5c72c29903813eJake Slack 37803928aee4356845252ac6b662d5c72c29903813eJake Slack 37903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 38003928aee4356845252ac6b662d5c72c29903813eJake Slack * Set the time in seconds which is the interval between 38103928aee4356845252ac6b662d5c72c29903813eJake Slack * saving the session access time to the database. 38203928aee4356845252ac6b662d5c72c29903813eJake Slack * 38303928aee4356845252ac6b662d5c72c29903813eJake Slack * This is an optimization that prevents the database from 38403928aee4356845252ac6b662d5c72c29903813eJake Slack * being overloaded when a session is accessed very frequently. 38503928aee4356845252ac6b662d5c72c29903813eJake Slack * 38603928aee4356845252ac6b662d5c72c29903813eJake Slack * On session exit, if the session attributes have NOT changed, 38703928aee4356845252ac6b662d5c72c29903813eJake Slack * the time at which we last saved the accessed 38803928aee4356845252ac6b662d5c72c29903813eJake Slack * time is compared to the current accessed time. If the interval 38903928aee4356845252ac6b662d5c72c29903813eJake Slack * is at least saveIntervalSecs, then the access time will be 39003928aee4356845252ac6b662d5c72c29903813eJake Slack * persisted to the database. 39103928aee4356845252ac6b662d5c72c29903813eJake Slack * 39203928aee4356845252ac6b662d5c72c29903813eJake Slack * If any session attribute does change, then the attributes and 39303928aee4356845252ac6b662d5c72c29903813eJake Slack * the accessed time are persisted. 39403928aee4356845252ac6b662d5c72c29903813eJake Slack * 39503928aee4356845252ac6b662d5c72c29903813eJake Slack * @param sec 39603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 39703928aee4356845252ac6b662d5c72c29903813eJake Slack public void setSaveInterval (long sec) 39803928aee4356845252ac6b662d5c72c29903813eJake Slack { 39903928aee4356845252ac6b662d5c72c29903813eJake Slack _saveIntervalSec=sec; 40003928aee4356845252ac6b662d5c72c29903813eJake Slack } 40103928aee4356845252ac6b662d5c72c29903813eJake Slack 40203928aee4356845252ac6b662d5c72c29903813eJake Slack public long getSaveInterval () 40303928aee4356845252ac6b662d5c72c29903813eJake Slack { 40403928aee4356845252ac6b662d5c72c29903813eJake Slack return _saveIntervalSec; 40503928aee4356845252ac6b662d5c72c29903813eJake Slack } 40603928aee4356845252ac6b662d5c72c29903813eJake Slack 40703928aee4356845252ac6b662d5c72c29903813eJake Slack 40803928aee4356845252ac6b662d5c72c29903813eJake Slack 40903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 41003928aee4356845252ac6b662d5c72c29903813eJake Slack * A method that can be implemented in subclasses to support 41103928aee4356845252ac6b662d5c72c29903813eJake Slack * distributed caching of sessions. This method will be 41203928aee4356845252ac6b662d5c72c29903813eJake Slack * called whenever the session is written to the database 41303928aee4356845252ac6b662d5c72c29903813eJake Slack * because the session data has changed. 41403928aee4356845252ac6b662d5c72c29903813eJake Slack * 41503928aee4356845252ac6b662d5c72c29903813eJake Slack * This could be used eg with a JMS backplane to notify nodes 41603928aee4356845252ac6b662d5c72c29903813eJake Slack * that the session has changed and to delete the session from 41703928aee4356845252ac6b662d5c72c29903813eJake Slack * the node's cache, and re-read it from the database. 41803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param session 41903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 42003928aee4356845252ac6b662d5c72c29903813eJake Slack public void cacheInvalidate (Session session) 42103928aee4356845252ac6b662d5c72c29903813eJake Slack { 42203928aee4356845252ac6b662d5c72c29903813eJake Slack 42303928aee4356845252ac6b662d5c72c29903813eJake Slack } 42403928aee4356845252ac6b662d5c72c29903813eJake Slack 42503928aee4356845252ac6b662d5c72c29903813eJake Slack 42603928aee4356845252ac6b662d5c72c29903813eJake Slack /** 42703928aee4356845252ac6b662d5c72c29903813eJake Slack * A session has been requested by its id on this node. 42803928aee4356845252ac6b662d5c72c29903813eJake Slack * 42903928aee4356845252ac6b662d5c72c29903813eJake Slack * Load the session by id AND context path from the database. 43003928aee4356845252ac6b662d5c72c29903813eJake Slack * Multiple contexts may share the same session id (due to dispatching) 43103928aee4356845252ac6b662d5c72c29903813eJake Slack * but they CANNOT share the same contents. 43203928aee4356845252ac6b662d5c72c29903813eJake Slack * 43303928aee4356845252ac6b662d5c72c29903813eJake Slack * Check if last node id is my node id, if so, then the session we have 43403928aee4356845252ac6b662d5c72c29903813eJake Slack * in memory cannot be stale. If another node used the session last, then 43503928aee4356845252ac6b662d5c72c29903813eJake Slack * we need to refresh from the db. 43603928aee4356845252ac6b662d5c72c29903813eJake Slack * 43703928aee4356845252ac6b662d5c72c29903813eJake Slack * NOTE: this method will go to the database, so if you only want to check 43803928aee4356845252ac6b662d5c72c29903813eJake Slack * for the existence of a Session in memory, use _sessions.get(id) instead. 43903928aee4356845252ac6b662d5c72c29903813eJake Slack * 44003928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSession(java.lang.String) 44103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 44203928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 44303928aee4356845252ac6b662d5c72c29903813eJake Slack public Session getSession(String idInCluster) 44403928aee4356845252ac6b662d5c72c29903813eJake Slack { 44503928aee4356845252ac6b662d5c72c29903813eJake Slack Session session = null; 44603928aee4356845252ac6b662d5c72c29903813eJake Slack Session memSession = (Session)_sessions.get(idInCluster); 44703928aee4356845252ac6b662d5c72c29903813eJake Slack 44803928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 44903928aee4356845252ac6b662d5c72c29903813eJake Slack { 45003928aee4356845252ac6b662d5c72c29903813eJake Slack //check if we need to reload the session - 45103928aee4356845252ac6b662d5c72c29903813eJake Slack //as an optimization, don't reload on every access 45203928aee4356845252ac6b662d5c72c29903813eJake Slack //to reduce the load on the database. This introduces a window of 45303928aee4356845252ac6b662d5c72c29903813eJake Slack //possibility that the node may decide that the session is local to it, 45403928aee4356845252ac6b662d5c72c29903813eJake Slack //when the session has actually been live on another node, and then 45503928aee4356845252ac6b662d5c72c29903813eJake Slack //re-migrated to this node. This should be an extremely rare occurrence, 45603928aee4356845252ac6b662d5c72c29903813eJake Slack //as load-balancers are generally well-behaved and consistently send 45703928aee4356845252ac6b662d5c72c29903813eJake Slack //sessions to the same node, changing only iff that node fails. 45803928aee4356845252ac6b662d5c72c29903813eJake Slack //Session data = null; 45903928aee4356845252ac6b662d5c72c29903813eJake Slack long now = System.currentTimeMillis(); 46003928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 46103928aee4356845252ac6b662d5c72c29903813eJake Slack { 46203928aee4356845252ac6b662d5c72c29903813eJake Slack if (memSession==null) 46303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession("+idInCluster+"): not in session map,"+ 46403928aee4356845252ac6b662d5c72c29903813eJake Slack " now="+now+ 46503928aee4356845252ac6b662d5c72c29903813eJake Slack " lastSaved="+(memSession==null?0:memSession._lastSaved)+ 46603928aee4356845252ac6b662d5c72c29903813eJake Slack " interval="+(_saveIntervalSec * 1000L)); 46703928aee4356845252ac6b662d5c72c29903813eJake Slack else 46803928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession("+idInCluster+"): in session map, "+ 46903928aee4356845252ac6b662d5c72c29903813eJake Slack " now="+now+ 47003928aee4356845252ac6b662d5c72c29903813eJake Slack " lastSaved="+(memSession==null?0:memSession._lastSaved)+ 47103928aee4356845252ac6b662d5c72c29903813eJake Slack " interval="+(_saveIntervalSec * 1000L)+ 47203928aee4356845252ac6b662d5c72c29903813eJake Slack " lastNode="+memSession._lastNode+ 47303928aee4356845252ac6b662d5c72c29903813eJake Slack " thisNode="+getSessionIdManager().getWorkerName()+ 47403928aee4356845252ac6b662d5c72c29903813eJake Slack " difference="+(now - memSession._lastSaved)); 47503928aee4356845252ac6b662d5c72c29903813eJake Slack } 47603928aee4356845252ac6b662d5c72c29903813eJake Slack 47703928aee4356845252ac6b662d5c72c29903813eJake Slack try 47803928aee4356845252ac6b662d5c72c29903813eJake Slack { 47903928aee4356845252ac6b662d5c72c29903813eJake Slack if (memSession==null) 48003928aee4356845252ac6b662d5c72c29903813eJake Slack { 48103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession("+idInCluster+"): no session in session map. Reloading session data from db."); 48203928aee4356845252ac6b662d5c72c29903813eJake Slack session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context)); 48303928aee4356845252ac6b662d5c72c29903813eJake Slack } 48403928aee4356845252ac6b662d5c72c29903813eJake Slack else if ((now - memSession._lastSaved) >= (_saveIntervalSec * 1000L)) 48503928aee4356845252ac6b662d5c72c29903813eJake Slack { 48603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession("+idInCluster+"): stale session. Reloading session data from db."); 48703928aee4356845252ac6b662d5c72c29903813eJake Slack session = loadSession(idInCluster, canonicalize(_context.getContextPath()), getVirtualHost(_context)); 48803928aee4356845252ac6b662d5c72c29903813eJake Slack } 48903928aee4356845252ac6b662d5c72c29903813eJake Slack else 49003928aee4356845252ac6b662d5c72c29903813eJake Slack { 49103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession("+idInCluster+"): session in session map"); 49203928aee4356845252ac6b662d5c72c29903813eJake Slack session = memSession; 49303928aee4356845252ac6b662d5c72c29903813eJake Slack } 49403928aee4356845252ac6b662d5c72c29903813eJake Slack } 49503928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 49603928aee4356845252ac6b662d5c72c29903813eJake Slack { 49703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Unable to load session "+idInCluster, e); 49803928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 49903928aee4356845252ac6b662d5c72c29903813eJake Slack } 50003928aee4356845252ac6b662d5c72c29903813eJake Slack 50103928aee4356845252ac6b662d5c72c29903813eJake Slack 50203928aee4356845252ac6b662d5c72c29903813eJake Slack //If we have a session 50303928aee4356845252ac6b662d5c72c29903813eJake Slack if (session != null) 50403928aee4356845252ac6b662d5c72c29903813eJake Slack { 50503928aee4356845252ac6b662d5c72c29903813eJake Slack //If the session was last used on a different node, or session doesn't exist on this node 50603928aee4356845252ac6b662d5c72c29903813eJake Slack if (!session.getLastNode().equals(getSessionIdManager().getWorkerName()) || memSession==null) 50703928aee4356845252ac6b662d5c72c29903813eJake Slack { 50803928aee4356845252ac6b662d5c72c29903813eJake Slack //if session doesn't expire, or has not already expired, update it and put it in this nodes' memory 50903928aee4356845252ac6b662d5c72c29903813eJake Slack if (session._expiryTime <= 0 || session._expiryTime > now) 51003928aee4356845252ac6b662d5c72c29903813eJake Slack { 51103928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 51203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession("+idInCluster+"): lastNode="+session.getLastNode()+" thisNode="+getSessionIdManager().getWorkerName()); 51303928aee4356845252ac6b662d5c72c29903813eJake Slack 51403928aee4356845252ac6b662d5c72c29903813eJake Slack session.setLastNode(getSessionIdManager().getWorkerName()); 51503928aee4356845252ac6b662d5c72c29903813eJake Slack _sessions.put(idInCluster, session); 51603928aee4356845252ac6b662d5c72c29903813eJake Slack 51703928aee4356845252ac6b662d5c72c29903813eJake Slack //update in db: if unable to update, session will be scavenged later 51803928aee4356845252ac6b662d5c72c29903813eJake Slack try 51903928aee4356845252ac6b662d5c72c29903813eJake Slack { 52003928aee4356845252ac6b662d5c72c29903813eJake Slack updateSessionNode(session); 52103928aee4356845252ac6b662d5c72c29903813eJake Slack session.didActivate(); 52203928aee4356845252ac6b662d5c72c29903813eJake Slack } 52303928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 52403928aee4356845252ac6b662d5c72c29903813eJake Slack { 52503928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Unable to update freshly loaded session "+idInCluster, e); 52603928aee4356845252ac6b662d5c72c29903813eJake Slack return null; 52703928aee4356845252ac6b662d5c72c29903813eJake Slack } 52803928aee4356845252ac6b662d5c72c29903813eJake Slack } 52903928aee4356845252ac6b662d5c72c29903813eJake Slack else 53003928aee4356845252ac6b662d5c72c29903813eJake Slack { 53103928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession ({}): Session has expired", idInCluster); 53203928aee4356845252ac6b662d5c72c29903813eJake Slack session=null; 53303928aee4356845252ac6b662d5c72c29903813eJake Slack } 53403928aee4356845252ac6b662d5c72c29903813eJake Slack 53503928aee4356845252ac6b662d5c72c29903813eJake Slack } 53603928aee4356845252ac6b662d5c72c29903813eJake Slack else 53703928aee4356845252ac6b662d5c72c29903813eJake Slack { 53803928aee4356845252ac6b662d5c72c29903813eJake Slack //the session loaded from the db and the one in memory are the same, so keep using the one in memory 53903928aee4356845252ac6b662d5c72c29903813eJake Slack session = memSession; 54003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession({}): Session not stale {}", idInCluster,session); 54103928aee4356845252ac6b662d5c72c29903813eJake Slack } 54203928aee4356845252ac6b662d5c72c29903813eJake Slack } 54303928aee4356845252ac6b662d5c72c29903813eJake Slack else 54403928aee4356845252ac6b662d5c72c29903813eJake Slack { 54503928aee4356845252ac6b662d5c72c29903813eJake Slack //No session in db with matching id and context path. 54603928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("getSession({}): No session in database matching id={}",idInCluster,idInCluster); 54703928aee4356845252ac6b662d5c72c29903813eJake Slack } 54803928aee4356845252ac6b662d5c72c29903813eJake Slack 54903928aee4356845252ac6b662d5c72c29903813eJake Slack return session; 55003928aee4356845252ac6b662d5c72c29903813eJake Slack } 55103928aee4356845252ac6b662d5c72c29903813eJake Slack } 55203928aee4356845252ac6b662d5c72c29903813eJake Slack 55303928aee4356845252ac6b662d5c72c29903813eJake Slack /** 55403928aee4356845252ac6b662d5c72c29903813eJake Slack * Get the number of sessions. 55503928aee4356845252ac6b662d5c72c29903813eJake Slack * 55603928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSessionManager#getSessions() 55703928aee4356845252ac6b662d5c72c29903813eJake Slack */ 55803928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 55903928aee4356845252ac6b662d5c72c29903813eJake Slack public int getSessions() 56003928aee4356845252ac6b662d5c72c29903813eJake Slack { 56103928aee4356845252ac6b662d5c72c29903813eJake Slack int size = 0; 56203928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 56303928aee4356845252ac6b662d5c72c29903813eJake Slack { 56403928aee4356845252ac6b662d5c72c29903813eJake Slack size = _sessions.size(); 56503928aee4356845252ac6b662d5c72c29903813eJake Slack } 56603928aee4356845252ac6b662d5c72c29903813eJake Slack return size; 56703928aee4356845252ac6b662d5c72c29903813eJake Slack } 56803928aee4356845252ac6b662d5c72c29903813eJake Slack 56903928aee4356845252ac6b662d5c72c29903813eJake Slack 57003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 57103928aee4356845252ac6b662d5c72c29903813eJake Slack * Start the session manager. 57203928aee4356845252ac6b662d5c72c29903813eJake Slack * 57303928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStart() 57403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 57503928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 57603928aee4356845252ac6b662d5c72c29903813eJake Slack public void doStart() throws Exception 57703928aee4356845252ac6b662d5c72c29903813eJake Slack { 57803928aee4356845252ac6b662d5c72c29903813eJake Slack if (_sessionIdManager==null) 57903928aee4356845252ac6b662d5c72c29903813eJake Slack throw new IllegalStateException("No session id manager defined"); 58003928aee4356845252ac6b662d5c72c29903813eJake Slack 58103928aee4356845252ac6b662d5c72c29903813eJake Slack _jdbcSessionIdMgr = (JDBCSessionIdManager)_sessionIdManager; 58203928aee4356845252ac6b662d5c72c29903813eJake Slack 58303928aee4356845252ac6b662d5c72c29903813eJake Slack _sessions = new ConcurrentHashMap<String, AbstractSession>(); 58403928aee4356845252ac6b662d5c72c29903813eJake Slack 58503928aee4356845252ac6b662d5c72c29903813eJake Slack super.doStart(); 58603928aee4356845252ac6b662d5c72c29903813eJake Slack } 58703928aee4356845252ac6b662d5c72c29903813eJake Slack 58803928aee4356845252ac6b662d5c72c29903813eJake Slack 58903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 59003928aee4356845252ac6b662d5c72c29903813eJake Slack * Stop the session manager. 59103928aee4356845252ac6b662d5c72c29903813eJake Slack * 59203928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSessionManager#doStop() 59303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 59403928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 59503928aee4356845252ac6b662d5c72c29903813eJake Slack public void doStop() throws Exception 59603928aee4356845252ac6b662d5c72c29903813eJake Slack { 59703928aee4356845252ac6b662d5c72c29903813eJake Slack _sessions.clear(); 59803928aee4356845252ac6b662d5c72c29903813eJake Slack _sessions = null; 59903928aee4356845252ac6b662d5c72c29903813eJake Slack 60003928aee4356845252ac6b662d5c72c29903813eJake Slack super.doStop(); 60103928aee4356845252ac6b662d5c72c29903813eJake Slack } 60203928aee4356845252ac6b662d5c72c29903813eJake Slack 60303928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 60403928aee4356845252ac6b662d5c72c29903813eJake Slack protected void invalidateSessions() 60503928aee4356845252ac6b662d5c72c29903813eJake Slack { 60603928aee4356845252ac6b662d5c72c29903813eJake Slack //Do nothing - we don't want to remove and 60703928aee4356845252ac6b662d5c72c29903813eJake Slack //invalidate all the sessions because this 60803928aee4356845252ac6b662d5c72c29903813eJake Slack //method is called from doStop(), and just 60903928aee4356845252ac6b662d5c72c29903813eJake Slack //because this context is stopping does not 61003928aee4356845252ac6b662d5c72c29903813eJake Slack //mean that we should remove the session from 61103928aee4356845252ac6b662d5c72c29903813eJake Slack //any other nodes 61203928aee4356845252ac6b662d5c72c29903813eJake Slack } 61303928aee4356845252ac6b662d5c72c29903813eJake Slack 61403928aee4356845252ac6b662d5c72c29903813eJake Slack 61503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 61603928aee4356845252ac6b662d5c72c29903813eJake Slack * Invalidate a session. 61703928aee4356845252ac6b662d5c72c29903813eJake Slack * 61803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param idInCluster 61903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 62003928aee4356845252ac6b662d5c72c29903813eJake Slack protected void invalidateSession (String idInCluster) 62103928aee4356845252ac6b662d5c72c29903813eJake Slack { 62203928aee4356845252ac6b662d5c72c29903813eJake Slack Session session = null; 62303928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 62403928aee4356845252ac6b662d5c72c29903813eJake Slack { 62503928aee4356845252ac6b662d5c72c29903813eJake Slack session = (Session)_sessions.get(idInCluster); 62603928aee4356845252ac6b662d5c72c29903813eJake Slack } 62703928aee4356845252ac6b662d5c72c29903813eJake Slack 62803928aee4356845252ac6b662d5c72c29903813eJake Slack if (session != null) 62903928aee4356845252ac6b662d5c72c29903813eJake Slack { 63003928aee4356845252ac6b662d5c72c29903813eJake Slack session.invalidate(); 63103928aee4356845252ac6b662d5c72c29903813eJake Slack } 63203928aee4356845252ac6b662d5c72c29903813eJake Slack } 63303928aee4356845252ac6b662d5c72c29903813eJake Slack 63403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 63503928aee4356845252ac6b662d5c72c29903813eJake Slack * Delete an existing session, both from the in-memory map and 63603928aee4356845252ac6b662d5c72c29903813eJake Slack * the database. 63703928aee4356845252ac6b662d5c72c29903813eJake Slack * 63803928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSessionManager#removeSession(java.lang.String) 63903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 64003928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 64103928aee4356845252ac6b662d5c72c29903813eJake Slack protected boolean removeSession(String idInCluster) 64203928aee4356845252ac6b662d5c72c29903813eJake Slack { 64303928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 64403928aee4356845252ac6b662d5c72c29903813eJake Slack { 64503928aee4356845252ac6b662d5c72c29903813eJake Slack Session session = (Session)_sessions.remove(idInCluster); 64603928aee4356845252ac6b662d5c72c29903813eJake Slack try 64703928aee4356845252ac6b662d5c72c29903813eJake Slack { 64803928aee4356845252ac6b662d5c72c29903813eJake Slack if (session != null) 64903928aee4356845252ac6b662d5c72c29903813eJake Slack deleteSession(session); 65003928aee4356845252ac6b662d5c72c29903813eJake Slack } 65103928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 65203928aee4356845252ac6b662d5c72c29903813eJake Slack { 65303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Problem deleting session id="+idInCluster, e); 65403928aee4356845252ac6b662d5c72c29903813eJake Slack } 65503928aee4356845252ac6b662d5c72c29903813eJake Slack return session!=null; 65603928aee4356845252ac6b662d5c72c29903813eJake Slack } 65703928aee4356845252ac6b662d5c72c29903813eJake Slack } 65803928aee4356845252ac6b662d5c72c29903813eJake Slack 65903928aee4356845252ac6b662d5c72c29903813eJake Slack 66003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 66103928aee4356845252ac6b662d5c72c29903813eJake Slack * Add a newly created session to our in-memory list for this node and persist it. 66203928aee4356845252ac6b662d5c72c29903813eJake Slack * 66303928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSessionManager#addSession(org.eclipse.jetty.server.session.AbstractSession) 66403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 66503928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 66603928aee4356845252ac6b662d5c72c29903813eJake Slack protected void addSession(AbstractSession session) 66703928aee4356845252ac6b662d5c72c29903813eJake Slack { 66803928aee4356845252ac6b662d5c72c29903813eJake Slack if (session==null) 66903928aee4356845252ac6b662d5c72c29903813eJake Slack return; 67003928aee4356845252ac6b662d5c72c29903813eJake Slack 67103928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 67203928aee4356845252ac6b662d5c72c29903813eJake Slack { 67303928aee4356845252ac6b662d5c72c29903813eJake Slack _sessions.put(session.getClusterId(), session); 67403928aee4356845252ac6b662d5c72c29903813eJake Slack } 67503928aee4356845252ac6b662d5c72c29903813eJake Slack 67603928aee4356845252ac6b662d5c72c29903813eJake Slack //TODO or delay the store until exit out of session? If we crash before we store it 67703928aee4356845252ac6b662d5c72c29903813eJake Slack //then session data will be lost. 67803928aee4356845252ac6b662d5c72c29903813eJake Slack try 67903928aee4356845252ac6b662d5c72c29903813eJake Slack { 68003928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (session) 68103928aee4356845252ac6b662d5c72c29903813eJake Slack { 68203928aee4356845252ac6b662d5c72c29903813eJake Slack session.willPassivate(); 68303928aee4356845252ac6b662d5c72c29903813eJake Slack storeSession(((JDBCSessionManager.Session)session)); 68403928aee4356845252ac6b662d5c72c29903813eJake Slack session.didActivate(); 68503928aee4356845252ac6b662d5c72c29903813eJake Slack } 68603928aee4356845252ac6b662d5c72c29903813eJake Slack } 68703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 68803928aee4356845252ac6b662d5c72c29903813eJake Slack { 68903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Unable to store new session id="+session.getId() , e); 69003928aee4356845252ac6b662d5c72c29903813eJake Slack } 69103928aee4356845252ac6b662d5c72c29903813eJake Slack } 69203928aee4356845252ac6b662d5c72c29903813eJake Slack 69303928aee4356845252ac6b662d5c72c29903813eJake Slack 69403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 69503928aee4356845252ac6b662d5c72c29903813eJake Slack * Make a new Session. 69603928aee4356845252ac6b662d5c72c29903813eJake Slack * 69703928aee4356845252ac6b662d5c72c29903813eJake Slack * @see org.eclipse.jetty.server.session.AbstractSessionManager#newSession(javax.servlet.http.HttpServletRequest) 69803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 69903928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 70003928aee4356845252ac6b662d5c72c29903813eJake Slack protected AbstractSession newSession(HttpServletRequest request) 70103928aee4356845252ac6b662d5c72c29903813eJake Slack { 70203928aee4356845252ac6b662d5c72c29903813eJake Slack return new Session(request); 70303928aee4356845252ac6b662d5c72c29903813eJake Slack } 70403928aee4356845252ac6b662d5c72c29903813eJake Slack 70503928aee4356845252ac6b662d5c72c29903813eJake Slack /* ------------------------------------------------------------ */ 70603928aee4356845252ac6b662d5c72c29903813eJake Slack /** Remove session from manager 70703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param session The session to remove 70803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param invalidate True if {@link HttpSessionListener#sessionDestroyed(HttpSessionEvent)} and 70903928aee4356845252ac6b662d5c72c29903813eJake Slack * {@link SessionIdManager#invalidateAll(String)} should be called. 71003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 71103928aee4356845252ac6b662d5c72c29903813eJake Slack @Override 71203928aee4356845252ac6b662d5c72c29903813eJake Slack public void removeSession(AbstractSession session, boolean invalidate) 71303928aee4356845252ac6b662d5c72c29903813eJake Slack { 71403928aee4356845252ac6b662d5c72c29903813eJake Slack // Remove session from context and global maps 71503928aee4356845252ac6b662d5c72c29903813eJake Slack boolean removed = false; 71603928aee4356845252ac6b662d5c72c29903813eJake Slack 71703928aee4356845252ac6b662d5c72c29903813eJake Slack synchronized (this) 71803928aee4356845252ac6b662d5c72c29903813eJake Slack { 71903928aee4356845252ac6b662d5c72c29903813eJake Slack //take this session out of the map of sessions for this context 72003928aee4356845252ac6b662d5c72c29903813eJake Slack if (getSession(session.getClusterId()) != null) 72103928aee4356845252ac6b662d5c72c29903813eJake Slack { 72203928aee4356845252ac6b662d5c72c29903813eJake Slack removed = true; 72303928aee4356845252ac6b662d5c72c29903813eJake Slack removeSession(session.getClusterId()); 72403928aee4356845252ac6b662d5c72c29903813eJake Slack } 72503928aee4356845252ac6b662d5c72c29903813eJake Slack } 72603928aee4356845252ac6b662d5c72c29903813eJake Slack 72703928aee4356845252ac6b662d5c72c29903813eJake Slack if (removed) 72803928aee4356845252ac6b662d5c72c29903813eJake Slack { 72903928aee4356845252ac6b662d5c72c29903813eJake Slack // Remove session from all context and global id maps 73003928aee4356845252ac6b662d5c72c29903813eJake Slack _sessionIdManager.removeSession(session); 73103928aee4356845252ac6b662d5c72c29903813eJake Slack 73203928aee4356845252ac6b662d5c72c29903813eJake Slack if (invalidate) 73303928aee4356845252ac6b662d5c72c29903813eJake Slack _sessionIdManager.invalidateAll(session.getClusterId()); 73403928aee4356845252ac6b662d5c72c29903813eJake Slack 73503928aee4356845252ac6b662d5c72c29903813eJake Slack if (invalidate && !_sessionListeners.isEmpty()) 73603928aee4356845252ac6b662d5c72c29903813eJake Slack { 73703928aee4356845252ac6b662d5c72c29903813eJake Slack HttpSessionEvent event=new HttpSessionEvent(session); 73803928aee4356845252ac6b662d5c72c29903813eJake Slack for (HttpSessionListener l : _sessionListeners) 73903928aee4356845252ac6b662d5c72c29903813eJake Slack l.sessionDestroyed(event); 74003928aee4356845252ac6b662d5c72c29903813eJake Slack } 74103928aee4356845252ac6b662d5c72c29903813eJake Slack if (!invalidate) 74203928aee4356845252ac6b662d5c72c29903813eJake Slack { 74303928aee4356845252ac6b662d5c72c29903813eJake Slack session.willPassivate(); 74403928aee4356845252ac6b662d5c72c29903813eJake Slack } 74503928aee4356845252ac6b662d5c72c29903813eJake Slack } 74603928aee4356845252ac6b662d5c72c29903813eJake Slack } 74703928aee4356845252ac6b662d5c72c29903813eJake Slack 74803928aee4356845252ac6b662d5c72c29903813eJake Slack 74903928aee4356845252ac6b662d5c72c29903813eJake Slack /** 75003928aee4356845252ac6b662d5c72c29903813eJake Slack * Expire any Sessions we have in memory matching the list of 75103928aee4356845252ac6b662d5c72c29903813eJake Slack * expired Session ids. 75203928aee4356845252ac6b662d5c72c29903813eJake Slack * 75303928aee4356845252ac6b662d5c72c29903813eJake Slack * @param sessionIds 75403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 75503928aee4356845252ac6b662d5c72c29903813eJake Slack protected void expire (List<?> sessionIds) 75603928aee4356845252ac6b662d5c72c29903813eJake Slack { 75703928aee4356845252ac6b662d5c72c29903813eJake Slack //don't attempt to scavenge if we are shutting down 75803928aee4356845252ac6b662d5c72c29903813eJake Slack if (isStopping() || isStopped()) 75903928aee4356845252ac6b662d5c72c29903813eJake Slack return; 76003928aee4356845252ac6b662d5c72c29903813eJake Slack 76103928aee4356845252ac6b662d5c72c29903813eJake Slack //Remove any sessions we already have in memory that match the ids 76203928aee4356845252ac6b662d5c72c29903813eJake Slack Thread thread=Thread.currentThread(); 76303928aee4356845252ac6b662d5c72c29903813eJake Slack ClassLoader old_loader=thread.getContextClassLoader(); 76403928aee4356845252ac6b662d5c72c29903813eJake Slack ListIterator<?> itor = sessionIds.listIterator(); 76503928aee4356845252ac6b662d5c72c29903813eJake Slack 76603928aee4356845252ac6b662d5c72c29903813eJake Slack try 76703928aee4356845252ac6b662d5c72c29903813eJake Slack { 76803928aee4356845252ac6b662d5c72c29903813eJake Slack while (itor.hasNext()) 76903928aee4356845252ac6b662d5c72c29903813eJake Slack { 77003928aee4356845252ac6b662d5c72c29903813eJake Slack String sessionId = (String)itor.next(); 77103928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 77203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Expiring session id "+sessionId); 77303928aee4356845252ac6b662d5c72c29903813eJake Slack 77403928aee4356845252ac6b662d5c72c29903813eJake Slack Session session = (Session)_sessions.get(sessionId); 77503928aee4356845252ac6b662d5c72c29903813eJake Slack if (session != null) 77603928aee4356845252ac6b662d5c72c29903813eJake Slack { 77703928aee4356845252ac6b662d5c72c29903813eJake Slack session.timeout(); 77803928aee4356845252ac6b662d5c72c29903813eJake Slack itor.remove(); 77903928aee4356845252ac6b662d5c72c29903813eJake Slack } 78003928aee4356845252ac6b662d5c72c29903813eJake Slack else 78103928aee4356845252ac6b662d5c72c29903813eJake Slack { 78203928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 78303928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Unrecognized session id="+sessionId); 78403928aee4356845252ac6b662d5c72c29903813eJake Slack } 78503928aee4356845252ac6b662d5c72c29903813eJake Slack } 78603928aee4356845252ac6b662d5c72c29903813eJake Slack } 78703928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Throwable t) 78803928aee4356845252ac6b662d5c72c29903813eJake Slack { 78903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.warn("Problem expiring sessions", t); 79003928aee4356845252ac6b662d5c72c29903813eJake Slack } 79103928aee4356845252ac6b662d5c72c29903813eJake Slack finally 79203928aee4356845252ac6b662d5c72c29903813eJake Slack { 79303928aee4356845252ac6b662d5c72c29903813eJake Slack thread.setContextClassLoader(old_loader); 79403928aee4356845252ac6b662d5c72c29903813eJake Slack } 79503928aee4356845252ac6b662d5c72c29903813eJake Slack } 79603928aee4356845252ac6b662d5c72c29903813eJake Slack 79703928aee4356845252ac6b662d5c72c29903813eJake Slack 79803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 79903928aee4356845252ac6b662d5c72c29903813eJake Slack * Load a session from the database 80003928aee4356845252ac6b662d5c72c29903813eJake Slack * @param id 80103928aee4356845252ac6b662d5c72c29903813eJake Slack * @return the session data that was loaded 80203928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 80303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 80403928aee4356845252ac6b662d5c72c29903813eJake Slack protected Session loadSession (final String id, final String canonicalContextPath, final String vhost) 80503928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 80603928aee4356845252ac6b662d5c72c29903813eJake Slack { 80703928aee4356845252ac6b662d5c72c29903813eJake Slack final AtomicReference<Session> _reference = new AtomicReference<Session>(); 80803928aee4356845252ac6b662d5c72c29903813eJake Slack final AtomicReference<Exception> _exception = new AtomicReference<Exception>(); 80903928aee4356845252ac6b662d5c72c29903813eJake Slack Runnable load = new Runnable() 81003928aee4356845252ac6b662d5c72c29903813eJake Slack { 81103928aee4356845252ac6b662d5c72c29903813eJake Slack @SuppressWarnings("unchecked") 81203928aee4356845252ac6b662d5c72c29903813eJake Slack public void run() 81303928aee4356845252ac6b662d5c72c29903813eJake Slack { 81403928aee4356845252ac6b662d5c72c29903813eJake Slack Session session = null; 81503928aee4356845252ac6b662d5c72c29903813eJake Slack Connection connection=null; 81603928aee4356845252ac6b662d5c72c29903813eJake Slack PreparedStatement statement = null; 81703928aee4356845252ac6b662d5c72c29903813eJake Slack try 81803928aee4356845252ac6b662d5c72c29903813eJake Slack { 81903928aee4356845252ac6b662d5c72c29903813eJake Slack connection = getConnection(); 82003928aee4356845252ac6b662d5c72c29903813eJake Slack statement = _jdbcSessionIdMgr._dbAdaptor.getLoadStatement(connection, id, canonicalContextPath, vhost); 82103928aee4356845252ac6b662d5c72c29903813eJake Slack ResultSet result = statement.executeQuery(); 82203928aee4356845252ac6b662d5c72c29903813eJake Slack if (result.next()) 82303928aee4356845252ac6b662d5c72c29903813eJake Slack { 82403928aee4356845252ac6b662d5c72c29903813eJake Slack session = new Session(id, result.getString(_jdbcSessionIdMgr._sessionTableRowId), result.getLong("createTime"), result.getLong("accessTime")); 82503928aee4356845252ac6b662d5c72c29903813eJake Slack session.setCookieSet(result.getLong("cookieTime")); 82603928aee4356845252ac6b662d5c72c29903813eJake Slack session.setLastAccessedTime(result.getLong("lastAccessTime")); 82703928aee4356845252ac6b662d5c72c29903813eJake Slack session.setLastNode(result.getString("lastNode")); 82803928aee4356845252ac6b662d5c72c29903813eJake Slack session.setLastSaved(result.getLong("lastSavedTime")); 82903928aee4356845252ac6b662d5c72c29903813eJake Slack session.setExpiryTime(result.getLong("expiryTime")); 83003928aee4356845252ac6b662d5c72c29903813eJake Slack session.setCanonicalContext(result.getString("contextPath")); 83103928aee4356845252ac6b662d5c72c29903813eJake Slack session.setVirtualHost(result.getString("virtualHost")); 83203928aee4356845252ac6b662d5c72c29903813eJake Slack 83303928aee4356845252ac6b662d5c72c29903813eJake Slack InputStream is = ((JDBCSessionIdManager)getSessionIdManager())._dbAdaptor.getBlobInputStream(result, "map"); 83403928aee4356845252ac6b662d5c72c29903813eJake Slack ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream (is); 83503928aee4356845252ac6b662d5c72c29903813eJake Slack Object o = ois.readObject(); 83603928aee4356845252ac6b662d5c72c29903813eJake Slack session.addAttributes((Map<String,Object>)o); 83703928aee4356845252ac6b662d5c72c29903813eJake Slack ois.close(); 83803928aee4356845252ac6b662d5c72c29903813eJake Slack 83903928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 84003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("LOADED session "+session); 84103928aee4356845252ac6b662d5c72c29903813eJake Slack } 84203928aee4356845252ac6b662d5c72c29903813eJake Slack _reference.set(session); 84303928aee4356845252ac6b662d5c72c29903813eJake Slack } 84403928aee4356845252ac6b662d5c72c29903813eJake Slack catch (Exception e) 84503928aee4356845252ac6b662d5c72c29903813eJake Slack { 84603928aee4356845252ac6b662d5c72c29903813eJake Slack _exception.set(e); 84703928aee4356845252ac6b662d5c72c29903813eJake Slack } 84803928aee4356845252ac6b662d5c72c29903813eJake Slack finally 84903928aee4356845252ac6b662d5c72c29903813eJake Slack { 85003928aee4356845252ac6b662d5c72c29903813eJake Slack if (statement!=null) 85103928aee4356845252ac6b662d5c72c29903813eJake Slack { 85203928aee4356845252ac6b662d5c72c29903813eJake Slack try { statement.close(); } 85303928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) { LOG.warn(e); } 85403928aee4356845252ac6b662d5c72c29903813eJake Slack } 85503928aee4356845252ac6b662d5c72c29903813eJake Slack 85603928aee4356845252ac6b662d5c72c29903813eJake Slack if (connection!=null) 85703928aee4356845252ac6b662d5c72c29903813eJake Slack { 85803928aee4356845252ac6b662d5c72c29903813eJake Slack try { connection.close();} 85903928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) { LOG.warn(e); } 86003928aee4356845252ac6b662d5c72c29903813eJake Slack } 86103928aee4356845252ac6b662d5c72c29903813eJake Slack } 86203928aee4356845252ac6b662d5c72c29903813eJake Slack } 86303928aee4356845252ac6b662d5c72c29903813eJake Slack }; 86403928aee4356845252ac6b662d5c72c29903813eJake Slack 86503928aee4356845252ac6b662d5c72c29903813eJake Slack if (_context==null) 86603928aee4356845252ac6b662d5c72c29903813eJake Slack load.run(); 86703928aee4356845252ac6b662d5c72c29903813eJake Slack else 86803928aee4356845252ac6b662d5c72c29903813eJake Slack _context.getContextHandler().handle(load); 86903928aee4356845252ac6b662d5c72c29903813eJake Slack 87003928aee4356845252ac6b662d5c72c29903813eJake Slack if (_exception.get()!=null) 87103928aee4356845252ac6b662d5c72c29903813eJake Slack { 87203928aee4356845252ac6b662d5c72c29903813eJake Slack //if the session could not be restored, take its id out of the pool of currently-in-use 87303928aee4356845252ac6b662d5c72c29903813eJake Slack //session ids 87403928aee4356845252ac6b662d5c72c29903813eJake Slack _jdbcSessionIdMgr.removeSession(id); 87503928aee4356845252ac6b662d5c72c29903813eJake Slack throw _exception.get(); 87603928aee4356845252ac6b662d5c72c29903813eJake Slack } 87703928aee4356845252ac6b662d5c72c29903813eJake Slack 87803928aee4356845252ac6b662d5c72c29903813eJake Slack return _reference.get(); 87903928aee4356845252ac6b662d5c72c29903813eJake Slack } 88003928aee4356845252ac6b662d5c72c29903813eJake Slack 88103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 88203928aee4356845252ac6b662d5c72c29903813eJake Slack * Insert a session into the database. 88303928aee4356845252ac6b662d5c72c29903813eJake Slack * 88403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param data 88503928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 88603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 88703928aee4356845252ac6b662d5c72c29903813eJake Slack protected void storeSession (Session session) 88803928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 88903928aee4356845252ac6b662d5c72c29903813eJake Slack { 89003928aee4356845252ac6b662d5c72c29903813eJake Slack if (session==null) 89103928aee4356845252ac6b662d5c72c29903813eJake Slack return; 89203928aee4356845252ac6b662d5c72c29903813eJake Slack 89303928aee4356845252ac6b662d5c72c29903813eJake Slack //put into the database 89403928aee4356845252ac6b662d5c72c29903813eJake Slack Connection connection = getConnection(); 89503928aee4356845252ac6b662d5c72c29903813eJake Slack PreparedStatement statement = null; 89603928aee4356845252ac6b662d5c72c29903813eJake Slack try 89703928aee4356845252ac6b662d5c72c29903813eJake Slack { 89803928aee4356845252ac6b662d5c72c29903813eJake Slack String rowId = calculateRowId(session); 89903928aee4356845252ac6b662d5c72c29903813eJake Slack 90003928aee4356845252ac6b662d5c72c29903813eJake Slack long now = System.currentTimeMillis(); 90103928aee4356845252ac6b662d5c72c29903813eJake Slack connection.setAutoCommit(true); 90203928aee4356845252ac6b662d5c72c29903813eJake Slack statement = connection.prepareStatement(_jdbcSessionIdMgr._insertSession); 90303928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(1, rowId); //rowId 90403928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(2, session.getId()); //session id 90503928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(3, session.getCanonicalContext()); //context path 90603928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(4, session.getVirtualHost()); //first vhost 90703928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(5, getSessionIdManager().getWorkerName());//my node id 90803928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(6, session.getAccessed());//accessTime 90903928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(7, session.getLastAccessedTime()); //lastAccessTime 91003928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(8, session.getCreationTime()); //time created 91103928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(9, session.getCookieSet());//time cookie was set 91203928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(10, now); //last saved time 91303928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(11, session.getExpiryTime()); 91403928aee4356845252ac6b662d5c72c29903813eJake Slack 91503928aee4356845252ac6b662d5c72c29903813eJake Slack ByteArrayOutputStream baos = new ByteArrayOutputStream(); 91603928aee4356845252ac6b662d5c72c29903813eJake Slack ObjectOutputStream oos = new ObjectOutputStream(baos); 91703928aee4356845252ac6b662d5c72c29903813eJake Slack oos.writeObject(session.getAttributeMap()); 91803928aee4356845252ac6b662d5c72c29903813eJake Slack byte[] bytes = baos.toByteArray(); 91903928aee4356845252ac6b662d5c72c29903813eJake Slack 92003928aee4356845252ac6b662d5c72c29903813eJake Slack ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 92103928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob 92203928aee4356845252ac6b662d5c72c29903813eJake Slack 92303928aee4356845252ac6b662d5c72c29903813eJake Slack statement.executeUpdate(); 92403928aee4356845252ac6b662d5c72c29903813eJake Slack session.setRowId(rowId); //set it on the in-memory data as well as in db 92503928aee4356845252ac6b662d5c72c29903813eJake Slack session.setLastSaved(now); 92603928aee4356845252ac6b662d5c72c29903813eJake Slack 92703928aee4356845252ac6b662d5c72c29903813eJake Slack 92803928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 92903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Stored session "+session); 93003928aee4356845252ac6b662d5c72c29903813eJake Slack } 93103928aee4356845252ac6b662d5c72c29903813eJake Slack finally 93203928aee4356845252ac6b662d5c72c29903813eJake Slack { 93303928aee4356845252ac6b662d5c72c29903813eJake Slack if (statement!=null) 93403928aee4356845252ac6b662d5c72c29903813eJake Slack { 93503928aee4356845252ac6b662d5c72c29903813eJake Slack try { statement.close(); } 93603928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) { LOG.warn(e); } 93703928aee4356845252ac6b662d5c72c29903813eJake Slack } 93803928aee4356845252ac6b662d5c72c29903813eJake Slack 93903928aee4356845252ac6b662d5c72c29903813eJake Slack if (connection!=null) 94003928aee4356845252ac6b662d5c72c29903813eJake Slack connection.close(); 94103928aee4356845252ac6b662d5c72c29903813eJake Slack } 94203928aee4356845252ac6b662d5c72c29903813eJake Slack } 94303928aee4356845252ac6b662d5c72c29903813eJake Slack 94403928aee4356845252ac6b662d5c72c29903813eJake Slack 94503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 94603928aee4356845252ac6b662d5c72c29903813eJake Slack * Update data on an existing persisted session. 94703928aee4356845252ac6b662d5c72c29903813eJake Slack * 94803928aee4356845252ac6b662d5c72c29903813eJake Slack * @param data the session 94903928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 95003928aee4356845252ac6b662d5c72c29903813eJake Slack */ 95103928aee4356845252ac6b662d5c72c29903813eJake Slack protected void updateSession (Session data) 95203928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 95303928aee4356845252ac6b662d5c72c29903813eJake Slack { 95403928aee4356845252ac6b662d5c72c29903813eJake Slack if (data==null) 95503928aee4356845252ac6b662d5c72c29903813eJake Slack return; 95603928aee4356845252ac6b662d5c72c29903813eJake Slack 95703928aee4356845252ac6b662d5c72c29903813eJake Slack Connection connection = getConnection(); 95803928aee4356845252ac6b662d5c72c29903813eJake Slack PreparedStatement statement = null; 95903928aee4356845252ac6b662d5c72c29903813eJake Slack try 96003928aee4356845252ac6b662d5c72c29903813eJake Slack { 96103928aee4356845252ac6b662d5c72c29903813eJake Slack long now = System.currentTimeMillis(); 96203928aee4356845252ac6b662d5c72c29903813eJake Slack connection.setAutoCommit(true); 96303928aee4356845252ac6b662d5c72c29903813eJake Slack statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSession); 96403928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(1, getSessionIdManager().getWorkerName());//my node id 96503928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(2, data.getAccessed());//accessTime 96603928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(3, data.getLastAccessedTime()); //lastAccessTime 96703928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(4, now); //last saved time 96803928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(5, data.getExpiryTime()); 96903928aee4356845252ac6b662d5c72c29903813eJake Slack 97003928aee4356845252ac6b662d5c72c29903813eJake Slack ByteArrayOutputStream baos = new ByteArrayOutputStream(); 97103928aee4356845252ac6b662d5c72c29903813eJake Slack ObjectOutputStream oos = new ObjectOutputStream(baos); 97203928aee4356845252ac6b662d5c72c29903813eJake Slack oos.writeObject(data.getAttributeMap()); 97303928aee4356845252ac6b662d5c72c29903813eJake Slack byte[] bytes = baos.toByteArray(); 97403928aee4356845252ac6b662d5c72c29903813eJake Slack ByteArrayInputStream bais = new ByteArrayInputStream(bytes); 97503928aee4356845252ac6b662d5c72c29903813eJake Slack 97603928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setBinaryStream(6, bais, bytes.length);//attribute map as blob 97703928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(7, data.getRowId()); //rowId 97803928aee4356845252ac6b662d5c72c29903813eJake Slack statement.executeUpdate(); 97903928aee4356845252ac6b662d5c72c29903813eJake Slack 98003928aee4356845252ac6b662d5c72c29903813eJake Slack data.setLastSaved(now); 98103928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 98203928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Updated session "+data); 98303928aee4356845252ac6b662d5c72c29903813eJake Slack } 98403928aee4356845252ac6b662d5c72c29903813eJake Slack finally 98503928aee4356845252ac6b662d5c72c29903813eJake Slack { 98603928aee4356845252ac6b662d5c72c29903813eJake Slack if (statement!=null) 98703928aee4356845252ac6b662d5c72c29903813eJake Slack { 98803928aee4356845252ac6b662d5c72c29903813eJake Slack try { statement.close(); } 98903928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) { LOG.warn(e); } 99003928aee4356845252ac6b662d5c72c29903813eJake Slack } 99103928aee4356845252ac6b662d5c72c29903813eJake Slack 99203928aee4356845252ac6b662d5c72c29903813eJake Slack if (connection!=null) 99303928aee4356845252ac6b662d5c72c29903813eJake Slack connection.close(); 99403928aee4356845252ac6b662d5c72c29903813eJake Slack } 99503928aee4356845252ac6b662d5c72c29903813eJake Slack } 99603928aee4356845252ac6b662d5c72c29903813eJake Slack 99703928aee4356845252ac6b662d5c72c29903813eJake Slack 99803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 99903928aee4356845252ac6b662d5c72c29903813eJake Slack * Update the node on which the session was last seen to be my node. 100003928aee4356845252ac6b662d5c72c29903813eJake Slack * 100103928aee4356845252ac6b662d5c72c29903813eJake Slack * @param data the session 100203928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 100303928aee4356845252ac6b662d5c72c29903813eJake Slack */ 100403928aee4356845252ac6b662d5c72c29903813eJake Slack protected void updateSessionNode (Session data) 100503928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 100603928aee4356845252ac6b662d5c72c29903813eJake Slack { 100703928aee4356845252ac6b662d5c72c29903813eJake Slack String nodeId = getSessionIdManager().getWorkerName(); 100803928aee4356845252ac6b662d5c72c29903813eJake Slack Connection connection = getConnection(); 100903928aee4356845252ac6b662d5c72c29903813eJake Slack PreparedStatement statement = null; 101003928aee4356845252ac6b662d5c72c29903813eJake Slack try 101103928aee4356845252ac6b662d5c72c29903813eJake Slack { 101203928aee4356845252ac6b662d5c72c29903813eJake Slack connection.setAutoCommit(true); 101303928aee4356845252ac6b662d5c72c29903813eJake Slack statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionNode); 101403928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(1, nodeId); 101503928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(2, data.getRowId()); 101603928aee4356845252ac6b662d5c72c29903813eJake Slack statement.executeUpdate(); 101703928aee4356845252ac6b662d5c72c29903813eJake Slack statement.close(); 101803928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 101903928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Updated last node for session id="+data.getId()+", lastNode = "+nodeId); 102003928aee4356845252ac6b662d5c72c29903813eJake Slack } 102103928aee4356845252ac6b662d5c72c29903813eJake Slack finally 102203928aee4356845252ac6b662d5c72c29903813eJake Slack { 102303928aee4356845252ac6b662d5c72c29903813eJake Slack if (statement!=null) 102403928aee4356845252ac6b662d5c72c29903813eJake Slack { 102503928aee4356845252ac6b662d5c72c29903813eJake Slack try { statement.close(); } 102603928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) { LOG.warn(e); } 102703928aee4356845252ac6b662d5c72c29903813eJake Slack } 102803928aee4356845252ac6b662d5c72c29903813eJake Slack 102903928aee4356845252ac6b662d5c72c29903813eJake Slack if (connection!=null) 103003928aee4356845252ac6b662d5c72c29903813eJake Slack connection.close(); 103103928aee4356845252ac6b662d5c72c29903813eJake Slack } 103203928aee4356845252ac6b662d5c72c29903813eJake Slack } 103303928aee4356845252ac6b662d5c72c29903813eJake Slack 103403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 103503928aee4356845252ac6b662d5c72c29903813eJake Slack * Persist the time the session was last accessed. 103603928aee4356845252ac6b662d5c72c29903813eJake Slack * 103703928aee4356845252ac6b662d5c72c29903813eJake Slack * @param data the session 103803928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 103903928aee4356845252ac6b662d5c72c29903813eJake Slack */ 104003928aee4356845252ac6b662d5c72c29903813eJake Slack private void updateSessionAccessTime (Session data) 104103928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 104203928aee4356845252ac6b662d5c72c29903813eJake Slack { 104303928aee4356845252ac6b662d5c72c29903813eJake Slack Connection connection = getConnection(); 104403928aee4356845252ac6b662d5c72c29903813eJake Slack PreparedStatement statement = null; 104503928aee4356845252ac6b662d5c72c29903813eJake Slack try 104603928aee4356845252ac6b662d5c72c29903813eJake Slack { 104703928aee4356845252ac6b662d5c72c29903813eJake Slack long now = System.currentTimeMillis(); 104803928aee4356845252ac6b662d5c72c29903813eJake Slack connection.setAutoCommit(true); 104903928aee4356845252ac6b662d5c72c29903813eJake Slack statement = connection.prepareStatement(_jdbcSessionIdMgr._updateSessionAccessTime); 105003928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(1, getSessionIdManager().getWorkerName()); 105103928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(2, data.getAccessed()); 105203928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(3, data.getLastAccessedTime()); 105303928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(4, now); 105403928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setLong(5, data.getExpiryTime()); 105503928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(6, data.getRowId()); 105603928aee4356845252ac6b662d5c72c29903813eJake Slack statement.executeUpdate(); 105703928aee4356845252ac6b662d5c72c29903813eJake Slack data.setLastSaved(now); 105803928aee4356845252ac6b662d5c72c29903813eJake Slack statement.close(); 105903928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 106003928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Updated access time session id="+data.getId()); 106103928aee4356845252ac6b662d5c72c29903813eJake Slack } 106203928aee4356845252ac6b662d5c72c29903813eJake Slack finally 106303928aee4356845252ac6b662d5c72c29903813eJake Slack { 106403928aee4356845252ac6b662d5c72c29903813eJake Slack if (statement!=null) 106503928aee4356845252ac6b662d5c72c29903813eJake Slack { 106603928aee4356845252ac6b662d5c72c29903813eJake Slack try { statement.close(); } 106703928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) { LOG.warn(e); } 106803928aee4356845252ac6b662d5c72c29903813eJake Slack } 106903928aee4356845252ac6b662d5c72c29903813eJake Slack 107003928aee4356845252ac6b662d5c72c29903813eJake Slack if (connection!=null) 107103928aee4356845252ac6b662d5c72c29903813eJake Slack connection.close(); 107203928aee4356845252ac6b662d5c72c29903813eJake Slack } 107303928aee4356845252ac6b662d5c72c29903813eJake Slack } 107403928aee4356845252ac6b662d5c72c29903813eJake Slack 107503928aee4356845252ac6b662d5c72c29903813eJake Slack 107603928aee4356845252ac6b662d5c72c29903813eJake Slack 107703928aee4356845252ac6b662d5c72c29903813eJake Slack 107803928aee4356845252ac6b662d5c72c29903813eJake Slack /** 107903928aee4356845252ac6b662d5c72c29903813eJake Slack * Delete a session from the database. Should only be called 108003928aee4356845252ac6b662d5c72c29903813eJake Slack * when the session has been invalidated. 108103928aee4356845252ac6b662d5c72c29903813eJake Slack * 108203928aee4356845252ac6b662d5c72c29903813eJake Slack * @param data 108303928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws Exception 108403928aee4356845252ac6b662d5c72c29903813eJake Slack */ 108503928aee4356845252ac6b662d5c72c29903813eJake Slack protected void deleteSession (Session data) 108603928aee4356845252ac6b662d5c72c29903813eJake Slack throws Exception 108703928aee4356845252ac6b662d5c72c29903813eJake Slack { 108803928aee4356845252ac6b662d5c72c29903813eJake Slack Connection connection = getConnection(); 108903928aee4356845252ac6b662d5c72c29903813eJake Slack PreparedStatement statement = null; 109003928aee4356845252ac6b662d5c72c29903813eJake Slack try 109103928aee4356845252ac6b662d5c72c29903813eJake Slack { 109203928aee4356845252ac6b662d5c72c29903813eJake Slack connection.setAutoCommit(true); 109303928aee4356845252ac6b662d5c72c29903813eJake Slack statement = connection.prepareStatement(_jdbcSessionIdMgr._deleteSession); 109403928aee4356845252ac6b662d5c72c29903813eJake Slack statement.setString(1, data.getRowId()); 109503928aee4356845252ac6b662d5c72c29903813eJake Slack statement.executeUpdate(); 109603928aee4356845252ac6b662d5c72c29903813eJake Slack if (LOG.isDebugEnabled()) 109703928aee4356845252ac6b662d5c72c29903813eJake Slack LOG.debug("Deleted Session "+data); 109803928aee4356845252ac6b662d5c72c29903813eJake Slack } 109903928aee4356845252ac6b662d5c72c29903813eJake Slack finally 110003928aee4356845252ac6b662d5c72c29903813eJake Slack { 110103928aee4356845252ac6b662d5c72c29903813eJake Slack if (statement!=null) 110203928aee4356845252ac6b662d5c72c29903813eJake Slack { 110303928aee4356845252ac6b662d5c72c29903813eJake Slack try { statement.close(); } 110403928aee4356845252ac6b662d5c72c29903813eJake Slack catch(Exception e) { LOG.warn(e); } 110503928aee4356845252ac6b662d5c72c29903813eJake Slack } 110603928aee4356845252ac6b662d5c72c29903813eJake Slack 110703928aee4356845252ac6b662d5c72c29903813eJake Slack if (connection!=null) 110803928aee4356845252ac6b662d5c72c29903813eJake Slack connection.close(); 110903928aee4356845252ac6b662d5c72c29903813eJake Slack } 111003928aee4356845252ac6b662d5c72c29903813eJake Slack } 111103928aee4356845252ac6b662d5c72c29903813eJake Slack 111203928aee4356845252ac6b662d5c72c29903813eJake Slack 111303928aee4356845252ac6b662d5c72c29903813eJake Slack 111403928aee4356845252ac6b662d5c72c29903813eJake Slack /** 111503928aee4356845252ac6b662d5c72c29903813eJake Slack * Get a connection from the driver. 111603928aee4356845252ac6b662d5c72c29903813eJake Slack * @return 111703928aee4356845252ac6b662d5c72c29903813eJake Slack * @throws SQLException 111803928aee4356845252ac6b662d5c72c29903813eJake Slack */ 111903928aee4356845252ac6b662d5c72c29903813eJake Slack private Connection getConnection () 112003928aee4356845252ac6b662d5c72c29903813eJake Slack throws SQLException 112103928aee4356845252ac6b662d5c72c29903813eJake Slack { 112203928aee4356845252ac6b662d5c72c29903813eJake Slack return ((JDBCSessionIdManager)getSessionIdManager()).getConnection(); 112303928aee4356845252ac6b662d5c72c29903813eJake Slack } 112403928aee4356845252ac6b662d5c72c29903813eJake Slack 112503928aee4356845252ac6b662d5c72c29903813eJake Slack /** 112603928aee4356845252ac6b662d5c72c29903813eJake Slack * Calculate a unique id for this session across the cluster. 112703928aee4356845252ac6b662d5c72c29903813eJake Slack * 112803928aee4356845252ac6b662d5c72c29903813eJake Slack * Unique id is composed of: contextpath_virtualhost0_sessionid 112903928aee4356845252ac6b662d5c72c29903813eJake Slack * @param data 113003928aee4356845252ac6b662d5c72c29903813eJake Slack * @return 113103928aee4356845252ac6b662d5c72c29903813eJake Slack */ 113203928aee4356845252ac6b662d5c72c29903813eJake Slack private String calculateRowId (Session data) 113303928aee4356845252ac6b662d5c72c29903813eJake Slack { 113403928aee4356845252ac6b662d5c72c29903813eJake Slack String rowId = canonicalize(_context.getContextPath()); 113503928aee4356845252ac6b662d5c72c29903813eJake Slack rowId = rowId + "_" + getVirtualHost(_context); 113603928aee4356845252ac6b662d5c72c29903813eJake Slack rowId = rowId+"_"+data.getId(); 113703928aee4356845252ac6b662d5c72c29903813eJake Slack return rowId; 113803928aee4356845252ac6b662d5c72c29903813eJake Slack } 113903928aee4356845252ac6b662d5c72c29903813eJake Slack 114003928aee4356845252ac6b662d5c72c29903813eJake Slack /** 114103928aee4356845252ac6b662d5c72c29903813eJake Slack * Get the first virtual host for the context. 114203928aee4356845252ac6b662d5c72c29903813eJake Slack * 114303928aee4356845252ac6b662d5c72c29903813eJake Slack * Used to help identify the exact session/contextPath. 114403928aee4356845252ac6b662d5c72c29903813eJake Slack * 114503928aee4356845252ac6b662d5c72c29903813eJake Slack * @return 0.0.0.0 if no virtual host is defined 114603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 114703928aee4356845252ac6b662d5c72c29903813eJake Slack private static String getVirtualHost (ContextHandler.Context context) 114803928aee4356845252ac6b662d5c72c29903813eJake Slack { 114903928aee4356845252ac6b662d5c72c29903813eJake Slack String vhost = "0.0.0.0"; 115003928aee4356845252ac6b662d5c72c29903813eJake Slack 115103928aee4356845252ac6b662d5c72c29903813eJake Slack if (context==null) 115203928aee4356845252ac6b662d5c72c29903813eJake Slack return vhost; 115303928aee4356845252ac6b662d5c72c29903813eJake Slack 115403928aee4356845252ac6b662d5c72c29903813eJake Slack String [] vhosts = context.getContextHandler().getVirtualHosts(); 115503928aee4356845252ac6b662d5c72c29903813eJake Slack if (vhosts==null || vhosts.length==0 || vhosts[0]==null) 115603928aee4356845252ac6b662d5c72c29903813eJake Slack return vhost; 115703928aee4356845252ac6b662d5c72c29903813eJake Slack 115803928aee4356845252ac6b662d5c72c29903813eJake Slack return vhosts[0]; 115903928aee4356845252ac6b662d5c72c29903813eJake Slack } 116003928aee4356845252ac6b662d5c72c29903813eJake Slack 116103928aee4356845252ac6b662d5c72c29903813eJake Slack /** 116203928aee4356845252ac6b662d5c72c29903813eJake Slack * Make an acceptable file name from a context path. 116303928aee4356845252ac6b662d5c72c29903813eJake Slack * 116403928aee4356845252ac6b662d5c72c29903813eJake Slack * @param path 116503928aee4356845252ac6b662d5c72c29903813eJake Slack * @return 116603928aee4356845252ac6b662d5c72c29903813eJake Slack */ 116703928aee4356845252ac6b662d5c72c29903813eJake Slack private static String canonicalize (String path) 116803928aee4356845252ac6b662d5c72c29903813eJake Slack { 116903928aee4356845252ac6b662d5c72c29903813eJake Slack if (path==null) 117003928aee4356845252ac6b662d5c72c29903813eJake Slack return ""; 117103928aee4356845252ac6b662d5c72c29903813eJake Slack 117203928aee4356845252ac6b662d5c72c29903813eJake Slack return path.replace('/', '_').replace('.','_').replace('\\','_'); 117303928aee4356845252ac6b662d5c72c29903813eJake Slack } 117403928aee4356845252ac6b662d5c72c29903813eJake Slack} 1175