Ensure session loading runs in scope of context classloader.
This commit is contained in:
parent
31ea1704a1
commit
b1707ef228
|
@ -27,7 +27,7 @@ import java.util.Set;
|
|||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.ContextId;
|
||||
import org.eclipse.jetty.server.session.SessionContext;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -161,7 +161,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Loading session {} from DataStore", id);
|
||||
|
||||
Entity entity = _datastore.get(makeKey(id, _contextId));
|
||||
Entity entity = _datastore.get(makeKey(id, _context));
|
||||
if (entity == null)
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("No session {} in DataStore ", id);
|
||||
|
@ -181,7 +181,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
public boolean delete(String id) throws Exception
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Removing session {} from DataStore", id);
|
||||
_datastore.delete(makeKey(id, _contextId));
|
||||
_datastore.delete(makeKey(id, _context));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -252,7 +252,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("Writing session {} to DataStore", data.getId());
|
||||
|
||||
Entity entity = entityFromSession(data, makeKey(id, _contextId));
|
||||
Entity entity = entityFromSession(data, makeKey(id, _context));
|
||||
_datastore.put(entity);
|
||||
}
|
||||
|
||||
|
@ -270,7 +270,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
* @param session
|
||||
* @return
|
||||
*/
|
||||
private Key makeKey (String id, ContextId context)
|
||||
private Key makeKey (String id, SessionContext context)
|
||||
{
|
||||
String key = context.getCanonicalContextPath()+"_"+context.getVhost()+"_"+id;
|
||||
return _keyFactory.newKey(key);
|
||||
|
@ -345,8 +345,6 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
long expiry = entity.getLong(EXPIRY);
|
||||
long maxInactive = entity.getLong(MAXINACTIVE);
|
||||
Blob blob = (Blob) entity.getBlob(ATTRIBUTES);
|
||||
|
||||
System.err.println("Session "+id+" from Entity, expiry="+expiry);
|
||||
|
||||
SessionData session = newSessionData (id, createTime, accessed, lastAccessed, maxInactive);
|
||||
session.setLastNode(lastNode);
|
||||
|
@ -369,18 +367,11 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
};
|
||||
|
||||
load.run();
|
||||
|
||||
/* if (_context==null)
|
||||
load.run();
|
||||
else
|
||||
_context.getContextHandler().handle(null,load);*/
|
||||
|
||||
|
||||
//ensure this runs in the context classloader
|
||||
_context.run(load);
|
||||
|
||||
if (exception.get() != null)
|
||||
{
|
||||
throw exception.get();
|
||||
}
|
||||
|
||||
return reference.get();
|
||||
}
|
||||
|
|
|
@ -22,12 +22,12 @@ package org.eclipse.jetty.session.infinispan;
|
|||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.server.SessionIdManager;
|
||||
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.ContextId;
|
||||
import org.eclipse.jetty.server.session.SessionContext;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.server.session.SessionKey;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
import org.eclipse.jetty.util.log.Logger;
|
||||
import org.infinispan.commons.api.BasicCache;
|
||||
|
@ -88,8 +88,34 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
*/
|
||||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
{
|
||||
return (SessionData)_cache.get(getCacheKey(id, _contextId));
|
||||
{
|
||||
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
|
||||
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
|
||||
|
||||
Runnable load = new Runnable()
|
||||
{
|
||||
public void run ()
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
SessionData sd = (SessionData)_cache.get(getCacheKey(id, _context));
|
||||
reference.set(sd);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception.set(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
//ensure the load runs in the context classloader scope
|
||||
_context.run(load);
|
||||
|
||||
if (exception.get() != null)
|
||||
throw exception.get();
|
||||
|
||||
return reference.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -98,7 +124,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
@Override
|
||||
public boolean delete(String id) throws Exception
|
||||
{
|
||||
return (_cache.remove(getCacheKey(id, _contextId)) != null);
|
||||
return (_cache.remove(getCacheKey(id, _context)) != null);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -145,9 +171,9 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
//scavenges the session before this timeout occurs, the session will be removed.
|
||||
//NOTE: that no session listeners can be called for this.
|
||||
if (data.getMaxInactiveMs() > 0)
|
||||
_cache.put(getCacheKey(id, _contextId), data, -1, TimeUnit.MILLISECONDS, (data.getMaxInactiveMs() * _idleExpiryMultiple), TimeUnit.MILLISECONDS);
|
||||
_cache.put(getCacheKey(id, _context), data, -1, TimeUnit.MILLISECONDS, (data.getMaxInactiveMs() * _idleExpiryMultiple), TimeUnit.MILLISECONDS);
|
||||
else
|
||||
_cache.put(getCacheKey(id, _contextId), data);
|
||||
_cache.put(getCacheKey(id, _context), data);
|
||||
|
||||
//tickle the session id manager to keep the sessionid entry for this session up-to-date
|
||||
if (_idMgr != null && _idMgr instanceof InfinispanSessionIdManager)
|
||||
|
@ -157,9 +183,9 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
|
||||
public static String getCacheKey (String id, ContextId contextId)
|
||||
public static String getCacheKey (String id, SessionContext context)
|
||||
{
|
||||
return contextId.getCanonicalContextPath()+"_"+contextId.getVhost()+"_"+id;
|
||||
return context.getCanonicalContextPath()+"_"+context.getVhost()+"_"+id;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -90,7 +90,7 @@ public abstract class NoSqlSessionDataStore extends AbstractSessionDataStore
|
|||
@Override
|
||||
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
{
|
||||
return new NoSqlSessionData(id, _contextId.getCanonicalContextPath(), _contextId.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
return new NoSqlSessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.HashMap;
|
|||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
|
@ -193,76 +194,90 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
{
|
||||
DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("id={} loaded={}", id, sessionDocument);
|
||||
|
||||
if (sessionDocument == null)
|
||||
return null;
|
||||
|
||||
Boolean valid = (Boolean)sessionDocument.get(__VALID);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("id={} valid={}", id, valid);
|
||||
if (valid == null || !valid)
|
||||
return null;
|
||||
|
||||
try
|
||||
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
|
||||
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
|
||||
Runnable r = new Runnable()
|
||||
{
|
||||
Object version = getNestedValue(sessionDocument, getContextSubfield(__VERSION));
|
||||
|
||||
Long created = (Long)sessionDocument.get(__CREATED);
|
||||
Long accessed = (Long)sessionDocument.get(__ACCESSED);
|
||||
Long maxInactive = (Long)sessionDocument.get(__MAX_IDLE);
|
||||
Long expiry = (Long)sessionDocument.get(__EXPIRY);
|
||||
|
||||
NoSqlSessionData data = null;
|
||||
|
||||
// get the session for the context
|
||||
DBObject sessionSubDocumentForContext = (DBObject)getNestedValue(sessionDocument,getContextField());
|
||||
|
||||
if (LOG.isDebugEnabled()) LOG.debug("attrs {}", sessionSubDocumentForContext);
|
||||
|
||||
if (sessionSubDocumentForContext != null)
|
||||
public void run ()
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Session {} present for context {}", id, _contextId);
|
||||
|
||||
//only load a session if it exists for this context
|
||||
data = (NoSqlSessionData)newSessionData(id, created, accessed, accessed, maxInactive);
|
||||
data.setVersion(version);
|
||||
data.setExpiry(expiry);
|
||||
data.setContextPath(_contextId.getCanonicalContextPath());
|
||||
data.setVhost(_contextId.getVhost());
|
||||
|
||||
HashMap<String, Object> attributes = new HashMap<>();
|
||||
for (String name : sessionSubDocumentForContext.keySet())
|
||||
try
|
||||
{
|
||||
//skip special metadata attribute which is not one of the actual session attributes
|
||||
if ( __METADATA.equals(name) )
|
||||
continue;
|
||||
String attr = decodeName(name);
|
||||
Object value = decodeValue(sessionSubDocumentForContext.get(name));
|
||||
attributes.put(attr,value);
|
||||
}
|
||||
|
||||
data.putAllAttributes(attributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Session {} not present for context {}", id, _contextId);
|
||||
}
|
||||
DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id));
|
||||
|
||||
return data;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
LOG.warn(e);
|
||||
}
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("id={} loaded={}", id, sessionDocument);
|
||||
|
||||
if (sessionDocument == null)
|
||||
return;
|
||||
|
||||
Boolean valid = (Boolean)sessionDocument.get(__VALID);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("id={} valid={}", id, valid);
|
||||
if (valid == null || !valid)
|
||||
return;
|
||||
|
||||
|
||||
Object version = getNestedValue(sessionDocument, getContextSubfield(__VERSION));
|
||||
|
||||
Long created = (Long)sessionDocument.get(__CREATED);
|
||||
Long accessed = (Long)sessionDocument.get(__ACCESSED);
|
||||
Long maxInactive = (Long)sessionDocument.get(__MAX_IDLE);
|
||||
Long expiry = (Long)sessionDocument.get(__EXPIRY);
|
||||
|
||||
NoSqlSessionData data = null;
|
||||
|
||||
// get the session for the context
|
||||
DBObject sessionSubDocumentForContext = (DBObject)getNestedValue(sessionDocument,getContextField());
|
||||
|
||||
if (LOG.isDebugEnabled()) LOG.debug("attrs {}", sessionSubDocumentForContext);
|
||||
|
||||
if (sessionSubDocumentForContext != null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Session {} present for context {}", id, _context);
|
||||
|
||||
//only load a session if it exists for this context
|
||||
data = (NoSqlSessionData)newSessionData(id, created, accessed, accessed, maxInactive);
|
||||
data.setVersion(version);
|
||||
data.setExpiry(expiry);
|
||||
data.setContextPath(_context.getCanonicalContextPath());
|
||||
data.setVhost(_context.getVhost());
|
||||
|
||||
HashMap<String, Object> attributes = new HashMap<>();
|
||||
for (String name : sessionSubDocumentForContext.keySet())
|
||||
{
|
||||
//skip special metadata attribute which is not one of the actual session attributes
|
||||
if ( __METADATA.equals(name) )
|
||||
continue;
|
||||
String attr = decodeName(name);
|
||||
Object value = decodeValue(sessionSubDocumentForContext.get(name));
|
||||
attributes.put(attr,value);
|
||||
}
|
||||
|
||||
data.putAllAttributes(attributes);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Session {} not present for context {}", id, _context);
|
||||
}
|
||||
|
||||
reference.set(data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception.set(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
return null;
|
||||
_context.run(r);
|
||||
|
||||
if (exception.get() != null)
|
||||
throw exception.get();
|
||||
|
||||
return reference.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -272,7 +287,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
public boolean delete(String id) throws Exception
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Remove:session {} for context ",id, _contextId);
|
||||
LOG.debug("Remove:session {} for context ",id, _context);
|
||||
|
||||
/*
|
||||
* Check if the session exists and if it does remove the context
|
||||
|
@ -345,7 +360,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
for ( DBObject session : verifiedExpiredSessions )
|
||||
{
|
||||
String id = (String)session.get(__ID);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("{} Mongo confirmed expired session {}", _contextId,id);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("{} Mongo confirmed expired session {}", _context,id);
|
||||
expiredSessions.add(id);
|
||||
}
|
||||
}
|
||||
|
@ -368,7 +383,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
for (DBObject session : oldExpiredSessions)
|
||||
{
|
||||
String id = (String)session.get(__ID);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("{} Mongo found old expired session {}", _contextId, id);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("{} Mongo found old expired session {}", _context, id);
|
||||
expiredSessions.add(id);
|
||||
}
|
||||
|
||||
|
@ -499,7 +514,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
|
|||
|
||||
private String getCanonicalContextId ()
|
||||
{
|
||||
return canonicalizeVHost(_contextId.getVhost()) + ":" + _contextId.getCanonicalContextPath();
|
||||
return canonicalizeVHost(_context.getVhost()) + ":" + _context.getCanonicalContextPath();
|
||||
}
|
||||
|
||||
private String canonicalizeVHost (String vhost)
|
||||
|
|
|
@ -29,7 +29,7 @@ import org.eclipse.jetty.util.component.AbstractLifeCycle;
|
|||
*/
|
||||
public abstract class AbstractSessionDataStore extends AbstractLifeCycle implements SessionDataStore
|
||||
{
|
||||
protected ContextId _contextId; //context associated with this session data store
|
||||
protected SessionContext _context; //context associated with this session data store
|
||||
|
||||
|
||||
public abstract void doStore(String id, SessionData data, boolean isNew) throws Exception;
|
||||
|
@ -37,11 +37,11 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
|
|||
|
||||
|
||||
|
||||
public void initialize (ContextId id)
|
||||
public void initialize (SessionContext context)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Context set after SessionDataStore started");
|
||||
_contextId = id;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -75,7 +75,7 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
|
|||
@Override
|
||||
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
{
|
||||
return new SessionData(id, _contextId.getCanonicalContextPath(), _contextId.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
}
|
||||
|
||||
protected void checkStarted () throws IllegalStateException
|
||||
|
@ -90,8 +90,8 @@ public abstract class AbstractSessionDataStore extends AbstractLifeCycle impleme
|
|||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
if (_contextId == null)
|
||||
throw new IllegalStateException ("No ContextId");
|
||||
if (_context == null)
|
||||
throw new IllegalStateException ("No SessionContext");
|
||||
|
||||
super.doStart();
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
protected SessionDataStore _sessionDataStore;
|
||||
protected StalenessStrategy _staleStrategy;
|
||||
protected SessionManager _manager;
|
||||
protected ContextId _contextId;
|
||||
protected SessionContext _context;
|
||||
|
||||
|
||||
|
||||
|
@ -123,11 +123,11 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
|
||||
|
||||
|
||||
public void initialize (ContextId contextId)
|
||||
public void initialize (SessionContext context)
|
||||
{
|
||||
if (isStarted())
|
||||
throw new IllegalStateException("Context set after session store started");
|
||||
_contextId = contextId;
|
||||
_context = context;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -139,10 +139,10 @@ public abstract class AbstractSessionStore extends AbstractLifeCycle implements
|
|||
if (_manager == null)
|
||||
throw new IllegalStateException ("No session manager");
|
||||
|
||||
if (_contextId == null)
|
||||
if (_context == null)
|
||||
throw new IllegalStateException ("No ContextId");
|
||||
|
||||
_sessionDataStore.initialize(_contextId);
|
||||
_sessionDataStore.initialize(_context);
|
||||
_sessionDataStore.start();
|
||||
|
||||
super.doStart();
|
||||
|
|
|
@ -41,7 +41,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
public boolean putIfAbsent (String id, SessionData data); //only insert if no mapping for key already
|
||||
public boolean remove (String id); //remove the mapping for key, returns false if no mapping
|
||||
public void put (String id, SessionData data); //overwrite or add the mapping
|
||||
public void initialize(ContextId contextId);
|
||||
public void initialize(SessionContext context);
|
||||
}
|
||||
|
||||
|
||||
|
@ -144,8 +144,8 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
|
|||
@Override
|
||||
protected void doStart() throws Exception
|
||||
{
|
||||
_cache.initialize(_contextId);
|
||||
_delegateDataStore.initialize(_contextId);
|
||||
_cache.initialize(_context);
|
||||
_delegateDataStore.initialize(_context);
|
||||
super.doStart();
|
||||
}
|
||||
|
||||
|
|
|
@ -33,6 +33,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -96,7 +97,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
File file = null;
|
||||
if (_storeDir != null)
|
||||
{
|
||||
file = new File(_storeDir, _contextId.toString()+"_"+id);
|
||||
file = new File(_storeDir, getFileName(id));
|
||||
if (file.exists() && file.getParentFile().equals(_storeDir))
|
||||
{
|
||||
file.delete();
|
||||
|
@ -124,40 +125,135 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
@Override
|
||||
public SessionData load(String id) throws Exception
|
||||
{
|
||||
File file = new File(_storeDir, _contextId.toString()+"_"+id);
|
||||
|
||||
if (!file.exists())
|
||||
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
|
||||
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
|
||||
Runnable r = new Runnable()
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("No file: {}",file);
|
||||
return null;
|
||||
}
|
||||
|
||||
try (FileInputStream in = new FileInputStream(file))
|
||||
{
|
||||
SessionData data = load(in);
|
||||
//delete restored file
|
||||
file.delete();
|
||||
return data;
|
||||
}
|
||||
catch (UnreadableSessionDataException e)
|
||||
{
|
||||
if (isDeleteUnrestorableFiles() && file.exists() && file.getParentFile().equals(_storeDir));
|
||||
public void run ()
|
||||
{
|
||||
file.delete();
|
||||
LOG.warn("Deleted unrestorable file for session {}", id);
|
||||
File file = new File(_storeDir,getFileName(id));
|
||||
|
||||
if (!file.exists())
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("No file: {}",file);
|
||||
return;
|
||||
}
|
||||
|
||||
try (FileInputStream in = new FileInputStream(file))
|
||||
{
|
||||
SessionData data = load(in);
|
||||
//delete restored file
|
||||
file.delete();
|
||||
reference.set(data);
|
||||
}
|
||||
catch (UnreadableSessionDataException e)
|
||||
{
|
||||
if (isDeleteUnrestorableFiles() && file.exists() && file.getParentFile().equals(_storeDir));
|
||||
{
|
||||
file.delete();
|
||||
LOG.warn("Deleted unrestorable file for session {}", id);
|
||||
}
|
||||
exception.set(e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
exception.set(e);
|
||||
}
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
};
|
||||
//ensure this runs with the context classloader set
|
||||
_context.run(r);
|
||||
|
||||
if (exception.get() != null)
|
||||
throw exception.get();
|
||||
|
||||
return reference.get();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, boolean isNew) throws Exception
|
||||
{
|
||||
File file = null;
|
||||
if (_storeDir != null)
|
||||
{
|
||||
file = new File(_storeDir, getFileName(id));
|
||||
if (file.exists())
|
||||
file.delete();
|
||||
|
||||
try(FileOutputStream fos = new FileOutputStream(file,false))
|
||||
{
|
||||
save(fos, id, data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (file != null)
|
||||
file.delete(); // No point keeping the file if we didn't save the whole session
|
||||
throw new UnwriteableSessionDataException(id, _context,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void initializeStore ()
|
||||
{
|
||||
if (_storeDir == null)
|
||||
throw new IllegalStateException("No file store specified");
|
||||
|
||||
if (!_storeDir.exists())
|
||||
_storeDir.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void save(OutputStream os, String id, SessionData data) throws IOException
|
||||
{
|
||||
DataOutputStream out = new DataOutputStream(os);
|
||||
out.writeUTF(id);
|
||||
out.writeUTF(_context.getCanonicalContextPath());
|
||||
out.writeUTF(_context.getVhost());
|
||||
out.writeUTF(data.getLastNode());
|
||||
out.writeLong(data.getCreated());
|
||||
out.writeLong(data.getAccessed());
|
||||
out.writeLong(data.getLastAccessed());
|
||||
out.writeLong(data.getCookieSet());
|
||||
out.writeLong(data.getExpiry());
|
||||
out.writeLong(data.getMaxInactiveMs());
|
||||
|
||||
List<String> keys = new ArrayList<String>(data.getKeys());
|
||||
out.writeInt(keys.size());
|
||||
ObjectOutputStream oos = new ObjectOutputStream(out);
|
||||
for (String name:keys)
|
||||
{
|
||||
oos.writeUTF(name);
|
||||
oos.writeObject(data.getAttribute(name));
|
||||
}
|
||||
}
|
||||
|
||||
private String getFileName (String id)
|
||||
{
|
||||
return _context.getCanonicalContextPath()+"_"+_context.getVhost()+"_"+id;
|
||||
}
|
||||
|
||||
|
||||
private SessionData load (InputStream is)
|
||||
throws Exception
|
||||
throws Exception
|
||||
{
|
||||
String id = null;
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
SessionData data = null;
|
||||
|
@ -189,12 +285,12 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new UnreadableSessionDataException(id, _contextId, e);
|
||||
throw new UnreadableSessionDataException(id, _context, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void restoreAttributes (InputStream is, int size, SessionData data)
|
||||
throws Exception
|
||||
throws Exception
|
||||
{
|
||||
if (size>0)
|
||||
{
|
||||
|
@ -211,78 +307,6 @@ public class FileSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(org.eclipse.jetty.server.session.SessionKey, org.eclipse.jetty.server.session.SessionData)
|
||||
*/
|
||||
@Override
|
||||
public void doStore(String id, SessionData data, boolean isNew) throws Exception
|
||||
{
|
||||
File file = null;
|
||||
if (_storeDir != null)
|
||||
{
|
||||
file = new File(_storeDir, _contextId.toString()+"_"+id);
|
||||
if (file.exists())
|
||||
file.delete();
|
||||
|
||||
try(FileOutputStream fos = new FileOutputStream(file,false))
|
||||
{
|
||||
save(fos, id, data);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (file != null)
|
||||
file.delete(); // No point keeping the file if we didn't save the whole session
|
||||
throw new UnwriteableSessionDataException(id, _contextId,e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* ------------------------------------------------------------ */
|
||||
private void save(OutputStream os, String id, SessionData data) throws IOException
|
||||
{
|
||||
DataOutputStream out = new DataOutputStream(os);
|
||||
out.writeUTF(id);
|
||||
out.writeUTF(_contextId.getCanonicalContextPath());
|
||||
out.writeUTF(_contextId.getVhost());
|
||||
out.writeUTF(data.getLastNode());
|
||||
out.writeLong(data.getCreated());
|
||||
out.writeLong(data.getAccessed());
|
||||
out.writeLong(data.getLastAccessed());
|
||||
out.writeLong(data.getCookieSet());
|
||||
out.writeLong(data.getExpiry());
|
||||
out.writeLong(data.getMaxInactiveMs());
|
||||
|
||||
List<String> keys = new ArrayList<String>(data.getKeys());
|
||||
out.writeInt(keys.size());
|
||||
ObjectOutputStream oos = new ObjectOutputStream(out);
|
||||
for (String name:keys)
|
||||
{
|
||||
oos.writeUTF(name);
|
||||
oos.writeObject(data.getAttribute(name));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void initializeStore ()
|
||||
{
|
||||
if (_storeDir == null)
|
||||
throw new IllegalStateException("No file store specified");
|
||||
|
||||
if (!_storeDir.exists())
|
||||
_storeDir.mkdirs();
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
|
||||
*/
|
||||
@Override
|
||||
public boolean isPassivating()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
|
||||
import org.eclipse.jetty.util.log.Log;
|
||||
|
@ -359,7 +360,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
return statement;
|
||||
}
|
||||
|
||||
public void fillCheckSessionExistsStatement (PreparedStatement statement, String id, ContextId contextId)
|
||||
public void fillCheckSessionExistsStatement (PreparedStatement statement, String id, SessionContext contextId)
|
||||
throws SQLException
|
||||
{
|
||||
statement.clearParameters();
|
||||
|
@ -378,7 +379,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
}
|
||||
|
||||
|
||||
public PreparedStatement getLoadStatement (Connection connection, String id, ContextId contextId)
|
||||
public PreparedStatement getLoadStatement (Connection connection, String id, SessionContext contextId)
|
||||
throws SQLException
|
||||
{
|
||||
if (_dbAdaptor == null)
|
||||
|
@ -412,7 +413,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
|
||||
public PreparedStatement getUpdateStatement (Connection connection, String id, ContextId contextId)
|
||||
public PreparedStatement getUpdateStatement (Connection connection, String id, SessionContext contextId)
|
||||
throws SQLException
|
||||
{
|
||||
if (_dbAdaptor == null)
|
||||
|
@ -447,7 +448,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
|
||||
|
||||
public PreparedStatement getDeleteStatement (Connection connection, String id, ContextId contextId)
|
||||
public PreparedStatement getDeleteStatement (Connection connection, String id, SessionContext contextId)
|
||||
throws Exception
|
||||
{
|
||||
if (_dbAdaptor == null)
|
||||
|
@ -635,70 +636,92 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
public SessionData load(String id) throws Exception
|
||||
{
|
||||
if (getLoadAttempts() > 0 && loadAttemptsExhausted(id))
|
||||
throw new UnreadableSessionDataException(id, _contextId, true);
|
||||
throw new UnreadableSessionDataException(id, _context, true);
|
||||
|
||||
try (Connection connection = _dbAdaptor.getConnection();
|
||||
PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, _contextId);
|
||||
ResultSet result = statement.executeQuery())
|
||||
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
|
||||
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
|
||||
|
||||
Runnable r = new Runnable()
|
||||
{
|
||||
SessionData data = null;
|
||||
if (result.next())
|
||||
{
|
||||
data = newSessionData(id,
|
||||
result.getLong(_sessionTableSchema.getCreateTimeColumn()),
|
||||
result.getLong(_sessionTableSchema.getAccessTimeColumn()),
|
||||
result.getLong(_sessionTableSchema.getLastAccessTimeColumn()),
|
||||
result.getLong(_sessionTableSchema.getMaxIntervalColumn()));
|
||||
data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
|
||||
data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
|
||||
data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
|
||||
data.setExpiry(result.getLong(_sessionTableSchema.getExpiryTimeColumn()));
|
||||
data.setContextPath(result.getString(_sessionTableSchema.getContextPathColumn())); //TODO needed? this is part of the key now
|
||||
data.setVhost(result.getString(_sessionTableSchema.getVirtualHostColumn())); //TODO needed??? this is part of the key now
|
||||
|
||||
try (InputStream is = _dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn());
|
||||
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
|
||||
public void run ()
|
||||
{
|
||||
try (Connection connection = _dbAdaptor.getConnection();
|
||||
PreparedStatement statement = _sessionTableSchema.getLoadStatement(connection, id, _context);
|
||||
ResultSet result = statement.executeQuery())
|
||||
{
|
||||
Object o = ois.readObject();
|
||||
data.putAllAttributes((Map<String,Object>)o);
|
||||
SessionData data = null;
|
||||
if (result.next())
|
||||
{
|
||||
data = newSessionData(id,
|
||||
result.getLong(_sessionTableSchema.getCreateTimeColumn()),
|
||||
result.getLong(_sessionTableSchema.getAccessTimeColumn()),
|
||||
result.getLong(_sessionTableSchema.getLastAccessTimeColumn()),
|
||||
result.getLong(_sessionTableSchema.getMaxIntervalColumn()));
|
||||
data.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
|
||||
data.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
|
||||
data.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
|
||||
data.setExpiry(result.getLong(_sessionTableSchema.getExpiryTimeColumn()));
|
||||
data.setContextPath(result.getString(_sessionTableSchema.getContextPathColumn())); //TODO needed? this is part of the key now
|
||||
data.setVhost(result.getString(_sessionTableSchema.getVirtualHostColumn())); //TODO needed??? this is part of the key now
|
||||
|
||||
try (InputStream is = _dbAdaptor.getBlobInputStream(result, _sessionTableSchema.getMapColumn());
|
||||
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
|
||||
{
|
||||
Object o = ois.readObject();
|
||||
data.putAllAttributes((Map<String,Object>)o);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (getLoadAttempts() > 0)
|
||||
{
|
||||
incLoadAttempt (id);
|
||||
}
|
||||
throw new UnreadableSessionDataException (id, _context, e);
|
||||
}
|
||||
|
||||
//if the session successfully loaded, remove failed attempts
|
||||
_unloadables.remove(id);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("LOADED session {}", data);
|
||||
}
|
||||
else
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("No session {}", id);
|
||||
|
||||
reference.set(data);
|
||||
}
|
||||
catch (UnreadableSessionDataException e)
|
||||
{
|
||||
if (getLoadAttempts() > 0 && loadAttemptsExhausted(id) && isDeleteUnloadableSessions())
|
||||
{
|
||||
try
|
||||
{
|
||||
delete (id);
|
||||
_unloadables.remove(id);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.warn("Problem deleting unloadable session {}", id);
|
||||
}
|
||||
|
||||
}
|
||||
exception.set(e);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (getLoadAttempts() > 0)
|
||||
{
|
||||
incLoadAttempt (id);
|
||||
}
|
||||
throw new UnreadableSessionDataException (id, _contextId, e);
|
||||
exception.set(e);
|
||||
}
|
||||
|
||||
//if the session successfully loaded, remove failed attempts
|
||||
_unloadables.remove(id);
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("LOADED session {}", data);
|
||||
}
|
||||
else
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("No session {}", id);
|
||||
return data;
|
||||
}
|
||||
catch (UnreadableSessionDataException e)
|
||||
{
|
||||
if (getLoadAttempts() > 0 && loadAttemptsExhausted(id) && isDeleteUnloadableSessions())
|
||||
{
|
||||
try
|
||||
{
|
||||
delete (id);
|
||||
_unloadables.remove(id);
|
||||
}
|
||||
catch (Exception x)
|
||||
{
|
||||
LOG.warn("Problem deleting unloadable session {}", id);
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
//ensure this runs with context classloader set
|
||||
_context.run(r);
|
||||
|
||||
if (exception.get() != null)
|
||||
throw exception.get();
|
||||
|
||||
return reference.get();
|
||||
}
|
||||
|
||||
|
||||
|
@ -710,7 +733,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
public boolean delete(String id) throws Exception
|
||||
{
|
||||
try (Connection connection = _dbAdaptor.getConnection();
|
||||
PreparedStatement statement = _sessionTableSchema.getDeleteStatement(connection, id, _contextId))
|
||||
PreparedStatement statement = _sessionTableSchema.getDeleteStatement(connection, id, _context))
|
||||
{
|
||||
connection.setAutoCommit(true);
|
||||
int rows = statement.executeUpdate();
|
||||
|
@ -756,8 +779,8 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
try (PreparedStatement statement = connection.prepareStatement(s))
|
||||
{
|
||||
statement.setString(1, id); //session id
|
||||
statement.setString(2, _contextId.getCanonicalContextPath()); //context path
|
||||
statement.setString(3, _contextId.getVhost()); //first vhost
|
||||
statement.setString(2, _context.getCanonicalContextPath()); //context path
|
||||
statement.setString(3, _context.getVhost()); //first vhost
|
||||
statement.setString(4, data.getLastNode());//my node id
|
||||
statement.setLong(5, data.getAccessed());//accessTime
|
||||
statement.setLong(6, data.getLastAccessed()); //lastAccessTime
|
||||
|
@ -788,7 +811,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
try (Connection connection = _dbAdaptor.getConnection())
|
||||
{
|
||||
connection.setAutoCommit(true);
|
||||
try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, _contextId.getCanonicalContextPath()))
|
||||
try (PreparedStatement statement = _sessionTableSchema.getUpdateSessionStatement(connection, _context.getCanonicalContextPath()))
|
||||
{
|
||||
statement.setString(1, data.getLastNode());//should be my node id
|
||||
statement.setLong(2, data.getAccessed());//accessTime
|
||||
|
@ -805,16 +828,16 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
|
||||
statement.setBinaryStream(7, bais, bytes.length);//attribute map as blob
|
||||
|
||||
if ((_contextId.getCanonicalContextPath() == null || "".equals(_contextId.getCanonicalContextPath())) && _dbAdaptor.isEmptyStringNull())
|
||||
if ((_context.getCanonicalContextPath() == null || "".equals(_context.getCanonicalContextPath())) && _dbAdaptor.isEmptyStringNull())
|
||||
{
|
||||
statement.setString(8, id);
|
||||
statement.setString(9, _contextId.getVhost());
|
||||
statement.setString(9, _context.getVhost());
|
||||
}
|
||||
else
|
||||
{
|
||||
statement.setString(8, id);
|
||||
statement.setString(9, _contextId.getCanonicalContextPath());
|
||||
statement.setString(10, _contextId.getVhost());
|
||||
statement.setString(9, _context.getCanonicalContextPath());
|
||||
statement.setString(10, _context.getVhost());
|
||||
}
|
||||
|
||||
statement.executeUpdate();
|
||||
|
@ -848,9 +871,9 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
*/
|
||||
long upperBound = now;
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug ("{}- Pass 1: Searching for sessions for node {} and context {} expired before {}", _contextId.getNode(), _contextId.getCanonicalContextPath(), upperBound);
|
||||
LOG.debug ("{}- Pass 1: Searching for sessions for node {} and context {} expired before {}", _context.getWorkerName(), _context.getCanonicalContextPath(), upperBound);
|
||||
|
||||
try (PreparedStatement statement = _sessionTableSchema.getMyExpiredSessionsStatement(connection, _contextId.getCanonicalContextPath(), _contextId.getVhost(), upperBound))
|
||||
try (PreparedStatement statement = _sessionTableSchema.getMyExpiredSessionsStatement(connection, _context.getCanonicalContextPath(), _context.getVhost(), upperBound))
|
||||
{
|
||||
try (ResultSet result = statement.executeQuery())
|
||||
{
|
||||
|
@ -859,7 +882,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
String sessionId = result.getString(_sessionTableSchema.getIdColumn());
|
||||
long exp = result.getLong(_sessionTableSchema.getExpiryTimeColumn());
|
||||
expiredSessionKeys.add(sessionId);
|
||||
if (LOG.isDebugEnabled()) LOG.debug (_contextId.getCanonicalContextPath()+"- Found expired sessionId="+sessionId);
|
||||
if (LOG.isDebugEnabled()) LOG.debug (_context.getCanonicalContextPath()+"- Found expired sessionId="+sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -872,7 +895,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
upperBound = now - (3 * _gracePeriodMs);
|
||||
if (upperBound > 0)
|
||||
{
|
||||
if (LOG.isDebugEnabled()) LOG.debug("{}- Pass 2: Searching for sessions expired before {}",_contextId.getNode(), upperBound);
|
||||
if (LOG.isDebugEnabled()) LOG.debug("{}- Pass 2: Searching for sessions expired before {}",_context.getWorkerName(), upperBound);
|
||||
|
||||
selectExpiredSessions.setLong(1, upperBound);
|
||||
try (ResultSet result = selectExpiredSessions.executeQuery())
|
||||
|
@ -883,7 +906,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
String ctxtpth = result.getString(_sessionTableSchema.getContextPathColumn());
|
||||
String vh = result.getString(_sessionTableSchema.getVirtualHostColumn());
|
||||
expiredSessionKeys.add(sessionId);
|
||||
if (LOG.isDebugEnabled()) LOG.debug ("{}- Found expired sessionId=",_contextId.getNode(), sessionId);
|
||||
if (LOG.isDebugEnabled()) LOG.debug ("{}- Found expired sessionId=",_context.getWorkerName(), sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -904,11 +927,11 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
|
|||
if (!notExpiredInDB.isEmpty())
|
||||
{
|
||||
//we have some sessions to check
|
||||
try (PreparedStatement checkSessionExists = _sessionTableSchema.getCheckSessionExistsStatement(connection, _contextId.getCanonicalContextPath()))
|
||||
try (PreparedStatement checkSessionExists = _sessionTableSchema.getCheckSessionExistsStatement(connection, _context.getCanonicalContextPath()))
|
||||
{
|
||||
for (String k: notExpiredInDB)
|
||||
{
|
||||
_sessionTableSchema.fillCheckSessionExistsStatement (checkSessionExists, k, _contextId);
|
||||
_sessionTableSchema.fillCheckSessionExistsStatement (checkSessionExists, k, _context);
|
||||
try (ResultSet result = checkSessionExists.executeQuery())
|
||||
{
|
||||
if (!result.next())
|
||||
|
|
|
@ -45,7 +45,7 @@ public class NullSessionDataStore extends AbstractSessionDataStore
|
|||
@Override
|
||||
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
|
||||
{
|
||||
return new SessionData(id, _contextId.getCanonicalContextPath(), _contextId.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,41 +19,44 @@
|
|||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||
|
||||
/**
|
||||
* ContextId
|
||||
*
|
||||
* SessionContext
|
||||
*
|
||||
* The worker name which identifies this server instance, and the particular
|
||||
* Context.
|
||||
*
|
||||
* A SessionManager is 1:1 with a SessionContext.
|
||||
*/
|
||||
public class ContextId
|
||||
public class SessionContext
|
||||
{
|
||||
public final static String NULL_VHOST = "0.0.0.0";
|
||||
|
||||
private String _node;
|
||||
private ContextHandler.Context _context;
|
||||
private String _workerName;
|
||||
private String _canonicalContextPath;
|
||||
private String _vhost;
|
||||
|
||||
|
||||
public static ContextId getContextId (String node, Context context)
|
||||
|
||||
public String getWorkerName()
|
||||
{
|
||||
return new ContextId((node==null?"":node), getContextPath(context), getVirtualHost(context));
|
||||
return _workerName;
|
||||
}
|
||||
|
||||
|
||||
public SessionContext (String workerName, ContextHandler.Context context)
|
||||
{
|
||||
_workerName = workerName;
|
||||
_context = context;
|
||||
_canonicalContextPath = canonicalizeContextPath(_context);
|
||||
_vhost = canonicalizeVHost(_context);
|
||||
}
|
||||
|
||||
|
||||
private ContextId (String node, String path, String vhost)
|
||||
public Context getContext ()
|
||||
{
|
||||
if (node == null || path == null || vhost == null)
|
||||
throw new IllegalArgumentException ("Bad values for ContextId ["+node+","+path+","+vhost+"]");
|
||||
|
||||
_node = node;
|
||||
_canonicalContextPath = path;
|
||||
_vhost = vhost;
|
||||
}
|
||||
|
||||
public String getNode()
|
||||
{
|
||||
return _node;
|
||||
return _context;
|
||||
}
|
||||
|
||||
public String getCanonicalContextPath()
|
||||
|
@ -68,28 +71,24 @@ public class ContextId
|
|||
|
||||
public String toString ()
|
||||
{
|
||||
return _node+"_"+_canonicalContextPath +"_"+_vhost;
|
||||
return _workerName+"_"+_canonicalContextPath +"_"+_vhost;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals (Object o)
|
||||
|
||||
/**
|
||||
* Run a runnable in the context (with context classloader set) if
|
||||
* there is one, otherwise just run it.
|
||||
* @param r
|
||||
*/
|
||||
public void run (Runnable r)
|
||||
{
|
||||
if (o == null)
|
||||
return false;
|
||||
|
||||
ContextId id = (ContextId)o;
|
||||
if (id.getNode().equals(getNode()) && id.getCanonicalContextPath().equals(getCanonicalContextPath()) && id.getVhost().equals(getVhost()))
|
||||
return true;
|
||||
return false;
|
||||
if (_context != null)
|
||||
_context.getContextHandler().handle(r);
|
||||
else
|
||||
r.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
return java.util.Objects.hash(getNode(), getCanonicalContextPath(), getVhost());
|
||||
}
|
||||
|
||||
public static String getContextPath (Context context)
|
||||
private String canonicalizeContextPath (Context context)
|
||||
{
|
||||
if (context == null)
|
||||
return "";
|
||||
|
@ -104,7 +103,7 @@ public class ContextId
|
|||
*
|
||||
* @return 0.0.0.0 if no virtual host is defined
|
||||
*/
|
||||
public static String getVirtualHost (Context context)
|
||||
private String canonicalizeVHost (Context context)
|
||||
{
|
||||
String vhost = NULL_VHOST;
|
||||
|
||||
|
@ -124,12 +123,12 @@ public class ContextId
|
|||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private static String canonicalize (String path)
|
||||
private String canonicalize (String path)
|
||||
{
|
||||
if (path==null)
|
||||
return "";
|
||||
|
||||
return path.replace('/', '_').replace('.','_').replace('\\','_');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -36,9 +36,9 @@ public interface SessionDataStore extends LifeCycle
|
|||
* given context. A SessionDataStore can only
|
||||
* be used by one context(/session manager).
|
||||
*
|
||||
* @param contextId
|
||||
* @param context
|
||||
*/
|
||||
void initialize(ContextId contextId);
|
||||
void initialize(SessionContext context);
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,154 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
//
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
//
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
//
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler.Context;
|
||||
|
||||
/**
|
||||
* SessionKey
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class SessionKey
|
||||
{
|
||||
public final static String NULL_VHOST = "0.0.0.0";
|
||||
private String _id;
|
||||
private String _canonicalContextPath;
|
||||
private String _vhost;
|
||||
|
||||
|
||||
public static SessionKey getKey (String id, Context context)
|
||||
{
|
||||
String cpath = getContextPath(context);
|
||||
String vhosts = getVirtualHost(context);
|
||||
return new SessionKey (id, cpath, vhosts);
|
||||
}
|
||||
|
||||
public static SessionKey getKey (SessionData data)
|
||||
{
|
||||
String cpath = canonicalize(data.getContextPath());
|
||||
String vhost = data.getVhost();
|
||||
if (vhost == null)
|
||||
vhost = NULL_VHOST;
|
||||
String id = data.getId();
|
||||
return new SessionKey(id, cpath, vhost);
|
||||
}
|
||||
|
||||
public static SessionKey getKey (String id, String path, String virtualHost)
|
||||
{
|
||||
String cpath = canonicalize(path);
|
||||
String vhost = NULL_VHOST;
|
||||
if (virtualHost != null && !("".equals(virtualHost)))
|
||||
vhost = virtualHost;
|
||||
|
||||
return new SessionKey(id, cpath, vhost);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
public String getId()
|
||||
{
|
||||
return _id;
|
||||
}
|
||||
|
||||
public String getCanonicalContextPath()
|
||||
{
|
||||
return _canonicalContextPath;
|
||||
}
|
||||
|
||||
public String getVhost()
|
||||
{
|
||||
return _vhost;
|
||||
}
|
||||
|
||||
public String toString ()
|
||||
{
|
||||
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)
|
||||
return "";
|
||||
return canonicalize (context.getContextPath());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the first virtual host for the context.
|
||||
*
|
||||
* Used to help identify the exact session/contextPath.
|
||||
*
|
||||
* @return 0.0.0.0 if no virtual host is defined
|
||||
*/
|
||||
public static String getVirtualHost (Context context)
|
||||
{
|
||||
String vhost = NULL_VHOST;
|
||||
|
||||
if (context==null)
|
||||
return vhost;
|
||||
|
||||
String [] vhosts = context.getContextHandler().getVirtualHosts();
|
||||
if (vhosts==null || vhosts.length==0 || vhosts[0]==null)
|
||||
return vhost;
|
||||
|
||||
return vhosts[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Make an acceptable name from a context path.
|
||||
*
|
||||
* @param path
|
||||
* @return
|
||||
*/
|
||||
private static String canonicalize (String path)
|
||||
{
|
||||
if (path==null)
|
||||
return "";
|
||||
|
||||
return path.replace('/', '_').replace('.','_').replace('\\','_');
|
||||
}
|
||||
}
|
|
@ -107,7 +107,7 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
|
||||
protected ClassLoader _loader;
|
||||
protected ContextHandler.Context _context;
|
||||
protected ContextId _contextId;
|
||||
protected SessionContext _sessionContext;
|
||||
protected String _sessionCookie=__DefaultSessionCookie;
|
||||
protected String _sessionIdPathParameterName = __DefaultSessionIdPathParameterName;
|
||||
protected String _sessionIdPathParameterNamePrefix =";"+ _sessionIdPathParameterName +"=";
|
||||
|
@ -302,13 +302,13 @@ public class SessionManager extends ContainerLifeCycle implements org.eclipse.je
|
|||
_checkingRemoteSessionIdEncoding=Boolean.parseBoolean(tmp);
|
||||
}
|
||||
|
||||
_contextId = ContextId.getContextId(_sessionIdManager.getWorkerName(), _context);
|
||||
_sessionContext = new SessionContext(_sessionIdManager.getWorkerName(), _context);
|
||||
|
||||
if (_sessionStore instanceof AbstractSessionStore)
|
||||
((AbstractSessionStore)_sessionStore).setSessionManager(this);
|
||||
|
||||
|
||||
_sessionStore.initialize(_contextId);
|
||||
_sessionStore.initialize(_sessionContext);
|
||||
_sessionStore.start();
|
||||
|
||||
super.doStart();
|
||||
|
|
|
@ -36,7 +36,7 @@ import org.eclipse.jetty.util.component.LifeCycle;
|
|||
*/
|
||||
public interface SessionStore extends LifeCycle
|
||||
{
|
||||
void initialize(ContextId contextId);
|
||||
void initialize(SessionContext context);
|
||||
Session newSession (HttpServletRequest request, String id, long time, long maxInactiveMs);
|
||||
Session get(String id, boolean staleCheck) throws Exception;
|
||||
void put(String id, Session session) throws Exception;
|
||||
|
|
|
@ -27,7 +27,7 @@ package org.eclipse.jetty.server.session;
|
|||
public class UnreadableSessionDataException extends Exception
|
||||
{
|
||||
private String _id;
|
||||
private ContextId _contextId;
|
||||
private SessionContext _sessionContext;
|
||||
|
||||
|
||||
public String getId()
|
||||
|
@ -35,23 +35,23 @@ public class UnreadableSessionDataException extends Exception
|
|||
return _id;
|
||||
}
|
||||
|
||||
public ContextId getContextId()
|
||||
public SessionContext getSessionContext()
|
||||
{
|
||||
return _contextId;
|
||||
return _sessionContext;
|
||||
}
|
||||
|
||||
|
||||
public UnreadableSessionDataException (String id, ContextId contextId, Throwable t)
|
||||
public UnreadableSessionDataException (String id, SessionContext contextId, Throwable t)
|
||||
{
|
||||
super ("Unreadable session "+id+" for "+contextId, t);
|
||||
_contextId = contextId;
|
||||
_sessionContext = contextId;
|
||||
_id = id;
|
||||
}
|
||||
|
||||
public UnreadableSessionDataException (String id, ContextId contextId, boolean loadAttemptsExhausted)
|
||||
public UnreadableSessionDataException (String id, SessionContext contextId, boolean loadAttemptsExhausted)
|
||||
{
|
||||
super("Unreadable session "+id+" for "+contextId+(loadAttemptsExhausted?" max load attempts":""));
|
||||
_contextId = contextId;
|
||||
_sessionContext = contextId;
|
||||
_id = id;
|
||||
}
|
||||
|
||||
|
|
|
@ -27,11 +27,11 @@ package org.eclipse.jetty.server.session;
|
|||
public class UnwriteableSessionDataException extends Exception
|
||||
{
|
||||
private String _id;
|
||||
private ContextId _contextId;
|
||||
private SessionContext _sessionContext;
|
||||
|
||||
|
||||
|
||||
public UnwriteableSessionDataException (String id, ContextId contextId, Throwable t)
|
||||
public UnwriteableSessionDataException (String id, SessionContext contextId, Throwable t)
|
||||
{
|
||||
super ("Unwriteable session "+id+" for "+contextId, t);
|
||||
_id = id;
|
||||
|
@ -42,8 +42,8 @@ public class UnwriteableSessionDataException extends Exception
|
|||
return _id;
|
||||
}
|
||||
|
||||
public ContextId getContextId()
|
||||
public SessionContext getSessionContext()
|
||||
{
|
||||
return _contextId;
|
||||
return _sessionContext;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,8 +105,7 @@ public class FileSessionManagerTest
|
|||
manager.getSessionDataStore().setStoreDir(testDir);
|
||||
manager.start();
|
||||
|
||||
//See SessionKey.getKey()
|
||||
String expectedFilename = "__0.0.0.0_validFile123";
|
||||
String expectedFilename = "_0.0.0.0_validFile123";
|
||||
|
||||
Assert.assertTrue(new File(testDir, expectedFilename).createNewFile());
|
||||
|
||||
|
@ -153,7 +152,7 @@ public class FileSessionManagerTest
|
|||
manager.setMaxInactiveInterval(30); // change max inactive interval for *new* sessions
|
||||
manager.stop();
|
||||
|
||||
String expectedFilename = "foo__0.0.0.0_"+session.getId();
|
||||
String expectedFilename = "_0.0.0.0_"+session.getId();
|
||||
Assert.assertTrue("File should exist!", new File(testDir, expectedFilename).exists());
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue