Make jdbc session tests work
This commit is contained in:
parent
84239bc7f2
commit
b0748c5865
|
@ -33,8 +33,8 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
|
||||
public abstract class AbstractSessionIdManager extends AbstractLifeCycle implements SessionIdManager
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(AbstractSessionIdManager.class);
|
||||
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
private final static String __NEW_SESSION_ID="org.eclipse.jetty.server.newSessionId";
|
||||
|
||||
protected Random _random;
|
||||
|
@ -243,7 +243,6 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
|||
}
|
||||
|
||||
_scavenger.start();
|
||||
System.err.println("Started scavenger "+_scavenger);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -345,6 +344,7 @@ public abstract class AbstractSessionIdManager extends AbstractLifeCycle impleme
|
|||
{
|
||||
//take the id out of the list of known sessionids for this node
|
||||
removeId(id);
|
||||
|
||||
//tell all contexts that may have a session object with this id to
|
||||
//get rid of them
|
||||
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
|
||||
|
|
|
@ -20,10 +20,14 @@
|
|||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
||||
|
||||
/**
|
||||
* AbstractSessionStore
|
||||
|
@ -32,26 +36,75 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
|||
*/
|
||||
public abstract class AbstractSessionStore extends AbstractLifeCycle implements SessionStore
|
||||
{
|
||||
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
protected SessionDataStore _sessionDataStore;
|
||||
protected StalenessStrategy _staleStrategy;
|
||||
protected SessionManager _manager;
|
||||
|
||||
protected final CounterStatistic _sessionStats = new CounterStatistic();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Create a new Session object from session data
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public abstract Session newSession (SessionData data);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get the session matching the key
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public abstract Session doGet(SessionKey key);
|
||||
|
||||
public abstract void doPut (SessionKey key, Session session);
|
||||
|
||||
|
||||
/**
|
||||
* Put the session into the map if it wasn't already there
|
||||
*
|
||||
* @param key the identity of the session
|
||||
* @param session the session object
|
||||
* @return null if the session wasn't already in the map, or the existing entry otherwise
|
||||
*/
|
||||
public abstract Session doPutIfAbsent (SessionKey key, Session session);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Check to see if the session exists in the store
|
||||
* @param key
|
||||
* @return
|
||||
*/
|
||||
public abstract boolean doExists (SessionKey key);
|
||||
|
||||
public abstract void doDelete (SessionKey key);
|
||||
|
||||
|
||||
/**
|
||||
* Remove the session with this identity from the store
|
||||
* @param key
|
||||
* @return the removed Session or null if no such key
|
||||
*/
|
||||
public abstract Session doDelete (SessionKey key);
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Get a list of keys for sessions that the store thinks has expired
|
||||
* @return
|
||||
*/
|
||||
public abstract Set<SessionKey> doGetExpiredCandidates();
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public AbstractSessionStore ()
|
||||
{
|
||||
}
|
||||
|
@ -126,11 +179,21 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
* @see org.eclipse.jetty.server.session.SessionStore#get(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session get(SessionKey key) throws Exception
|
||||
public Session get(SessionKey key, boolean staleCheck) throws Exception
|
||||
{
|
||||
//look locally
|
||||
Session session = doGet(key);
|
||||
|
||||
|
||||
if (staleCheck && isStale(session))
|
||||
{
|
||||
//delete from memory so should reload
|
||||
doDelete(key);
|
||||
session = null;
|
||||
_sessionStats.decrement();
|
||||
}
|
||||
|
||||
|
||||
//not in session store, load the data for the session if possible
|
||||
if (session == null && _sessionDataStore != null)
|
||||
{
|
||||
|
@ -139,7 +202,15 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
{
|
||||
session = newSession(data);
|
||||
session.setSessionManager(_manager);
|
||||
doPut(key, session);
|
||||
Session existing = doPutIfAbsent(key, session);
|
||||
if (existing != null)
|
||||
{
|
||||
//some other thread has got in first and added the session
|
||||
//so use it
|
||||
session = existing;
|
||||
}
|
||||
else
|
||||
_sessionStats.increment();
|
||||
}
|
||||
}
|
||||
return session;
|
||||
|
@ -159,9 +230,20 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
throw new IllegalArgumentException ("Put key="+key+" session="+(session==null?"null":session.getId()));
|
||||
|
||||
session.setSessionManager(_manager);
|
||||
|
||||
//if the session is already in our cache, then we want to write through any changes
|
||||
if (doExists(key))
|
||||
|
||||
Session existing = doPutIfAbsent(key,session);
|
||||
if (existing == null)
|
||||
{
|
||||
//session not already in cache write through
|
||||
if (_sessionDataStore != null)
|
||||
{
|
||||
session.willPassivate();
|
||||
_sessionDataStore.store(SessionKey.getKey(session.getSessionData()), session.getSessionData());
|
||||
session.didActivate();
|
||||
}
|
||||
_sessionStats.increment();
|
||||
}
|
||||
else
|
||||
{
|
||||
//if the session data has changed, or the cache is considered stale, write it to any backing store
|
||||
if ((session.getSessionData().isDirty() || isStale(session)) && _sessionDataStore != null)
|
||||
|
@ -171,18 +253,6 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
session.didActivate();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//session not already in cache, add it and write through
|
||||
if (_sessionDataStore != null)
|
||||
{
|
||||
session.willPassivate();
|
||||
_sessionDataStore.store(SessionKey.getKey(session.getSessionData()), session.getSessionData());
|
||||
session.didActivate();
|
||||
}
|
||||
doPut(key,session);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -207,11 +277,17 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
@Override
|
||||
public boolean delete(SessionKey key) throws Exception
|
||||
{
|
||||
boolean deleted = true;
|
||||
if (_sessionDataStore != null)
|
||||
deleted = _sessionDataStore.delete(key);
|
||||
doDelete(key);
|
||||
return deleted;
|
||||
{
|
||||
boolean dsdel = _sessionDataStore.delete(key);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in db {}",key, dsdel);
|
||||
}
|
||||
if (doDelete(key) != null)
|
||||
{
|
||||
_sessionStats.decrement();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isStale (Session session)
|
||||
|
@ -235,4 +311,46 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
return _sessionDataStore.getExpired(candidates);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public Session newSession(HttpServletRequest request, SessionKey key, long time, long maxInactiveMs)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getSessions()
|
||||
{
|
||||
return (int)_sessionStats.getCurrent();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getSessionsMax()
|
||||
{
|
||||
return (int)_sessionStats.getMax();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public int getSessionsTotal()
|
||||
{
|
||||
return (int)_sessionStats.getTotal();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void resetStats()
|
||||
{
|
||||
_sessionStats.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
/**
|
||||
* FileSessionDataStore
|
||||
*
|
||||
*
|
||||
* A file-based store of session data.
|
||||
*/
|
||||
public class FileSessionDataStore extends AbstractSessionDataStore
|
||||
{
|
||||
|
|
|
@ -50,7 +50,6 @@ public class HashSessionIdManager extends AbstractSessionIdManager
|
|||
public String newSessionId(long seedTerm)
|
||||
{
|
||||
String id = super.newSessionId(seedTerm);
|
||||
useId(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -25,12 +25,15 @@ import java.io.InputStream;
|
|||
import java.io.ObjectOutputStream;
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.ParameterMetaData;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
@ -43,14 +46,13 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
/**
|
||||
* JDBCSessionDataStore
|
||||
*
|
||||
*
|
||||
* Session data stored in database
|
||||
*/
|
||||
public class JDBCSessionDataStore extends AbstractSessionDataStore
|
||||
{
|
||||
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
protected boolean _initialized = false;
|
||||
protected long _lastScavengeTime = 0;
|
||||
protected Map<SessionKey, AtomicInteger> _unloadables = new ConcurrentHashMap<>();
|
||||
|
||||
private DatabaseAdaptor _dbAdaptor;
|
||||
|
@ -58,6 +60,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
private int _attempts = -1; // <= 0 means unlimited attempts to load a session
|
||||
private boolean _deleteUnloadables = false; //true means if attempts exhausted delete the session
|
||||
private long _gracePeriodMs = 1000L * 60 * 60; //default grace period is 1hr
|
||||
|
||||
/**
|
||||
* SessionTableSchema
|
||||
|
@ -69,7 +72,6 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
protected DatabaseAdaptor _dbAdaptor;
|
||||
protected String _tableName = "JettySessions";
|
||||
protected String _rowIdColumn = "rowId";
|
||||
protected String _idColumn = "sessionId";
|
||||
protected String _contextPathColumn = "contextPath";
|
||||
protected String _virtualHostColumn = "virtualHost";
|
||||
|
@ -100,23 +102,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
checkNotNull(tableName);
|
||||
_tableName = tableName;
|
||||
}
|
||||
public String getRowIdColumn()
|
||||
{
|
||||
if ("rowId".equals(_rowIdColumn) && _dbAdaptor.isRowIdReserved())
|
||||
_rowIdColumn = "srowId";
|
||||
return _rowIdColumn;
|
||||
}
|
||||
public void setRowIdColumn(String rowIdColumn)
|
||||
{
|
||||
checkNotNull(rowIdColumn);
|
||||
if (_dbAdaptor == null)
|
||||
throw new IllegalStateException ("DbAdaptor is null");
|
||||
|
||||
if (_dbAdaptor.isRowIdReserved() && "rowId".equals(rowIdColumn))
|
||||
throw new IllegalArgumentException("rowId is reserved word for Oracle");
|
||||
|
||||
_rowIdColumn = rowIdColumn;
|
||||
}
|
||||
|
||||
public String getIdColumn()
|
||||
{
|
||||
return _idColumn;
|
||||
|
@ -234,11 +220,11 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
String blobType = _dbAdaptor.getBlobType();
|
||||
String longType = _dbAdaptor.getLongType();
|
||||
|
||||
return "create table "+_tableName+" ("+getRowIdColumn()+" varchar(120), "+_idColumn+" varchar(120), "+
|
||||
return "create table "+_tableName+" ("+_idColumn+" varchar(120), "+
|
||||
_contextPathColumn+" varchar(60), "+_virtualHostColumn+" varchar(60), "+_lastNodeColumn+" varchar(60), "+_accessTimeColumn+" "+longType+", "+
|
||||
_lastAccessTimeColumn+" "+longType+", "+_createTimeColumn+" "+longType+", "+_cookieTimeColumn+" "+longType+", "+
|
||||
_lastSavedTimeColumn+" "+longType+", "+_expiryTimeColumn+" "+longType+", "+_maxIntervalColumn+" "+longType+", "+
|
||||
_mapColumn+" "+blobType+", primary key("+getRowIdColumn()+"))";
|
||||
_mapColumn+" "+blobType+", primary key("+_idColumn+", "+_contextPathColumn+","+_virtualHostColumn+"))";
|
||||
}
|
||||
|
||||
public String getCreateIndexOverExpiryStatementAsString (String indexName)
|
||||
|
@ -277,44 +263,124 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)";
|
||||
}
|
||||
|
||||
public String getUpdateSessionStatementAsString(SessionKey key)
|
||||
public PreparedStatement getUpdateSessionStatement(Connection connection, String canonicalContextPath)
|
||||
throws SQLException
|
||||
{
|
||||
String s = "update "+getTableName()+
|
||||
" set "+getIdColumn()+" = ?, "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
|
||||
" set "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
|
||||
getLastAccessTimeColumn()+" = ?, "+getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+
|
||||
getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where ";
|
||||
|
||||
if (key.getCanonicalContextPath() == null || "".equals(key.getCanonicalContextPath()))
|
||||
if (canonicalContextPath == null || "".equals(canonicalContextPath))
|
||||
{
|
||||
if (_dbAdaptor.isEmptyStringNull())
|
||||
{
|
||||
return s+getIdColumn()+" = ? and "+
|
||||
s = s+getIdColumn()+" = ? and "+
|
||||
getContextPathColumn()+" is null and "+
|
||||
getVirtualHostColumn()+" = ?";
|
||||
|
||||
return connection.prepareStatement(s);
|
||||
}
|
||||
}
|
||||
|
||||
return s+getIdColumn()+" = ? and "+getContextPathColumn()+
|
||||
" = ? and "+getVirtualHostColumn()+" = ?";
|
||||
return connection.prepareStatement(s+getIdColumn()+" = ? and "+getContextPathColumn()+
|
||||
" = ? and "+getVirtualHostColumn()+" = ?");
|
||||
}
|
||||
|
||||
|
||||
public String getBoundedExpiredSessionsStatementAsString()
|
||||
|
||||
public PreparedStatement getMyExpiredSessionsStatement (Connection connection, String canonicalContextPath, String vhost, long expiry)
|
||||
throws SQLException
|
||||
{
|
||||
return "select "+getIdColumn()+" from "+getTableName()+" where "+getContextPathColumn()+" = ? and "+getVirtualHostColumn()+" = ? and "+getExpiryTimeColumn()+" >= ? and "+getExpiryTimeColumn()+" <= ?";
|
||||
if (_dbAdaptor == null)
|
||||
throw new IllegalStateException("No DB adaptor");
|
||||
|
||||
|
||||
if (canonicalContextPath == null || "".equals(canonicalContextPath))
|
||||
{
|
||||
if (_dbAdaptor.isEmptyStringNull())
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
|
||||
" from "+getTableName()+" where "+
|
||||
getContextPathColumn()+" is null and "+
|
||||
getVirtualHostColumn()+" = ? and "+getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
|
||||
statement.setString(1, vhost);
|
||||
statement.setLong(2, expiry);
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
|
||||
PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+", "+getExpiryTimeColumn()+
|
||||
" from "+getTableName()+" where "+getContextPathColumn()+" = ? and "+
|
||||
getVirtualHostColumn()+" = ? and "+
|
||||
getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
|
||||
|
||||
statement.setString(1, canonicalContextPath);
|
||||
statement.setString(2, vhost);
|
||||
statement.setLong(3, expiry);
|
||||
return statement;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public String getMyExpiredSessionsStatementAsString()
|
||||
public PreparedStatement getAllAncientExpiredSessionsStatement (Connection connection)
|
||||
throws SQLException
|
||||
{
|
||||
return "select "+getIdColumn()+" from "+getTableName()+" where "+getLastNodeColumn()+" = ? and "+getContextPathColumn()+" = and "+getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?";
|
||||
}
|
||||
|
||||
public String getAllAncientExpiredSessionsAsString()
|
||||
{
|
||||
return "select "+getIdColumn()+", "+getContextPathColumn()+", "+getVirtualHostColumn()+" from "+getTableName()+" where "+getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?";
|
||||
if (_dbAdaptor == null)
|
||||
throw new IllegalStateException("No DB adaptor");
|
||||
|
||||
PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getContextPathColumn()+", "+getVirtualHostColumn()+
|
||||
" from "+getTableName()+
|
||||
" where "+getExpiryTimeColumn()+" >0 and "+getExpiryTimeColumn()+" <= ?");
|
||||
return statement;
|
||||
}
|
||||
|
||||
|
||||
public PreparedStatement getCheckSessionExistsStatement (Connection connection, String canonicalContextPath)
|
||||
throws SQLException
|
||||
{
|
||||
if (_dbAdaptor == null)
|
||||
throw new IllegalStateException("No DB adaptor");
|
||||
|
||||
|
||||
if (canonicalContextPath == null || "".equals(canonicalContextPath))
|
||||
{
|
||||
if (_dbAdaptor.isEmptyStringNull())
|
||||
{
|
||||
PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
|
||||
" from "+getTableName()+
|
||||
" where "+getIdColumn()+" = ? and "+
|
||||
getContextPathColumn()+" is null and "+
|
||||
getVirtualHostColumn()+" = ?");
|
||||
return statement;
|
||||
}
|
||||
}
|
||||
|
||||
PreparedStatement statement = connection.prepareStatement("select "+getIdColumn()+", "+getExpiryTimeColumn()+
|
||||
" from "+getTableName()+
|
||||
" where "+getIdColumn()+" = ? and "+
|
||||
getContextPathColumn()+" = ? and "+
|
||||
getVirtualHostColumn()+" = ?");
|
||||
return statement;
|
||||
}
|
||||
|
||||
public void fillCheckSessionExistsStatement (PreparedStatement statement, SessionKey key)
|
||||
throws SQLException
|
||||
{
|
||||
statement.clearParameters();
|
||||
ParameterMetaData metaData = statement.getParameterMetaData();
|
||||
if (metaData.getParameterCount() < 3)
|
||||
{
|
||||
statement.setString(1, key.getId());
|
||||
statement.setString(2, key.getVhost());
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setString(1, key.getId());
|
||||
statement.setString(2, key.getCanonicalContextPath());
|
||||
statement.setString(3, key.getVhost());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public PreparedStatement getLoadStatement (Connection connection, SessionKey key)
|
||||
throws SQLException
|
||||
{
|
||||
|
@ -356,7 +422,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
throw new IllegalStateException("No DB adaptor");
|
||||
|
||||
String s = "update "+getTableName()+
|
||||
" set "+getIdColumn()+" = ?, "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
|
||||
" set "+getLastNodeColumn()+" = ?, "+getAccessTimeColumn()+" = ?, "+
|
||||
getLastAccessTimeColumn()+" = ?, "+getLastSavedTimeColumn()+" = ?, "+getExpiryTimeColumn()+" = ?, "+
|
||||
getMaxIntervalColumn()+" = ?, "+getMapColumn()+" = ? where ";
|
||||
|
||||
|
@ -581,6 +647,9 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
@Override
|
||||
public SessionData load(SessionKey key) throws Exception
|
||||
{
|
||||
if (getLoadAttempts() > 0 && loadAttemptsExhausted(key))
|
||||
throw new UnreadableSessionDataException(key, true);
|
||||
|
||||
try (Connection connection = _dbAdaptor.getConnection();
|
||||
PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, key);
|
||||
ResultSet result = statement.executeQuery())
|
||||
|
@ -614,7 +683,10 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
throw new UnreadableSessionDataException (key, e);
|
||||
}
|
||||
|
||||
|
||||
//if the session successfully loaded, remove failed attempts
|
||||
_unloadables.remove(key);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("LOADED session {}", data);
|
||||
}
|
||||
|
@ -625,7 +697,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
catch (UnreadableSessionDataException e)
|
||||
{
|
||||
if (getLoadAttempts() > 0 && loadAttemptsExhausted(key))
|
||||
if (getLoadAttempts() > 0 && loadAttemptsExhausted(key) && isDeleteUnloadableSessions())
|
||||
{
|
||||
try
|
||||
{
|
||||
|
@ -657,6 +729,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
int rows = statement.executeUpdate();
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Deleted Session {}:{}",key,(rows>0));
|
||||
|
||||
return rows > 0;
|
||||
}
|
||||
}
|
||||
|
@ -733,11 +806,9 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
private void doUpdate (Connection connection, SessionKey key, SessionData data)
|
||||
throws Exception
|
||||
{
|
||||
try (PreparedStatement statement = connection.prepareStatement(_sessionTableSchema.getUpdateSessionStatementAsString(key)))
|
||||
try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, key.getCanonicalContextPath()))
|
||||
{
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
|
||||
statement.setString(1, data.getLastNode());//should be my node id
|
||||
statement.setLong(2, data.getAccessed());//accessTime
|
||||
|
@ -745,7 +816,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
statement.setLong(4, now); //last saved time
|
||||
statement.setLong(5, data.getExpiry());
|
||||
statement.setLong(6, data.getMaxInactiveMs());
|
||||
|
||||
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||
oos.writeObject(data.getAllAttributes());
|
||||
|
@ -782,21 +853,10 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
public Set<SessionKey> getExpired(Set<SessionKey> candidates)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Scavenge sweep started at "+System.currentTimeMillis());
|
||||
LOG.debug("Getting expired sessions "+System.currentTimeMillis());
|
||||
|
||||
long now = System.currentTimeMillis();
|
||||
|
||||
//first time we're called, don't scavenge
|
||||
if (_lastScavengeTime == 0)
|
||||
{
|
||||
_lastScavengeTime = now;
|
||||
return Collections.emptySet();
|
||||
}
|
||||
|
||||
//we actually ignore the list of candidates as the database has the definitive list of sessions
|
||||
|
||||
long interval = now - _lastScavengeTime;
|
||||
|
||||
String cpath = SessionKey.getContextPath(_context);
|
||||
String vhost = SessionKey.getVirtualHost(_context);
|
||||
|
||||
|
@ -808,21 +868,18 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
/*
|
||||
* 1. Select sessions for our node and context that have expired since a grace interval
|
||||
*/
|
||||
long upperBound = _lastScavengeTime; //grace interval is 1 scavenge interval
|
||||
long upperBound = now;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug ("{}- Pass 1: Searching for sessions for node {} and context {} expired before {}", _node, _node, cpath, upperBound);
|
||||
|
||||
|
||||
try (PreparedStatement statement = connection.prepareStatement(_sessionTableSchema.getMyExpiredSessionsStatementAsString()))
|
||||
try (PreparedStatement statement = _sessionTableSchema.getMyExpiredSessionsStatement(connection, cpath, vhost, upperBound))
|
||||
{
|
||||
statement.setString(1, cpath);
|
||||
statement.setString(2, vhost);
|
||||
statement.setLong(3, upperBound);
|
||||
try (ResultSet result = statement.executeQuery())
|
||||
{
|
||||
while (result.next())
|
||||
{
|
||||
String sessionId = result.getString(_sessionTableSchema.getIdColumn());
|
||||
long exp = result.getLong(_sessionTableSchema.getExpiryTimeColumn());
|
||||
expiredSessionKeys.add(SessionKey.getKey(sessionId, cpath, vhost));
|
||||
if (LOG.isDebugEnabled()) LOG.debug (cpath+"- Found expired sessionId="+sessionId);
|
||||
}
|
||||
|
@ -830,15 +887,15 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
/*
|
||||
* 2. Select sessions for any node or context that have expired a long time ago (ie at least 3 intervals ago)
|
||||
* 2. Select sessions for any node or context that have expired a long time ago (ie at least 3 grace periods ago)
|
||||
*/
|
||||
try (PreparedStatement selectExpiredSessions = connection.prepareStatement(_sessionTableSchema.getAllAncientExpiredSessionsAsString()))
|
||||
try (PreparedStatement selectExpiredSessions = _sessionTableSchema.getAllAncientExpiredSessionsStatement(connection))
|
||||
{
|
||||
|
||||
upperBound = _lastScavengeTime - (3 * interval);
|
||||
upperBound = now - (3 * _gracePeriodMs);
|
||||
if (upperBound > 0)
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("{}- Pass 2: Searching for sessions expired before {}",_node, upperBound);
|
||||
|
||||
selectExpiredSessions.setLong(1, upperBound);
|
||||
try (ResultSet result = selectExpiredSessions.executeQuery())
|
||||
{
|
||||
|
@ -853,6 +910,44 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Set<SessionKey> notExpiredInDB = new HashSet<SessionKey>();
|
||||
for (SessionKey k: candidates)
|
||||
{
|
||||
//there are some keys that the session store thought had expired, but were not
|
||||
//found in our sweep either because it is no longer in the db, or its
|
||||
//expiry time was updated
|
||||
if (!expiredSessionKeys.contains(k))
|
||||
notExpiredInDB.add(k);
|
||||
}
|
||||
|
||||
|
||||
if (!notExpiredInDB.isEmpty())
|
||||
{
|
||||
//we have some sessions to check
|
||||
try (PreparedStatement checkSessionExists = _sessionTableSchema.getCheckSessionExistsStatement(connection, cpath))
|
||||
{
|
||||
for (SessionKey k: notExpiredInDB)
|
||||
{
|
||||
_sessionTableSchema.fillCheckSessionExistsStatement (checkSessionExists, k);
|
||||
try (ResultSet result = checkSessionExists.executeQuery())
|
||||
{
|
||||
if (!result.next())
|
||||
{
|
||||
//session doesn't exist any more, can be expired
|
||||
expiredSessionKeys.add(k);
|
||||
}
|
||||
//else its expiry time has not been reached
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Problem checking if potentially expired session {} exists in db", k,e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return expiredSessionKeys;
|
||||
}
|
||||
|
@ -861,13 +956,20 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
LOG.warn(e);
|
||||
return expiredSessionKeys; //return whatever we got
|
||||
}
|
||||
finally
|
||||
{
|
||||
_lastScavengeTime = now;
|
||||
}
|
||||
|
||||
}
|
||||
public int getGracePeriodSec ()
|
||||
{
|
||||
return (int)(_gracePeriodMs == 0L? 0 : _gracePeriodMs/1000L);
|
||||
}
|
||||
|
||||
|
||||
public void setGracePeriodSec (int sec)
|
||||
{
|
||||
if (sec < 0)
|
||||
_gracePeriodMs = 0;
|
||||
else
|
||||
_gracePeriodMs = sec * 1000L;
|
||||
}
|
||||
|
||||
public void setDatabaseAdaptor (DatabaseAdaptor dbAdaptor)
|
||||
{
|
||||
|
@ -906,6 +1008,12 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
_deleteUnloadables = delete;
|
||||
}
|
||||
|
||||
public boolean isDeleteUnloadableSessions ()
|
||||
{
|
||||
return _deleteUnloadables;
|
||||
}
|
||||
|
||||
|
||||
protected void incLoadAttempt (SessionKey key)
|
||||
{
|
||||
AtomicInteger i = new AtomicInteger(0);
|
||||
|
@ -920,6 +1028,25 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
if (isStarted())
|
||||
throw new IllegalStateException("Already started");
|
||||
}
|
||||
|
||||
|
||||
public int getLoadAttempts (SessionKey key)
|
||||
{
|
||||
AtomicInteger i = _unloadables.get(key);
|
||||
if (i == null)
|
||||
return 0;
|
||||
return i.get();
|
||||
}
|
||||
|
||||
public Set<SessionKey> getUnloadableSessions ()
|
||||
{
|
||||
return new HashSet<SessionKey>(_unloadables.keySet());
|
||||
}
|
||||
|
||||
public void clearUnloadableSessions()
|
||||
{
|
||||
_unloadables.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -179,7 +179,6 @@ public class JDBCSessionIdManager extends org.eclipse.jetty.server.session.Abstr
|
|||
public String newSessionId(long seedTerm)
|
||||
{
|
||||
String id = super.newSessionId(seedTerm);
|
||||
useId(id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
|
@ -22,19 +22,22 @@ package org.eclipse.jetty.server.session;
|
|||
/**
|
||||
* JDBCSessionManager
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class JDBCSessionManager extends SessionManager
|
||||
{
|
||||
|
||||
|
||||
protected DatabaseAdaptor _db = new DatabaseAdaptor();
|
||||
protected JDBCSessionDataStore _sessionDataStore = new JDBCSessionDataStore();
|
||||
|
||||
|
||||
public JDBCSessionManager()
|
||||
{
|
||||
_sessionStore = new MemorySessionStore();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doStart() throws Exception
|
||||
{
|
||||
_sessionStore = new MemorySessionStore();
|
||||
_sessionDataStore.setDatabaseAdaptor(_db);
|
||||
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
|
||||
|
||||
|
|
|
@ -31,15 +31,22 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
/**
|
||||
* MemorySessionStore
|
||||
*
|
||||
*
|
||||
* A session store that keeps its sessions in memory in a hashmap
|
||||
*/
|
||||
public class MemorySessionStore extends AbstractSessionStore
|
||||
{
|
||||
private static final Logger LOG = Log.getLogger(MemorySessionStore.class);
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
||||
protected ConcurrentHashMap<String, Session> _sessions = new ConcurrentHashMap<String, Session>();
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* MemorySession
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class MemorySession extends Session
|
||||
{
|
||||
|
||||
|
@ -64,9 +71,6 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
{
|
||||
super(data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -88,25 +92,18 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
public Session doGet(SessionKey key)
|
||||
{
|
||||
Session session = _sessions.get(key.getId());
|
||||
|
||||
if (isStale(session))
|
||||
{
|
||||
//delete from memory so should reload
|
||||
doDelete(key);
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPut(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session)
|
||||
*/
|
||||
@Override
|
||||
public void doPut(SessionKey key, Session session)
|
||||
public Session doPutIfAbsent(SessionKey key, Session session)
|
||||
{
|
||||
_sessions.put(key.getId(), session);
|
||||
return _sessions.putIfAbsent(key.getId(), session);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -122,9 +119,9 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public void doDelete(SessionKey key)
|
||||
public Session doDelete(SessionKey key)
|
||||
{
|
||||
_sessions.remove(key.getId());
|
||||
return _sessions.remove(key.getId());
|
||||
}
|
||||
|
||||
|
||||
|
@ -139,7 +136,9 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
for (Session s:_sessions.values())
|
||||
{
|
||||
if (s.isExpiredAt(now))
|
||||
{
|
||||
candidates.add(SessionKey.getKey(s.getId(), s.getContextPath(), s.getVHost()));
|
||||
}
|
||||
}
|
||||
return candidates;
|
||||
}
|
||||
|
@ -197,10 +196,10 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
* @see org.eclipse.jetty.server.session.SessionStore#newSession(java.lang.String)
|
||||
*/
|
||||
@Override
|
||||
public Session newSession(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
public Session newSession(HttpServletRequest request, SessionKey key, long time, long maxInactiveMs)
|
||||
{
|
||||
//TODO - how to tell that the session is new?!
|
||||
return new MemorySession(_sessionDataStore.newSessionData(key, created, accessed, lastAccessed, maxInactiveMs));
|
||||
MemorySession s = new MemorySession(request, _sessionDataStore.newSessionData(key, time, time, time, maxInactiveMs));
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
@ -212,7 +211,8 @@ public class MemorySessionStore extends AbstractSessionStore
|
|||
@Override
|
||||
public Session newSession(SessionData data)
|
||||
{
|
||||
return new MemorySession (data);
|
||||
MemorySession s = new MemorySession (data);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,8 @@ package org.eclipse.jetty.server.session;
|
|||
/**
|
||||
* NeverStale
|
||||
*
|
||||
*
|
||||
* This strategy says that a session never needs to be refreshed by the cluster.
|
||||
*
|
||||
*/
|
||||
public class NeverStaleStrategy implements StalenessStrategy
|
||||
{
|
||||
|
|
|
@ -32,7 +32,6 @@ import javax.servlet.http.HttpSessionBindingListener;
|
|||
import javax.servlet.http.HttpSessionContext;
|
||||
import javax.servlet.http.HttpSessionEvent;
|
||||
|
||||
import org.eclipse.jetty.server.session.SessionManager.SessionIf;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
|
||||
|
@ -46,8 +45,9 @@ import org.eclipse.jetty.util.log.Logger;
|
|||
*/
|
||||
public class Session implements SessionManager.SessionIf
|
||||
{
|
||||
|
||||
final static Logger LOG = Log.getLogger(Session.class); // TODO SessionHandler.LOG;
|
||||
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
|
||||
|
||||
|
||||
public final static String SESSION_CREATED_SECURE="org.eclipse.jetty.security.sessionCreatedSecure";
|
||||
|
||||
protected SessionData _sessionData;
|
||||
|
@ -138,21 +138,7 @@ public class Session implements SessionManager.SessionIf
|
|||
throw new IllegalStateException ("No session manager for session "+ _sessionData.getId());
|
||||
|
||||
_manager.removeSession(this,true);
|
||||
|
||||
// Notify listeners and unbind values
|
||||
boolean do_invalidate=false;
|
||||
synchronized (this)
|
||||
{
|
||||
if (!_sessionData.isInvalid())
|
||||
{
|
||||
if (_requests<=0)
|
||||
do_invalidate=true;
|
||||
else
|
||||
_doInvalidate=true;
|
||||
}
|
||||
}
|
||||
if (do_invalidate)
|
||||
doInvalidate();
|
||||
doInvalidate();
|
||||
}
|
||||
|
||||
|
||||
|
@ -366,7 +352,9 @@ public class Session implements SessionManager.SessionIf
|
|||
@Override
|
||||
public void setMaxInactiveInterval(int secs)
|
||||
{
|
||||
_sessionData.setMaxInactiveMs((long)secs*1000L);
|
||||
_sessionData.setMaxInactiveMs((long)secs*1000L);
|
||||
_sessionData.setExpiry(_sessionData.getMaxInactiveMs() <= 0 ? 0 : (System.currentTimeMillis() + _sessionData.getMaxInactiveMs()*1000L));
|
||||
_sessionData.setDirty(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -571,13 +559,6 @@ public class Session implements SessionManager.SessionIf
|
|||
checkValid();
|
||||
try
|
||||
{
|
||||
|
||||
/* // remove session from context
|
||||
_manager.removeSession(this,true);
|
||||
|
||||
//invalidate session
|
||||
doInvalidate();
|
||||
*/
|
||||
//tell id mgr to remove session from all other contexts
|
||||
((AbstractSessionIdManager)_manager.getSessionIdManager()).invalidateAll(_sessionData.getId());
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ import java.util.concurrent.ConcurrentHashMap;
|
|||
/**
|
||||
* SessionData
|
||||
*
|
||||
* The data associated with a session
|
||||
* The data associated with a session.
|
||||
*/
|
||||
public class SessionData implements Serializable
|
||||
{
|
||||
|
@ -57,6 +57,15 @@ public class SessionData implements Serializable
|
|||
protected long _lastSaved; //time in msec since last save
|
||||
|
||||
|
||||
/**
|
||||
* @param id
|
||||
* @param cpath
|
||||
* @param vhost
|
||||
* @param created
|
||||
* @param accessed
|
||||
* @param lastAccessed
|
||||
* @param maxInactiveMs
|
||||
*/
|
||||
public SessionData (String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
{
|
||||
_id = id;
|
||||
|
|
|
@ -243,6 +243,7 @@ public class SessionHandler extends ScopedHandler
|
|||
if (requested_session_id != null && sessionManager != null)
|
||||
{
|
||||
HttpSession session = sessionManager.getHttpSession(requested_session_id);
|
||||
|
||||
if (session != null && sessionManager.isValid(session))
|
||||
baseRequest.setSession(session);
|
||||
return;
|
||||
|
@ -273,7 +274,6 @@ public class SessionHandler extends ScopedHandler
|
|||
if (requested_session_id != null)
|
||||
{
|
||||
session = sessionManager.getHttpSession(requested_session_id);
|
||||
|
||||
if (session != null && sessionManager.isValid(session))
|
||||
{
|
||||
break;
|
||||
|
|
|
@ -56,6 +56,8 @@ public class SessionKey
|
|||
|
||||
private SessionKey (String id, String path, String vhost)
|
||||
{
|
||||
if (id == null || path == null || vhost == null)
|
||||
throw new IllegalArgumentException ("Bad values for key");
|
||||
_id = id;
|
||||
_canonicalContextPath = path;
|
||||
_vhost = vhost;
|
||||
|
@ -81,6 +83,24 @@ public class SessionKey
|
|||
return _canonicalContextPath +"_"+_vhost+"_"+_id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object o)
|
||||
{
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
SessionKey k = ((SessionKey)o);
|
||||
if (k.getId().equals(getId()) && k.getCanonicalContextPath().equals(getCanonicalContextPath()) && k.getVhost().equals(getVhost()))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return java.util.Objects.hash(getId(), getCanonicalContextPath(), getVhost());
|
||||
}
|
||||
|
||||
public static String getContextPath (Context context)
|
||||
{
|
||||
if (context == null)
|
||||
|
|
|
@ -29,7 +29,6 @@ import java.util.HashSet;
|
|||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArrayList;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import javax.servlet.SessionCookieConfig;
|
||||
import javax.servlet.SessionTrackingMode;
|
||||
|
@ -52,10 +51,7 @@ import org.eclipse.jetty.util.annotation.ManagedOperation;
|
|||
import org.eclipse.jetty.util.component.ContainerLifeCycle;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.eclipse.jetty.util.statistic.CounterStatistic;
|
||||
import org.eclipse.jetty.util.statistic.SampleStatistic;
|
||||
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
|
||||
import org.eclipse.jetty.util.thread.Scheduler;
|
||||
|
||||
/**
|
||||
* AbstractSessionManager
|
||||
|
@ -92,7 +88,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
}
|
||||
};
|
||||
|
||||
private boolean _usingCookies=true;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
// Setting of max inactive interval for new sessions
|
||||
|
@ -120,47 +116,14 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
protected boolean _nodeIdInSessionId;
|
||||
protected boolean _checkingRemoteSessionIdEncoding;
|
||||
protected String _sessionComment;
|
||||
|
||||
protected SessionStore _sessionStore;
|
||||
protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
|
||||
public Set<SessionTrackingMode> _sessionTrackingModes;
|
||||
|
||||
private boolean _usingURLs;
|
||||
|
||||
|
||||
protected SessionStore _sessionStore;
|
||||
private boolean _usingCookies=true;
|
||||
|
||||
|
||||
protected final CounterStatistic _sessionsStats = new CounterStatistic();
|
||||
protected final SampleStatistic _sessionTimeStats = new SampleStatistic();
|
||||
|
||||
|
||||
protected Scheduler _scheduler; //scheduler for scavenging
|
||||
protected boolean _ownScheduler; //did we create our own scheduler or reuse common one
|
||||
protected Scheduler.Task _task; //scavenge task
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Scavenger
|
||||
*
|
||||
*/
|
||||
protected class Scavenger implements Runnable
|
||||
{
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
scavenge();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (_scheduler != null && _scheduler.isRunning())
|
||||
_task = _scheduler.schedule(this, _scavengeIntervalMs, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -397,7 +360,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
* @return seconds
|
||||
*/
|
||||
@Override
|
||||
@ManagedAttribute("defailt maximum time a session may be idle for (in s)")
|
||||
@ManagedAttribute("default maximum time a session may be idle for (in s)")
|
||||
public int getMaxInactiveInterval()
|
||||
{
|
||||
return _dftMaxIdleSecs;
|
||||
|
@ -410,7 +373,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
@ManagedAttribute("maximum number of simultaneous sessions")
|
||||
public int getSessionsMax()
|
||||
{
|
||||
return (int)_sessionsStats.getMax();
|
||||
return _sessionStore.getSessions();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -420,7 +383,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
@ManagedAttribute("total number of sessions")
|
||||
public int getSessionsTotal()
|
||||
{
|
||||
return (int)_sessionsStats.getTotal();
|
||||
return _sessionStore.getSessionsTotal();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -556,7 +519,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
@ManagedAttribute("number of currently active sessions")
|
||||
public int getSessions()
|
||||
{
|
||||
return (int)_sessionsStats.getCurrent();
|
||||
return _sessionStore.getSessions();
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -618,10 +581,11 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
long created=System.currentTimeMillis();
|
||||
String id =_sessionIdManager.newSessionId(request,created);
|
||||
SessionKey key = SessionKey.getKey(id, _context);
|
||||
Session session = _sessionStore.newSession(key, created, created, created, (_dftMaxIdleSecs>0?_dftMaxIdleSecs*1000L:-1));
|
||||
Session session = _sessionStore.newSession(request, key, created, (_dftMaxIdleSecs>0?_dftMaxIdleSecs*1000L:-1));
|
||||
session.setExtendedId(_sessionIdManager.getExtendedId(id,request));
|
||||
session.setSessionManager(this);
|
||||
session.setLastNode(_sessionIdManager.getWorkerName());
|
||||
session.getSessionData().setExpiry(_dftMaxIdleSecs <= 0 ? 0 : (created + _dftMaxIdleSecs*1000L));
|
||||
|
||||
if (request.isSecure())
|
||||
session.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
|
||||
|
@ -629,21 +593,23 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
try
|
||||
{
|
||||
_sessionStore.put(key, session);
|
||||
|
||||
_sessionIdManager.useId(id);
|
||||
|
||||
if (_sessionListeners!=null)
|
||||
{
|
||||
HttpSessionEvent event=new HttpSessionEvent(session);
|
||||
for (HttpSessionListener listener : _sessionListeners)
|
||||
listener.sessionCreated(event);
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
|
||||
_sessionsStats.increment();
|
||||
if (_sessionListeners!=null)
|
||||
{
|
||||
HttpSessionEvent event=new HttpSessionEvent(session);
|
||||
for (HttpSessionListener listener : _sessionListeners)
|
||||
listener.sessionCreated(event);
|
||||
}
|
||||
|
||||
return session;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
|
@ -666,7 +632,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
@ManagedOperation(value="reset statistics", impact="ACTION")
|
||||
public void statsReset()
|
||||
{
|
||||
_sessionsStats.reset(getSessions());
|
||||
_sessionStore.resetStats();
|
||||
_sessionTimeStats.reset();
|
||||
}
|
||||
|
||||
|
@ -752,7 +718,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
try
|
||||
{
|
||||
SessionKey key = SessionKey.getKey(id, _context);
|
||||
Session session = _sessionStore.get(key);
|
||||
Session session = _sessionStore.get(key, true);
|
||||
if (session != null)
|
||||
{
|
||||
//If the session we got back has expired
|
||||
|
@ -760,18 +726,10 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
{
|
||||
//Tell the id manager that this session id should not be used in case other threads
|
||||
//try to use the same session id in other contexts
|
||||
_sessionIdManager.removeId(id);
|
||||
|
||||
//Remove the expired session from cache and any backing persistent store
|
||||
try
|
||||
{
|
||||
_sessionStore.delete(key);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn("Unable to delete expired session {}", key);
|
||||
}
|
||||
_sessionIdManager.removeId(id);
|
||||
|
||||
//The scavenger thread will pick up this expired session
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
@ -845,18 +803,17 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
{
|
||||
//Remove the Session object from the session store and any backing data store
|
||||
boolean removed = _sessionStore.delete(SessionKey.getKey(session.getId(), _context));
|
||||
|
||||
if (removed)
|
||||
{
|
||||
_sessionsStats.decrement();
|
||||
_sessionTimeStats.set(round((System.currentTimeMillis() - session.getCreationTime())/1000.0));
|
||||
|
||||
if (invalidate && _sessionListeners!=null)
|
||||
if (invalidate)
|
||||
{
|
||||
HttpSessionEvent event=new HttpSessionEvent(session);
|
||||
for (int i = _sessionListeners.size()-1; i>=0; i--)
|
||||
if (_sessionListeners!=null)
|
||||
{
|
||||
_sessionListeners.get(i).sessionDestroyed(event);
|
||||
HttpSessionEvent event=new HttpSessionEvent(session);
|
||||
for (int i = _sessionListeners.size()-1; i>=0; i--)
|
||||
{
|
||||
_sessionListeners.get(i).sessionDestroyed(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -925,10 +882,6 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
new CookieConfig();
|
||||
|
||||
|
||||
private long _scavengeIntervalMs;
|
||||
private Scavenger _scavenger;
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
/**
|
||||
* @return total amount of time all sessions remained valid
|
||||
|
@ -994,7 +947,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
SessionKey oldKey = SessionKey.getKey(oldId, _context);
|
||||
SessionKey newKey = SessionKey.getKey(newId, _context);
|
||||
|
||||
Session session = _sessionStore.get(oldKey);
|
||||
Session session = _sessionStore.get(oldKey, true);
|
||||
if (session == null)
|
||||
{
|
||||
LOG.warn("Unable to renew id to "+newId+" for non-existant session "+oldId);
|
||||
|
@ -1036,10 +989,14 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
|
||||
try
|
||||
{
|
||||
Session session = _sessionStore.get(SessionKey.getKey(id, _context));
|
||||
Session session = _sessionStore.get(SessionKey.getKey(id, _context), false);
|
||||
if (session == null)
|
||||
{
|
||||
return; // couldn't get/load a session for this context with that id
|
||||
session.invalidateAndRemove();
|
||||
}
|
||||
|
||||
_sessionTimeStats.set(round((System.currentTimeMillis() - session.getCreationTime())/1000.0));
|
||||
session.invalidateAndRemove();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
|
|
@ -73,12 +73,22 @@ public class SessionScavenger extends AbstractLifeCycle
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* SessionIdManager associated with this scavenger
|
||||
* @param sessionIdManager
|
||||
*/
|
||||
public void setSessionIdManager (SessionIdManager sessionIdManager)
|
||||
{
|
||||
_sessionIdManager = sessionIdManager;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
|
||||
*/
|
||||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
|
@ -107,6 +117,9 @@ public class SessionScavenger extends AbstractLifeCycle
|
|||
super.doStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
|
||||
*/
|
||||
@Override
|
||||
protected void doStop() throws Exception
|
||||
{
|
||||
|
@ -124,6 +137,10 @@ public class SessionScavenger extends AbstractLifeCycle
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the period between scavenge cycles
|
||||
* @param sec
|
||||
*/
|
||||
public void setScavengeIntervalSec (long sec)
|
||||
{
|
||||
if (sec<=0)
|
||||
|
@ -156,11 +173,23 @@ public class SessionScavenger extends AbstractLifeCycle
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the period between scavenge cycles.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public long getScavengeIntervalSec ()
|
||||
{
|
||||
return _scavengeIntervalMs/1000;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Perform a scavenge cycle:
|
||||
* ask all SessionManagers to find sessions they think have expired and then make
|
||||
* sure that a session sharing the same id is expired on all contexts
|
||||
*/
|
||||
public void scavenge ()
|
||||
{
|
||||
//don't attempt to scavenge if we are shutting down
|
||||
|
@ -203,12 +232,13 @@ public class SessionScavenger extends AbstractLifeCycle
|
|||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see java.lang.Object#toString()
|
||||
*/
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return super.toString()+"[interval="+_scavengeIntervalMs+", ownscheduler="+_ownScheduler+"]";
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ package org.eclipse.jetty.server.session;
|
|||
|
||||
import java.util.Set;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.eclipse.jetty.util.component.LifeCycle;
|
||||
|
||||
/**
|
||||
|
@ -31,12 +33,15 @@ import org.eclipse.jetty.util.component.LifeCycle;
|
|||
*/
|
||||
public interface SessionStore extends LifeCycle
|
||||
{
|
||||
Session newSession (SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs);
|
||||
Session get(SessionKey key) throws Exception;
|
||||
Session newSession (HttpServletRequest request, SessionKey key, long time, long maxInactiveMs);
|
||||
Session get(SessionKey key, boolean staleCheck) throws Exception;
|
||||
void put(SessionKey key, Session session) throws Exception;
|
||||
boolean exists (SessionKey key) throws Exception;
|
||||
boolean delete (SessionKey key) throws Exception;
|
||||
void shutdown ();
|
||||
Set<SessionKey> getExpired ();
|
||||
|
||||
int getSessions();
|
||||
int getSessionsMax();
|
||||
int getSessionsTotal();
|
||||
void resetStats();
|
||||
}
|
||||
|
|
|
@ -22,7 +22,8 @@ package org.eclipse.jetty.server.session;
|
|||
/**
|
||||
* StalePeriodStrategy
|
||||
*
|
||||
*
|
||||
* A session is regarded as being stale if it has been
|
||||
* x seconds since it was last read from the cluster.
|
||||
*/
|
||||
public class StalePeriodStrategy implements StalenessStrategy
|
||||
{
|
||||
|
@ -48,17 +49,26 @@ public class StalePeriodStrategy implements StalenessStrategy
|
|||
}
|
||||
else
|
||||
{
|
||||
return (session.getSessionData().getAccessed() - session.getSessionData().getLastSaved() >= _staleMs);
|
||||
// return (session.getSessionData().getAccessed() - session.getSessionData().getLastSaved() >= _staleMs);
|
||||
return (System.currentTimeMillis() - session.getSessionData().getLastSaved() >= _staleMs);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
public long getStaleSec ()
|
||||
{
|
||||
return (_staleMs<=0?0L:_staleMs/1000L);
|
||||
}
|
||||
|
||||
/**
|
||||
* The amount of time in seconds that a session can be held
|
||||
* in memory without being refreshed from the cluster.
|
||||
* @param sec
|
||||
*/
|
||||
public void setStaleSec (long sec)
|
||||
{
|
||||
if (sec == 0)
|
||||
|
|
|
@ -41,6 +41,10 @@ public class UnreadableSessionDataException extends Exception
|
|||
_key = key;
|
||||
}
|
||||
|
||||
public UnreadableSessionDataException (SessionKey key, boolean loadAttemptsExhausted)
|
||||
{
|
||||
super("Unreadable session "+key+(loadAttemptsExhausted?" max load attempts":""));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -38,7 +38,7 @@ public class FileSessionManagerTest
|
|||
private static boolean _stacks;
|
||||
|
||||
|
||||
// @BeforeClass
|
||||
@BeforeClass
|
||||
public static void beforeClass ()
|
||||
{
|
||||
_log = ((StdErrLog)Log.getLogger("org.eclipse.jetty.server.session"));
|
||||
|
@ -46,7 +46,7 @@ public class FileSessionManagerTest
|
|||
_log.setHideStacks(true);
|
||||
}
|
||||
|
||||
//@AfterClass
|
||||
@AfterClass
|
||||
public static void afterClass()
|
||||
{
|
||||
_log.setHideStacks(_stacks);
|
||||
|
@ -99,7 +99,6 @@ public class FileSessionManagerTest
|
|||
manager.getSessionDataStore().setDeleteUnrestorableFiles(true);
|
||||
manager.setSessionIdManager(idmgr);
|
||||
handler.setSessionManager(manager);
|
||||
// manager.setLazyLoad(true);
|
||||
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
|
||||
FS.ensureEmpty(testDir);
|
||||
|
||||
|
|
|
@ -47,7 +47,7 @@ public class SessionCookieTest
|
|||
* @see org.eclipse.jetty.server.session.SessionStore#newSession(org.eclipse.jetty.server.session.SessionKey, long, long, long, long)
|
||||
*/
|
||||
@Override
|
||||
public Session newSession(SessionKey key, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
public Session newSession(HttpServletRequest request, SessionKey key, long time, long maxInactiveMs)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
|
@ -84,13 +84,12 @@ public class SessionCookieTest
|
|||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPut(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.Session)
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPutIfAbsent(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.Session)
|
||||
*/
|
||||
@Override
|
||||
public void doPut(SessionKey key, Session session)
|
||||
public Session doPutIfAbsent(SessionKey key, Session session)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -107,10 +106,9 @@ public class SessionCookieTest
|
|||
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(org.eclipse.jetty.server.session.SessionKey)
|
||||
*/
|
||||
@Override
|
||||
public void doDelete(SessionKey key)
|
||||
public Session doDelete(SessionKey key)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -43,7 +43,7 @@ public class InvalidationSessionTest extends AbstractInvalidationSessionTest
|
|||
//that the node will re-load the session from the database and discover that it has gone.
|
||||
try
|
||||
{
|
||||
Thread.sleep(2 * JdbcTestServer.SAVE_INTERVAL * 1000);
|
||||
Thread.sleep(2 * JdbcTestServer.STALE_INTERVAL * 1000);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
|
|
|
@ -36,8 +36,21 @@ public class JdbcTestServer extends AbstractTestServer
|
|||
{
|
||||
public static final String DRIVER_CLASS = "org.apache.derby.jdbc.EmbeddedDriver";
|
||||
public static final String DEFAULT_CONNECTION_URL = "jdbc:derby:sessions;create=true";
|
||||
public static final int SAVE_INTERVAL = 1;
|
||||
public static final int STALE_INTERVAL = 1;
|
||||
|
||||
|
||||
public static final String EXPIRY_COL = "extime";
|
||||
public static final String LAST_ACCESS_COL = "latime";
|
||||
public static final String LAST_NODE_COL = "lnode";
|
||||
public static final String LAST_SAVE_COL = "lstime";
|
||||
public static final String MAP_COL = "mo";
|
||||
public static final String MAX_IDLE_COL = "mi";
|
||||
public static final String TABLE = "mysessions";
|
||||
public static final String ID_COL = "mysessionid";
|
||||
public static final String ACCESS_COL = "atime";
|
||||
public static final String CONTEXT_COL = "cpath";
|
||||
public static final String COOKIE_COL = "cooktime";
|
||||
public static final String CREATE_COL = "ctime";
|
||||
|
||||
static
|
||||
{
|
||||
|
@ -81,33 +94,22 @@ public class JdbcTestServer extends AbstractTestServer
|
|||
synchronized(JdbcTestServer.class)
|
||||
{
|
||||
JDBCSessionIdManager idManager = new JDBCSessionIdManager(_server);
|
||||
idManager.setScavengeInterval(_scavengePeriod);
|
||||
idManager.setWorkerName("w"+(__workers++));
|
||||
idManager.setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:(String)config));
|
||||
idManager.getDatabaseAdaptor().setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:(String)config));
|
||||
JDBCSessionIdManager.SessionIdTableSchema idTableSchema = new JDBCSessionIdManager.SessionIdTableSchema();
|
||||
idTableSchema.setTableName("mysessionids");
|
||||
idTableSchema.setIdColumn("myid");
|
||||
idManager.setSessionIdTableSchema(idTableSchema);
|
||||
|
||||
JDBCSessionIdManager.SessionTableSchema sessionTableSchema = new JDBCSessionIdManager.SessionTableSchema();
|
||||
sessionTableSchema.setTableName("mysessions");
|
||||
sessionTableSchema.setIdColumn("mysessionid");
|
||||
sessionTableSchema.setAccessTimeColumn("atime");
|
||||
sessionTableSchema.setContextPathColumn("cpath");
|
||||
sessionTableSchema.setCookieTimeColumn("cooktime");
|
||||
sessionTableSchema.setCreateTimeColumn("ctime");
|
||||
sessionTableSchema.setExpiryTimeColumn("extime");
|
||||
sessionTableSchema.setLastAccessTimeColumn("latime");
|
||||
sessionTableSchema.setLastNodeColumn("lnode");
|
||||
sessionTableSchema.setLastSavedTimeColumn("lstime");
|
||||
sessionTableSchema.setMapColumn("mo");
|
||||
sessionTableSchema.setMaxIntervalColumn("mi");
|
||||
idManager.setSessionTableSchema(sessionTableSchema);
|
||||
|
||||
|
||||
|
||||
|
||||
return idManager;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionManager()
|
||||
*/
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionManager()
|
||||
*/
|
||||
|
@ -116,7 +118,26 @@ public class JdbcTestServer extends AbstractTestServer
|
|||
{
|
||||
JDBCSessionManager manager = new JDBCSessionManager();
|
||||
manager.setSessionIdManager((JDBCSessionIdManager)_sessionIdManager);
|
||||
manager.setSaveInterval(SAVE_INTERVAL); //ensure we save any changes to the session at least once per second
|
||||
JDBCSessionDataStore ds = manager.getSessionDataStore();
|
||||
ds.setGracePeriodSec(_scavengePeriod);
|
||||
manager.getDatabaseAdaptor().setDriverInfo(DRIVER_CLASS, DEFAULT_CONNECTION_URL);
|
||||
JDBCSessionDataStore.SessionTableSchema sessionTableSchema = new JDBCSessionDataStore.SessionTableSchema();
|
||||
sessionTableSchema.setTableName(TABLE);
|
||||
sessionTableSchema.setIdColumn(ID_COL);
|
||||
sessionTableSchema.setAccessTimeColumn(ACCESS_COL);
|
||||
sessionTableSchema.setContextPathColumn(CONTEXT_COL);
|
||||
sessionTableSchema.setCookieTimeColumn(COOKIE_COL);
|
||||
sessionTableSchema.setCreateTimeColumn(CREATE_COL);
|
||||
sessionTableSchema.setExpiryTimeColumn(EXPIRY_COL);
|
||||
sessionTableSchema.setLastAccessTimeColumn(LAST_ACCESS_COL);
|
||||
sessionTableSchema.setLastNodeColumn(LAST_NODE_COL);
|
||||
sessionTableSchema.setLastSavedTimeColumn(LAST_SAVE_COL);
|
||||
sessionTableSchema.setMapColumn(MAP_COL);
|
||||
sessionTableSchema.setMaxIntervalColumn(MAX_IDLE_COL);
|
||||
ds.setSessionTableSchema(sessionTableSchema);
|
||||
StalePeriodStrategy staleStrategy = new StalePeriodStrategy();
|
||||
staleStrategy.setStaleSec(STALE_INTERVAL);
|
||||
((AbstractSessionStore)manager.getSessionStore()).setStaleStrategy(staleStrategy);
|
||||
return manager;
|
||||
}
|
||||
|
||||
|
@ -153,8 +174,8 @@ public class JdbcTestServer extends AbstractTestServer
|
|||
{
|
||||
con = DriverManager.getConnection(DEFAULT_CONNECTION_URL);
|
||||
PreparedStatement statement = con.prepareStatement("select * from "+
|
||||
((JDBCSessionIdManager)_sessionIdManager)._sessionTableSchema.getTableName()+
|
||||
" where "+((JDBCSessionIdManager)_sessionIdManager)._sessionTableSchema.getIdColumn()+" = ?");
|
||||
TABLE+
|
||||
" where "+ID_COL+" = ?");
|
||||
statement.setString(1, id);
|
||||
ResultSet result = statement.executeQuery();
|
||||
if (verbose)
|
||||
|
|
|
@ -74,7 +74,7 @@ public class ModifyMaxInactiveIntervalTest
|
|||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
|
||||
|
||||
//do another request to change the maxinactive interval
|
||||
Request request = client.newRequest("http://localhost:" + port + "/mod/test?action=change&val="+newMaxInactive);
|
||||
request.header("Cookie", sessionCookie);
|
||||
|
@ -86,7 +86,6 @@ public class ModifyMaxInactiveIntervalTest
|
|||
Thread.currentThread().sleep(10*1000L);
|
||||
|
||||
//do another request using the cookie to ensure the session is still there
|
||||
|
||||
request= client.newRequest("http://localhost:" + port + "/mod/test?action=test");
|
||||
request.header("Cookie", sessionCookie);
|
||||
response = request.send();
|
||||
|
|
|
@ -42,7 +42,7 @@ import org.junit.Test;
|
|||
* SaveIntervalTest
|
||||
*
|
||||
* Checks to see that potentially stale sessions that have not
|
||||
* changed are not always reloaded from the datase.
|
||||
* changed are not always reloaded from the database.
|
||||
*
|
||||
* This test is Ignored because it takes a little while to run.
|
||||
*
|
||||
|
@ -65,7 +65,10 @@ public class SaveIntervalTest
|
|||
TestSaveIntervalServlet servlet = new TestSaveIntervalServlet();
|
||||
holder.setServlet(servlet);
|
||||
ctxA.addServlet(holder, "/test");
|
||||
((JDBCSessionManager)ctxA.getSessionHandler().getSessionManager()).setSaveInterval(SAVE);
|
||||
|
||||
StalePeriodStrategy strategy = new StalePeriodStrategy();
|
||||
strategy.setStaleSec(SAVE);
|
||||
((AbstractSessionStore)((JDBCSessionManager)ctxA.getSessionHandler().getSessionManager()).getSessionStore()).setStaleStrategy(strategy);
|
||||
server.start();
|
||||
int port=server.getPort();
|
||||
try
|
||||
|
@ -81,7 +84,7 @@ public class SaveIntervalTest
|
|||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
long lastSaved = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
|
||||
long lastSaved = ((Session)servlet._session).getSessionData().getLastSaved();
|
||||
|
||||
|
||||
//do another request to change the session attribute
|
||||
|
@ -89,7 +92,7 @@ public class SaveIntervalTest
|
|||
request.header("Cookie", sessionCookie);
|
||||
response = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
long tmp = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
|
||||
long tmp = ((Session)servlet._session).getSessionData().getLastSaved();
|
||||
assertNotEquals(lastSaved, tmp); //set of attribute will cause save to db
|
||||
lastSaved = tmp;
|
||||
|
||||
|
@ -105,7 +108,7 @@ public class SaveIntervalTest
|
|||
request.header("Cookie", sessionCookie);
|
||||
response = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
tmp = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
|
||||
tmp = ((Session)servlet._session).getSessionData().getLastSaved();
|
||||
assertNotEquals(lastSaved, tmp);
|
||||
lastSaved = tmp;
|
||||
|
||||
|
@ -119,7 +122,7 @@ public class SaveIntervalTest
|
|||
request.header("Cookie", sessionCookie);
|
||||
response = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
tmp = ((JDBCSessionManager.Session)servlet._session).getLastSaved();
|
||||
tmp = ((Session)servlet._session).getSessionData().getLastSaved();
|
||||
assertEquals(lastSaved, tmp); //the save interval did not expire, so update to the access time will not have been persisted
|
||||
}
|
||||
finally
|
||||
|
@ -147,7 +150,6 @@ public class SaveIntervalTest
|
|||
if ("create".equals(action))
|
||||
{
|
||||
HttpSession session = request.getSession(true);
|
||||
System.err.println("CREATE: Session id="+session.getId());
|
||||
_session = session;
|
||||
return;
|
||||
}
|
||||
|
@ -157,8 +159,7 @@ public class SaveIntervalTest
|
|||
HttpSession session = request.getSession(false);
|
||||
if (session == null)
|
||||
throw new ServletException("Session is null for action=change");
|
||||
|
||||
System.err.println("SET: Session id="+session.getId());
|
||||
|
||||
session.setAttribute("aaa", "12345");
|
||||
assertEquals(_session.getId(), session.getId());
|
||||
return;
|
||||
|
@ -169,7 +170,7 @@ public class SaveIntervalTest
|
|||
HttpSession session = request.getSession(false);
|
||||
if (session == null)
|
||||
throw new ServletException("Session does not exist");
|
||||
System.err.println("TICKLE: Session id="+session.getId());
|
||||
|
||||
assertEquals(_session.getId(), session.getId());
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -50,7 +50,6 @@ public class StopSessionManagerPreserveSessionTest extends AbstractStopSessionMa
|
|||
try
|
||||
{
|
||||
boolean actual = _server.existsInSessionTable(_id, true);
|
||||
System.err.println(expected+":"+actual);
|
||||
assertEquals(expected, actual);
|
||||
}
|
||||
catch (Exception e)
|
||||
|
|
|
@ -33,6 +33,7 @@ import javax.servlet.http.HttpSession;
|
|||
import org.eclipse.jetty.client.HttpClient;
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.client.api.Request;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
|
@ -51,7 +52,8 @@ public abstract class AbstractImmortalSessionTest
|
|||
int scavengePeriod = 2;
|
||||
//turn off session expiry by setting maxInactiveInterval to -1
|
||||
AbstractTestServer server = createServer(0, -1, scavengePeriod);
|
||||
server.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
|
||||
ServletContextHandler context = server.addContext(contextPath);
|
||||
context.addServlet(TestServlet.class, servletMapping);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -82,6 +84,8 @@ public abstract class AbstractImmortalSessionTest
|
|||
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
|
||||
resp = response.getContentAsString();
|
||||
assertEquals(String.valueOf(value),resp.trim());
|
||||
|
||||
assertEquals(1, ((org.eclipse.jetty.server.session.SessionManager)context.getSessionHandler().getSessionManager()).getSessions());
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
|
|
@ -20,6 +20,7 @@ package org.eclipse.jetty.server.session;
|
|||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.junit.Assert.fail;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
|
@ -83,9 +84,8 @@ public abstract class AbstractInvalidationSessionTest
|
|||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
|
||||
|
||||
// Be sure the session is also present in node2
|
||||
|
||||
Request request2 = client.newRequest(urls[1] + "?action=increment");
|
||||
request2.header("Cookie", sessionCookie);
|
||||
ContentResponse response2 = request2.send();
|
||||
|
@ -142,6 +142,18 @@ public abstract class AbstractInvalidationSessionTest
|
|||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
session.invalidate();
|
||||
|
||||
try
|
||||
{
|
||||
session.invalidate();
|
||||
fail("Session should be invalid");
|
||||
|
||||
}
|
||||
catch (IllegalStateException e)
|
||||
{
|
||||
//expected
|
||||
}
|
||||
|
||||
}
|
||||
else if ("test".equals(action))
|
||||
{
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.client.HttpClient;
|
|||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.server.Request;
|
||||
import org.eclipse.jetty.server.SessionManager;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
|
@ -62,14 +63,16 @@ public abstract class AbstractLocalSessionScavengingTest
|
|||
int inactivePeriod = 1;
|
||||
int scavengePeriod = 2;
|
||||
AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
|
||||
server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
|
||||
ServletContextHandler context1 = server1.addContext(contextPath);
|
||||
context1.addServlet(TestServlet.class, servletMapping);
|
||||
|
||||
try
|
||||
{
|
||||
server1.start();
|
||||
int port1 = server1.getPort();
|
||||
AbstractTestServer server2 = createServer(0, inactivePeriod, scavengePeriod * 3);
|
||||
server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
|
||||
ServletContextHandler context2 = server2.addContext(contextPath);
|
||||
context2.addServlet(TestServlet.class, servletMapping);
|
||||
|
||||
try
|
||||
{
|
||||
|
@ -90,28 +93,34 @@ public abstract class AbstractLocalSessionScavengingTest
|
|||
assertTrue(sessionCookie != null);
|
||||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
org.eclipse.jetty.server.session.SessionManager m1 = (org.eclipse.jetty.server.session.SessionManager)context1.getSessionHandler().getSessionManager();
|
||||
assertEquals(1, m1.getSessions());
|
||||
|
||||
// Be sure the session is also present in node2
|
||||
org.eclipse.jetty.client.api.Request request = client.newRequest(urls[1] + "?action=test");
|
||||
request.header("Cookie", sessionCookie);
|
||||
ContentResponse response2 = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
|
||||
|
||||
org.eclipse.jetty.server.session.SessionManager m2 = (org.eclipse.jetty.server.session.SessionManager)context2.getSessionHandler().getSessionManager();
|
||||
assertEquals(1, m2.getSessions());
|
||||
|
||||
// Wait for the scavenger to run on node1, waiting 2.5 times the scavenger period
|
||||
pause(scavengePeriod);
|
||||
|
||||
assertEquals(0, m1.getSessions());
|
||||
|
||||
// Check that node1 does not have any local session cached
|
||||
request = client.newRequest(urls[0] + "?action=check");
|
||||
request.header("Cookie", sessionCookie);
|
||||
response1 = request.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
|
||||
|
||||
|
||||
assertEquals(0, m1.getSessions());
|
||||
|
||||
// Wait for the scavenger to run on node2, waiting 2 times the scavenger period
|
||||
// This ensures that the scavenger on node2 runs at least once.
|
||||
pause(scavengePeriod);
|
||||
|
||||
|
||||
// Check that node2 does not have any local session cached
|
||||
request = client.newRequest(urls[1] + "?action=check");
|
||||
request.header("Cookie", sessionCookie);
|
||||
|
|
|
@ -46,9 +46,7 @@ public abstract class AbstractNewSessionTest
|
|||
{
|
||||
try
|
||||
{
|
||||
System.err.println("Sleeping "+(scavenge * 2500L));
|
||||
Thread.sleep(scavenge * 2500L);
|
||||
System.err.println("Sleeping "+(scavenge * 2500L));
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
|
|
|
@ -123,13 +123,12 @@ public abstract class AbstractSessionInvalidateAndCreateTest
|
|||
// Mangle the cookie, replacing Path with $Path, etc.
|
||||
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
|
||||
|
||||
|
||||
// Make a request which will invalidate the existing session and create a new one
|
||||
Request request2 = client.newRequest(url + "?action=test");
|
||||
request2.header("Cookie", sessionCookie);
|
||||
ContentResponse response2 = request2.send();
|
||||
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
|
||||
|
||||
|
||||
// Wait for the scavenger to run, waiting 3 times the scavenger period
|
||||
pause(scavengePeriod);
|
||||
|
||||
|
|
|
@ -62,7 +62,6 @@ public class WebAppObjectInSessionServlet extends HttpServlet
|
|||
{
|
||||
HttpSession session = request.getSession(false);
|
||||
Object staticAttribute = session.getAttribute("staticAttribute");
|
||||
System.err.println("staticAttribute="+staticAttribute);
|
||||
Assert.assertTrue(staticAttribute instanceof TestSharedStatic);
|
||||
|
||||
// Object objectAttribute = session.getAttribute("objectAttribute");
|
||||
|
|
Loading…
Reference in New Issue