Jetty 9.4.x 2231 refactor session tests (#2382)

* Issue #2231 WIP

* Issue #2231 Add tests for FileSessionDataStore and MongoSessionDataStore.

* Issue #2231 create unit tests for every SessionDataStore

Signed-off-by: Jan Bartel <janb@webtide.com>

* Issue #2231 Refactor session tests

Signed-off-by: Jan Bartel <janb@webtide.com>

* Issue #2231 Refactor and cleanup session tests.

Signed-off-by: Jan Bartel <janb@webtide.com>

* hazelcast tests faster

Signed-off-by: olivier lamy <olamy@webtide.com>

* make hazelcasts tests even faster

Signed-off-by: olivier lamy <olamy@webtide.com>

* cleanup comments

Signed-off-by: olivier lamy <olamy@webtide.com>

* run mongodb test in embdedded mode

Signed-off-by: olivier lamy <olamy@webtide.com>

* mongodb embedded test enabled per default

Signed-off-by: olivier lamy <olamy@webtide.com>

* Issue #2231 more session tests

Signed-off-by: Jan Bartel <janb@webtide.com>

* fix mongodb embedded tests

Signed-off-by: olivier lamy <olamy@webtide.com>

* cleanup code

Signed-off-by: olivier lamy <olamy@webtide.com>

* use Logger rather than System.err.println

Signed-off-by: olivier lamy <olamy@webtide.com>

* Issue #2231 Add test for DefaultSessionCache

Signed-off-by: Jan Bartel <janb@webtide.com>

* Issue #2231 Redisable mongo tests by default.

Signed-off-by: Jan Bartel <janb@webtide.com>

* fix issue with empty local repo build

Signed-off-by: olivier lamy <oliver.lamy@gmail.com>

* jenkins should run mongodb tests

Signed-off-by: olivier lamy <oliver.lamy@gmail.com>

* build this plugin last so we should not hit the maven invoker plugin

Signed-off-by: olivier lamy <oliver.lamy@gmail.com>

* build test first for this one

Signed-off-by: olivier lamy <oliver.lamy@gmail.com>

* use invoker plugin 3.0.2-SNAPSHOT as there is a fix for https://issues.apache.org/jira/browse/MINVOKER-191

Signed-off-by: olivier lamy <oliver.lamy@gmail.com>

* temporary use of apache snapshots repository because of maven-invoker-plugin 3.0.2-SNAPSHOT

Signed-off-by: olivier lamy <oliver.lamy@gmail.com>
This commit is contained in:
Jan Bartel 2018-03-28 21:14:15 +11:00 committed by Olivier Lamy
parent a28ec963d1
commit b4e400f236
133 changed files with 4809 additions and 6087 deletions

2
Jenkinsfile vendored
View File

@ -89,7 +89,7 @@ def getFullBuild(jdk, os) {
globalMavenSettingsConfig: 'oss-settings.xml',
mavenLocalRepo: "${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}") {
//
sh "mvn -V -B install -Dmaven.test.failure.ignore=true -Prun-its -T3 -e -Dmaven.repo.local=${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER}"
sh "mvn -V -B install -Dmaven.test.failure.ignore=true -Prun-its -T3 -e -Dmaven.repo.local=${env.JENKINS_HOME}/${env.EXECUTOR_NUMBER} -Pmongodb"
}
// withMaven doesn't label..
// Report failures in the jenkins UI

View File

@ -510,16 +510,22 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
{
if (LOG.isDebugEnabled()) LOG.debug("Loading session {} from DataStore", id);
Entity entity = _datastore.get(makeKey(id, _context));
if (entity == null)
try
{
if (LOG.isDebugEnabled()) LOG.debug("No session {} in DataStore ", id);
return null;
Entity entity = _datastore.get(makeKey(id, _context));
if (entity == null)
{
if (LOG.isDebugEnabled()) LOG.debug("No session {} in DataStore ", id);
return null;
}
else
{
return sessionFromEntity(entity);
}
}
else
catch (Exception e)
{
SessionData data = sessionFromEntity(entity);
return data;
throw new UnreadableSessionDataException(id, _context, e);
}
}
@ -706,7 +712,10 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
Query<ProjectionEntity> query = Query.newProjectionEntityQueryBuilder()
.setKind(_model.getKind())
.setProjection(_model.getExpiry())
.setFilter(PropertyFilter.eq(_model.getId(), id))
.setFilter(CompositeFilter.and(PropertyFilter.eq(_model.getId(), id),
PropertyFilter.eq(_model.getContextPath(), _context.getCanonicalContextPath()),
PropertyFilter.eq(_model.getVhost(), _context.getVhost())))
//.setFilter(PropertyFilter.eq(_model.getId(), id))
.build();
QueryResults<ProjectionEntity> presults;
@ -731,7 +740,10 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
{
Query<Entity> query = Query.newEntityQueryBuilder()
.setKind(_model.getKind())
.setFilter(PropertyFilter.eq(_model.getId(), id))
.setFilter(CompositeFilter.and(PropertyFilter.eq(_model.getId(), id),
PropertyFilter.eq(_model.getContextPath(), _context.getCanonicalContextPath()),
PropertyFilter.eq(_model.getVhost(), _context.getVhost())))
//.setFilter(PropertyFilter.eq(_model.getId(), id))
.build();
QueryResults<Entity> results;
@ -912,8 +924,8 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
if (entity == null)
return null;
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
final AtomicReference<SessionData> reference = new AtomicReference<>();
final AtomicReference<Exception> exception = new AtomicReference<>();
Runnable load = new Runnable()
{
@Override
@ -975,7 +987,9 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
_context.run(load);
if (exception.get() != null)
{
throw exception.get();
}
return reference.get();
}

View File

@ -23,6 +23,7 @@ import org.eclipse.jetty.server.session.AbstractSessionDataStore;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.server.session.UnreadableSessionDataException;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -55,23 +56,22 @@ public class HazelcastSessionDataStore
throws Exception
{
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
final AtomicReference<SessionData> reference = new AtomicReference<>();
final AtomicReference<Exception> exception = new AtomicReference<>();
//ensure the load runs in the context classloader scope
_context.run( () -> {
try
{
if (LOG.isDebugEnabled())
{
LOG.debug( "Loading session {} from hazelcast", id );
}
SessionData sd = sessionDataMap.get( getCacheKey( id ) );
reference.set(sd);
}
catch (Exception e)
{
exception.set(e);
exception.set(new UnreadableSessionDataException(id, _context, e));
}
} );
@ -126,12 +126,13 @@ public class HazelcastSessionDataStore
{
return Collections.emptySet();
}
long now = System.currentTimeMillis();
return candidates.stream().filter( candidate -> {
if (LOG.isDebugEnabled())
{
LOG.debug( "Checking expiry for candidate {}", candidate );
}
try
{
SessionData sd = load(candidate);
@ -193,9 +194,17 @@ public class HazelcastSessionDataStore
@Override
public boolean exists( String id )
throws Exception
throws Exception
{
return this.sessionDataMap.containsKey( getCacheKey( id ) );
//TODO find way to do query without pulling in whole session data
SessionData sd = load(id);
if (sd == null)
return false;
if (sd.getExpiry() <= 0)
return true; //never expires
else
return (Boolean.valueOf(sd.getExpiry() > System.currentTimeMillis())); //not expired yet
}
public String getCacheKey( String id )

View File

@ -24,9 +24,9 @@ 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.SessionData;
import org.eclipse.jetty.server.session.UnreadableSessionDataException;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
@ -84,8 +84,8 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
@Override
public SessionData load(String id) throws Exception
{
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
final AtomicReference<SessionData> reference = new AtomicReference<>();
final AtomicReference<Exception> exception = new AtomicReference<>();
Runnable load = new Runnable()
{
@ -103,7 +103,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
}
catch (Exception e)
{
exception.set(e);
exception.set(new UnreadableSessionDataException(id, _context, e));
}
}
};
@ -139,11 +139,10 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
long now = System.currentTimeMillis();
Set<String> expired = new HashSet<String>();
Set<String> expired = new HashSet<>();
//TODO if there is NOT an idle timeout set on entries in infinispan, need to check other sessions
//that are not currently in the SessionDataStore (eg they've been passivated)
//that are not currently in the SessionDataStore (eg they've been passivated)
for (String candidate:candidates)
{
if (LOG.isDebugEnabled())
@ -205,8 +204,6 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
try
{
//Put an idle timeout on the cache entry if the session is not immortal -
//if no requests arrive at any node before this timeout occurs, or no node
//scavenges the session before this timeout occurs, the session will be removed.
@ -218,10 +215,6 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
if (LOG.isDebugEnabled())
LOG.debug("Session {} saved to infinispan, expires {} ", id, data.getExpiry());
} catch (Exception e)
{
e.printStackTrace();
}
}
@ -265,8 +258,8 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
{
// TODO find a better way to do this that does not pull into memory the
// whole session object
final AtomicReference<Boolean> reference = new AtomicReference<Boolean>();
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
final AtomicReference<Boolean> reference = new AtomicReference<>();
final AtomicReference<Exception> exception = new AtomicReference<>();
Runnable load = new Runnable()
{

View File

@ -78,35 +78,6 @@
<artifactId>ant</artifactId>
<version>1.8.4</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>apache-jstl</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-servlets</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-proxy</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<reporting>
<plugins>

View File

@ -148,24 +148,6 @@
<artifactId>javax.transaction-api</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-client</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.http2</groupId>
<artifactId>http2-http-client-transport</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-home</artifactId>

View File

@ -37,12 +37,13 @@ public abstract class NoSqlSessionDataStore extends AbstractSessionDataStore
public class NoSqlSessionData extends SessionData
{
private Object _version;
private Set<String> _dirtyAttributes = new HashSet<String>();
private Set<String> _dirtyAttributes = new HashSet<>();
public NoSqlSessionData(String id, String cpath, String vhost, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
super(id, cpath, vhost, created, accessed, lastAccessed, maxInactiveMs);
setVersion (new Long(0));
}
public void setVersion (Object v)

View File

@ -19,6 +19,20 @@
package org.eclipse.jetty.nosql.mongodb;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.UnreadableSessionDataException;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.BasicDBObjectBuilder;
@ -29,26 +43,6 @@ import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import com.mongodb.WriteResult;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* MongoSessionDataStore
*
@ -108,12 +102,12 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
/**
* Special attribute for a session that is context-specific
*/
private final static String __METADATA = "__metadata__";
public final static String __METADATA = "__metadata__";
/**
* Name of nested document field containing 1 sub document per context for which the session id is in use
*/
private final static String __CONTEXT = "context";
public final static String __CONTEXT = "context";
/**
* Special attribute per session per context, incremented each time attributes are modified
@ -131,6 +125,9 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
*/
public final static String __ACCESSED = "accessed";
public final static String __LAST_ACCESSED = "lastAccessed";
/**
* Time this session will expire, based on last access time and maxIdle
*/
@ -144,7 +141,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
/**
* Time of session creation
*/
private final static String __CREATED = "created";
public final static String __CREATED = "created";
/**
* Whether or not session is valid
@ -188,8 +185,8 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
@Override
public SessionData load(String id) throws Exception
{
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
final AtomicReference<SessionData> reference = new AtomicReference<>();
final AtomicReference<Exception> exception = new AtomicReference<>();
Runnable r = new Runnable()
{
@Override
@ -212,19 +209,20 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
if (valid == null || !valid)
return;
Object version = getNestedValue(sessionDocument, getContextSubfield(__VERSION));
Long lastSaved = (Long)getNestedValue(sessionDocument, getContextSubfield(__LASTSAVED));
String lastNode = (String)getNestedValue(sessionDocument, getContextSubfield(__LASTNODE));
Object version = MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__VERSION));
Long lastSaved = (Long)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTSAVED));
String lastNode = (String)MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__LASTNODE));
Long created = (Long)sessionDocument.get(__CREATED);
Long accessed = (Long)sessionDocument.get(__ACCESSED);
Long lastAccessed = (Long)sessionDocument.get(__LAST_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());
DBObject sessionSubDocumentForContext = (DBObject)MongoUtils.getNestedValue(sessionDocument,getContextField());
if (LOG.isDebugEnabled()) LOG.debug("attrs {}", sessionSubDocumentForContext);
@ -234,7 +232,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
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 = (NoSqlSessionData)newSessionData(id, created, accessed, (lastAccessed == null? accessed:lastAccessed), maxInactive);
data.setVersion(version);
data.setExpiry(expiry);
data.setContextPath(_context.getCanonicalContextPath());
@ -248,8 +246,8 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
//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));
String attr = MongoUtils.decodeName(name);
Object value = MongoUtils.decodeValue(sessionSubDocumentForContext.get(name));
attributes.put(attr,value);
}
@ -265,7 +263,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
catch (Exception e)
{
exception.set(e);
exception.set(new UnreadableSessionDataException(id, _context, e));
}
}
};
@ -298,7 +296,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
if (sessionDocument != null)
{
DBObject c = (DBObject)getNestedValue(sessionDocument, __CONTEXT);
DBObject c = (DBObject)MongoUtils.getNestedValue(sessionDocument, __CONTEXT);
if (c == null)
{
//delete whole doc
@ -326,7 +324,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
BasicDBObject unsets = new BasicDBObject();
unsets.put(getContextField(),1);
remove.put("$unset",unsets);
WriteResult result = _dbSessions.update(mongoKey,remove,false,false,WriteConcern.SAFE);
_dbSessions.update(mongoKey,remove,false,false,WriteConcern.SAFE);
return true;
}
else
@ -347,6 +345,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
DBObject fields = new BasicDBObject();
fields.put(__EXPIRY, 1);
fields.put(__VALID, 1);
fields.put(getContextSubfield(__VERSION), 1);
DBObject sessionDocument = _dbSessions.findOne(new BasicDBObject(__ID, id), fields);
@ -359,9 +358,16 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
Long expiry = (Long)sessionDocument.get(__EXPIRY);
if (expiry.longValue() <= 0)
return true; //never expires, its good
return (expiry.longValue() > System.currentTimeMillis()); //expires later
//expired?
if (expiry.longValue() > 0 && expiry.longValue() < System.currentTimeMillis())
return false; //it's expired
//does it exist for this context?
Object version = MongoUtils.getNestedValue(sessionDocument, getContextSubfield(__VERSION));
if (version == null)
return false;
return true;
}
@ -425,24 +431,51 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
if (LOG.isDebugEnabled()) LOG.debug("{} Mongo found old expired session {}", _context, id+" exp="+session.get(__EXPIRY));
expiredSessions.add(id);
}
}
finally
{
oldExpiredSessions.close();
if (oldExpiredSessions != null)
oldExpiredSessions.close();
}
//check through sessions that were candidates, but not found as expired.
//they may no longer be persisted, in which case they are treated as expired.
for (String c:candidates)
{
if (!expiredSessions.contains(c))
{
try
{
if (!exists(c))
expiredSessions.add(c);
}
catch (Exception e)
{
LOG.warn("Problem checking potentially expired session {}", c, e);
}
}
}
return expiredSessions;
}
/**
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#initialize(org.eclipse.jetty.server.session.SessionContext)
*/
public void initialize (SessionContext context) throws Exception
{
if (isStarted())
throw new IllegalStateException("Context set after SessionDataStore started");
_context = context;
ensureIndexes();
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
NoSqlSessionData nsqd = (NoSqlSessionData)data;
{
// Form query for upsert
BasicDBObject key = new BasicDBObject(__ID, id);
@ -459,21 +492,21 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
{
upsert = true;
version = new Long(1);
sets.put(__CREATED,nsqd.getCreated());
sets.put(__CREATED,data.getCreated());
sets.put(__VALID,true);
sets.put(getContextSubfield(__VERSION),version);
sets.put(getContextSubfield(__LASTSAVED), data.getLastSaved());
sets.put(getContextSubfield(__LASTNODE), data.getLastNode());
sets.put(__MAX_IDLE, nsqd.getMaxInactiveMs());
sets.put(__EXPIRY, nsqd.getExpiry());
nsqd.setVersion(version);
sets.put(__MAX_IDLE, data.getMaxInactiveMs());
sets.put(__EXPIRY, data.getExpiry());
((NoSqlSessionData)data).setVersion(version);
}
else
{
sets.put(getContextSubfield(__LASTSAVED), data.getLastSaved());
sets.put(getContextSubfield(__LASTNODE), data.getLastNode());
version = new Long(((Number)version).longValue() + 1);
nsqd.setVersion(version);
((NoSqlSessionData)data).setVersion(version);
update.put("$inc",_version_1);
//if max idle time and/or expiry is smaller for this context, then choose that for the whole session doc
BasicDBObject fields = new BasicDBObject();
@ -487,23 +520,24 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
tmpLong = (Long)o.get(__EXPIRY);
long currentExpiry = (tmpLong == null? 0 : tmpLong.longValue());
if (currentMaxIdle != nsqd.getMaxInactiveMs())
sets.put(__MAX_IDLE, nsqd.getMaxInactiveMs());
if (currentMaxIdle != data.getMaxInactiveMs())
sets.put(__MAX_IDLE, data.getMaxInactiveMs());
if (currentExpiry != nsqd.getExpiry())
sets.put(__EXPIRY, nsqd.getExpiry());
if (currentExpiry != data.getExpiry())
sets.put(__EXPIRY, data.getExpiry());
}
else
LOG.warn("Session {} not found, can't update", id);
}
sets.put(__ACCESSED, nsqd.getAccessed());
sets.put(__ACCESSED, data.getAccessed());
sets.put(__LAST_ACCESSED, data.getLastAccessed());
Set<String> names = nsqd.takeDirtyAttributes();
Set<String> names = ((NoSqlSessionData)data).takeDirtyAttributes();
if (lastSaveTime <= 0)
{
names.addAll(nsqd.getAllAttributeNames()); // note dirty may include removed names
names.addAll(((NoSqlSessionData)data).getAllAttributeNames()); // note dirty may include removed names
}
@ -511,9 +545,9 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
{
Object value = data.getAttribute(name);
if (value == null)
unsets.put(getContextField() + "." + encodeName(name),1);
unsets.put(getContextField() + "." + MongoUtils.encodeName(name),1);
else
sets.put(getContextField() + "." + encodeName(name),encodeName(value));
sets.put(getContextField() + "." + MongoUtils.encodeName(name), MongoUtils.encodeName(value));
}
// Do the upsert
@ -521,37 +555,16 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
update.put("$set",sets);
if (!unsets.isEmpty())
update.put("$unset",unsets);
WriteResult res = _dbSessions.update(key,update,upsert,false,WriteConcern.SAFE);
if (LOG.isDebugEnabled())
LOG.debug("Save:db.sessions.update( {}, {},{} )", key, update, res);
}
@Override
protected void doStart() throws Exception
{
if (_dbSessions == null)
throw new IllegalStateException("DBCollection not set");
_version_1 = new BasicDBObject(getContextSubfield(__VERSION),1);
ensureIndexes();
super.doStart();
}
@Override
protected void doStop() throws Exception
{
super.doStop();
}
protected void ensureIndexes() throws MongoException
{
DBObject idKey = BasicDBObjectBuilder.start().add("id", 1).get();
_version_1 = new BasicDBObject(getContextSubfield(__VERSION),1);
DBObject idKey = BasicDBObjectBuilder.start().add("id", 1).get();
_dbSessions.createIndex(idKey,
BasicDBObjectBuilder.start()
.add("name", "id_1")
@ -560,16 +573,19 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
.add("unique", true)
.get());
DBObject versionKey = BasicDBObjectBuilder.start().add("id", 1).add("version", 1).get();
DBObject versionKey = BasicDBObjectBuilder.start().add("id", 1).add("version", 1).get();
_dbSessions.createIndex(versionKey, BasicDBObjectBuilder.start()
.add("name", "id_1_version_1")
.add("ns", _dbSessions.getFullName())
.add("sparse", false)
.add("unique", true)
.get());
LOG.debug( "done ensure Mongodb indexes existing" );
//TODO perhaps index on expiry time?
}
/*------------------------------------------------------------ */
private String getContextField ()
{
@ -597,105 +613,6 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
/*------------------------------------------------------------ */
protected Object decodeValue(final Object valueToDecode) throws IOException, ClassNotFoundException
{
if (valueToDecode == null || valueToDecode instanceof Number || valueToDecode instanceof String || valueToDecode instanceof Boolean || valueToDecode instanceof Date)
{
return valueToDecode;
}
else if (valueToDecode instanceof byte[])
{
final byte[] decodeObject = (byte[])valueToDecode;
final ByteArrayInputStream bais = new ByteArrayInputStream(decodeObject);
final ClassLoadingObjectInputStream objectInputStream = new ClassLoadingObjectInputStream(bais);
return objectInputStream.readUnshared();
}
else if (valueToDecode instanceof DBObject)
{
Map<String, Object> map = new HashMap<String, Object>();
for (String name : ((DBObject)valueToDecode).keySet())
{
String attr = decodeName(name);
map.put(attr,decodeValue(((DBObject)valueToDecode).get(name)));
}
return map;
}
else
{
throw new IllegalStateException(valueToDecode.getClass().toString());
}
}
/*------------------------------------------------------------ */
protected String decodeName(String name)
{
return name.replace("%2E",".").replace("%25","%");
}
/*------------------------------------------------------------ */
protected String encodeName(String name)
{
return name.replace("%","%25").replace(".","%2E");
}
/*------------------------------------------------------------ */
protected Object encodeName(Object value) throws IOException
{
if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof Date)
{
return value;
}
else if (value.getClass().equals(HashMap.class))
{
BasicDBObject o = new BasicDBObject();
for (Map.Entry<?, ?> entry : ((Map<?, ?>)value).entrySet())
{
if (!(entry.getKey() instanceof String))
{
o = null;
break;
}
o.append(encodeName(entry.getKey().toString()),encodeName(entry.getValue()));
}
if (o != null)
return o;
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
out.reset();
out.writeUnshared(value);
out.flush();
return bout.toByteArray();
}
/*------------------------------------------------------------ */
/**
* Dig through a given dbObject for the nested value
*/
private Object getNestedValue(DBObject dbObject, String nestedKey)
{
String[] keyChain = nestedKey.split("\\.");
DBObject temp = dbObject;
for (int i = 0; i < keyChain.length - 1; ++i)
{
temp = (DBObject)temp.get(keyChain[i]);
if ( temp == null )
{
return null;
}
}
return temp.get(keyChain[keyChain.length - 1]);
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
*/

View File

@ -149,4 +149,6 @@ public class MongoSessionDataStoreFactory extends AbstractSessionDataStoreFactor
return store;
}
}

View File

@ -0,0 +1,150 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import com.mongodb.BasicDBObject;
import com.mongodb.DBObject;
/**
* MongoUtils
*
* Some utility methods for manipulating mongo data. This class facilitates testing.
*
*/
public class MongoUtils
{
public static Object decodeValue(final Object valueToDecode) throws IOException, ClassNotFoundException
{
if (valueToDecode == null || valueToDecode instanceof Number || valueToDecode instanceof String || valueToDecode instanceof Boolean || valueToDecode instanceof Date)
{
return valueToDecode;
}
else if (valueToDecode instanceof byte[])
{
final byte[] decodeObject = (byte[])valueToDecode;
final ByteArrayInputStream bais = new ByteArrayInputStream(decodeObject);
final ClassLoadingObjectInputStream objectInputStream = new ClassLoadingObjectInputStream(bais);
return objectInputStream.readUnshared();
}
else if (valueToDecode instanceof DBObject)
{
Map<String, Object> map = new HashMap<String, Object>();
for (String name : ((DBObject)valueToDecode).keySet())
{
String attr = decodeName(name);
map.put(attr,decodeValue(((DBObject)valueToDecode).get(name)));
}
return map;
}
else
{
throw new IllegalStateException(valueToDecode.getClass().toString());
}
}
public static String decodeName(String name)
{
return name.replace("%2E",".").replace("%25","%");
}
public static String encodeName(String name)
{
return name.replace("%","%25").replace(".","%2E");
}
public static Object encodeName(Object value) throws IOException
{
if (value instanceof Number || value instanceof String || value instanceof Boolean || value instanceof Date)
{
return value;
}
else if (value.getClass().equals(HashMap.class))
{
BasicDBObject o = new BasicDBObject();
for (Map.Entry<?, ?> entry : ((Map<?, ?>)value).entrySet())
{
if (!(entry.getKey() instanceof String))
{
o = null;
break;
}
o.append(encodeName(entry.getKey().toString()),encodeName(entry.getValue()));
}
if (o != null)
return o;
}
ByteArrayOutputStream bout = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(bout);
out.reset();
out.writeUnshared(value);
out.flush();
return bout.toByteArray();
}
/**
* Dig through a given dbObject for the nested value
*
* @param dbObject the mongo object to search
* @param nestedKey the field key to find
*
* @return the value of the field key
*/
public static Object getNestedValue(DBObject dbObject, String nestedKey)
{
String[] keyChain = nestedKey.split("\\.");
DBObject temp = dbObject;
for (int i = 0; i < keyChain.length - 1; ++i)
{
temp = (DBObject)temp.get(keyChain[i]);
if ( temp == null )
{
return null;
}
}
return temp.get(keyChain[keyChain.length - 1]);
}
}

View File

@ -25,7 +25,6 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;

View File

@ -44,7 +44,7 @@ public class DefaultSessionCache extends AbstractSessionCache
/**
* The cache of sessions in a hashmap
*/
protected ConcurrentHashMap<String, Session> _sessions = new ConcurrentHashMap<String, Session>();
protected ConcurrentHashMap<String, Session> _sessions = new ConcurrentHashMap<>();
private final CounterStatistic _stats = new CounterStatistic();

View File

@ -29,7 +29,6 @@ import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;

View File

@ -30,9 +30,7 @@ import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.nio.file.FileVisitOption;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.Path;
import java.nio.file.attribute.FileTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
@ -264,12 +262,19 @@ public class FileSessionDataStore extends AbstractSessionDataStore
if (p == null)
return;
long expiry = getExpiryFromFilename(p.getFileName().toString());
//files with 0 expiry never expire
if (expiry >0 && ((now - expiry) >= (5*TimeUnit.SECONDS.toMillis(_gracePeriodSec))))
try
{
Files.deleteIfExists(p);
if (LOG.isDebugEnabled()) LOG.debug("Sweep deleted {}", p.getFileName());
long expiry = getExpiryFromFilename(p.getFileName().toString());
//files with 0 expiry never expire
if (expiry >0 && ((now - expiry) >= (5*TimeUnit.SECONDS.toMillis(_gracePeriodSec))))
{
Files.deleteIfExists(p);
if (LOG.isDebugEnabled()) LOG.debug("Sweep deleted {}", p.getFileName());
}
}
catch (NumberFormatException e)
{
LOG.warn("Not valid session filename {}", p.getFileName(), e);
}
}
@ -293,7 +298,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
if (filename == null)
{
if (LOG.isDebugEnabled())
LOG.debug("Unknown file {}",filename);
LOG.debug("Unknown file {}",idWithContext);
return;
}
File file = new File (_storeDir, filename);
@ -542,7 +547,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
* @param id identity of session
* @return the session id plus context
*/
private String getIdWithContext (String id)
protected String getIdWithContext (String id)
{
return _contextString+"_"+id;
}
@ -552,13 +557,13 @@ public class FileSessionDataStore extends AbstractSessionDataStore
* @param data
* @return the session id plus context and expiry
*/
private String getIdWithContextAndExpiry (SessionData data)
protected String getIdWithContextAndExpiry (SessionData data)
{
return ""+data.getExpiry()+"_"+getIdWithContext(data.getId());
}
private String getIdFromFilename (String filename)
protected String getIdFromFilename (String filename)
{
if (filename == null)
return null;
@ -567,7 +572,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
private long getExpiryFromFilename (String filename)
protected long getExpiryFromFilename (String filename)
{
if (StringUtil.isBlank(filename) || filename.indexOf("_") < 0)
throw new IllegalStateException ("Invalid or missing filename");
@ -577,7 +582,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
}
private String getContextFromFilename (String filename)
protected String getContextFromFilename (String filename)
{
if (StringUtil.isBlank(filename))
return null;
@ -593,7 +598,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
* @param filename the name of the file to use
* @return the session id plus context
*/
private String getIdWithContextFromFilename (String filename)
protected String getIdWithContextFromFilename (String filename)
{
if (StringUtil.isBlank(filename) || filename.indexOf('_') < 0)
return null;
@ -607,7 +612,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
* @param filename the filename to check
* @return true if the filename has the correct filename format
*/
private boolean isSessionFilename (String filename)
protected boolean isSessionFilename (String filename)
{
if (StringUtil.isBlank(filename))
return false;
@ -626,7 +631,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
* @param filename the filename to check
* @return true if the filename has the correct filename format and is for this context
*/
private boolean isOurContextSessionFilename (String filename)
protected boolean isOurContextSessionFilename (String filename)
{
if (StringUtil.isBlank(filename))
return false;

View File

@ -146,7 +146,7 @@ public class HouseKeeper extends AbstractLifeCycle
_task.cancel();
if (_runner == null)
_runner = new Runner();
LOG.info("Scavenging every {}ms", _intervalMs);
LOG.info("{} Scavenging every {}ms", _sessionIdManager.getWorkerName(), _intervalMs);
_task = _scheduler.schedule(_runner,_intervalMs,TimeUnit.MILLISECONDS);
}
}
@ -164,7 +164,7 @@ public class HouseKeeper extends AbstractLifeCycle
if (_task!=null)
{
_task.cancel();
LOG.info("Stopped scavenging");
LOG.info("{} Stopped scavenging", _sessionIdManager.getWorkerName());
}
_task = null;
if (_ownScheduler)
@ -204,13 +204,13 @@ public class HouseKeeper extends AbstractLifeCycle
if (sec <= 0)
{
_intervalMs = 0L;
LOG.info("Scavenging disabled");
LOG.info("{} Scavenging disabled", _sessionIdManager.getWorkerName());
stopScavenging();
}
else
{
if (sec < 10)
LOG.warn("Short interval of {}sec for session scavenging.", sec);
LOG.warn("{} Short interval of {}sec for session scavenging.", _sessionIdManager.getWorkerName(), sec);
_intervalMs=sec*1000L;
@ -261,7 +261,7 @@ public class HouseKeeper extends AbstractLifeCycle
return;
if (LOG.isDebugEnabled())
LOG.debug("{} scavenging sessions", this);
LOG.debug("{} scavenging sessions", _sessionIdManager.getWorkerName());
//find the session managers
for (SessionHandler manager:_sessionIdManager.getSessionHandlers())

View File

@ -816,7 +816,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
public Set<String> doGetExpired(Set<String> candidates)
{
if (LOG.isDebugEnabled())
LOG.debug("Getting expired sessions "+System.currentTimeMillis());
LOG.debug("Getting expired sessions at time {}", System.currentTimeMillis());
long now = System.currentTimeMillis();
@ -830,7 +830,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
*/
long upperBound = now;
if (LOG.isDebugEnabled())
LOG.debug ("{}- Pass 1: Searching for sessions for context {} managed by me {} and expired before {}", _context.getCanonicalContextPath(), _context.getWorkerName(), upperBound);
LOG.debug ("{}- Pass 1: Searching for sessions for context {} managed by me and expired before {}", _context.getWorkerName(), _context.getCanonicalContextPath(),upperBound);
try (PreparedStatement statement = _sessionTableSchema.getExpiredSessionsStatement(connection, _context.getCanonicalContextPath(), _context.getVhost(), upperBound))
{
@ -905,7 +905,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
}
catch (Exception e)
{
LOG.warn("Problem checking if potentially expired session {} exists in db", k,e);
LOG.warn("{} Problem checking if potentially expired session {} exists in db", _context.getWorkerName(), k,e);
}
}

View File

@ -372,9 +372,7 @@ public class SessionData implements Serializable
return (getExpiry() <= time);
}
/**
* @see java.lang.Object#toString()
*/
@Override
public String toString()
{

View File

@ -21,8 +21,6 @@ package org.eclipse.jetty.server.session;
import java.util.Set;
import org.eclipse.jetty.util.component.LifeCycle;
/**
* SessionDataStore
*
@ -68,10 +66,10 @@ public interface SessionDataStore extends SessionDataMap
/**
* Test if data exists for a given session id.
*
* @param id Identity of session whose existance should be checked
* @param id Identity of session whose existence should be checked
*
* @return true if valid, non-expired session exists
* @throws Exception if problem checking existance with persistence layer
* @throws Exception if problem checking existence with persistence layer
*/
public boolean exists (String id) throws Exception;

View File

@ -222,9 +222,9 @@ public class SessionHandler extends ScopedHandler
protected boolean _secureCookies=false;
protected boolean _secureRequestOnly=true;
protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<HttpSessionAttributeListener>();
protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<HttpSessionListener>();
protected final List<HttpSessionIdListener> _sessionIdListeners = new CopyOnWriteArrayList<HttpSessionIdListener>();
protected final List<HttpSessionAttributeListener> _sessionAttributeListeners = new CopyOnWriteArrayList<>();
protected final List<HttpSessionListener> _sessionListeners= new CopyOnWriteArrayList<>();
protected final List<HttpSessionIdListener> _sessionIdListeners = new CopyOnWriteArrayList<>();
protected ClassLoader _loader;
protected ContextHandler.Context _context;

View File

@ -1,421 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import java.io.File;
import java.io.FilenameFilter;
import java.util.Collections;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.toolchain.test.FS;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.IO;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.StdErrLog;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
public class FileSessionManagerTest
{
public static final long ONE_DAY = (1000L*60L*60L*24L);
private static StdErrLog _log;
private static boolean _stacks;
@BeforeClass
public static void beforeClass ()
{
_log = ((StdErrLog)Log.getLogger("org.eclipse.jetty.server.session"));
_stacks = _log.isHideStacks();
_log.setHideStacks(true);
}
@AfterClass
public static void afterClass()
{
_log.setHideStacks(_stacks);
}
@After
public void after()
{
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
if (testDir.exists())
FS.ensureEmpty(testDir);
}
@Test
public void testDangerousSessionIdRemoval() throws Exception
{
String expectedFilename = "_0.0.0.0_dangerFile";
File targetFile = MavenTestingUtils.getTargetFile(expectedFilename);
try
{
Server server = new Server();
SessionHandler handler = new SessionHandler();
handler.setServer(server);
final DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server);
idmgr.setServer(server);
server.setSessionIdManager(idmgr);
FileSessionDataStore ds = new FileSessionDataStore();
ds.setDeleteUnrestorableFiles(true);
DefaultSessionCache ss = new DefaultSessionCache(handler);
handler.setSessionCache(ss);
ss.setSessionDataStore(ds);
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
FS.ensureEmpty(testDir);
ds.setStoreDir(testDir);
handler.setSessionIdManager(idmgr);
handler.start();
//Create a file that is in the parent dir of the session storeDir
targetFile.createNewFile();
Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile(expectedFilename).exists());
//Verify that passing in a relative filename outside of the storedir does not lead
//to deletion of file (needs deleteUnrecoverableFiles(true))
Session session = handler.getSession("../_0.0.0.0_dangerFile");
Assert.assertTrue(session == null);
Assert.assertTrue("File should exist!", MavenTestingUtils.getTargetFile(expectedFilename).exists());
}
finally
{
if (targetFile.exists())
IO.delete(targetFile);
}
}
/**
* When starting the filestore, check that really old expired
* files are deleted irrespective of context session belongs to.
*
* @throws Exception
*/
@Test
public void testDeleteOfOlderFiles() throws Exception
{
Server server = new Server();
SessionHandler handler = new SessionHandler();
handler.setServer(server);
final DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server);
idmgr.setServer(server);
server.setSessionIdManager(idmgr);
FileSessionDataStore ds = new FileSessionDataStore();
ds.setDeleteUnrestorableFiles(false); //turn off deletion of unreadable session files
DefaultSessionCache ss = new DefaultSessionCache(handler);
handler.setSessionCache(ss);
ss.setSessionDataStore(ds);
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
FS.ensureEmpty(testDir);
ds.setStoreDir(testDir);
//create a really old file for session abc
String name1 = "100__0.0.0.0_abc";
File f1 = new File(testDir, name1);
if (f1.exists())
Assert.assertTrue(f1.delete());
f1.createNewFile();
//create another really old file for session abc
Thread.sleep(1100);
String name2 = "101__0.0.0.0_abc";
File f2 = new File(testDir, name2);
if (f2.exists())
Assert.assertTrue(f2.delete());
f2.createNewFile();
//make one file for session abc that should not have expired
Thread.sleep(1100);
long exp = System.currentTimeMillis() + ONE_DAY;
String name3 = Long.toString(exp)+"__0.0.0.0_abc";
File f3 = new File(testDir, name3);
if (f3.exists())
Assert.assertTrue(f3.delete());
f3.createNewFile();
//make a file that is for a different context
//that expired a long time ago - should be
//removed by sweep on startup
Thread.sleep(1100);
String name4 = "1099_foo_0.0.0.0_abc";
File f4 = new File(testDir, name4);
if (f4.exists())
Assert.assertTrue(f4.delete());
f4.createNewFile();
//make a file that is for a different context
//that should not have expired - ensure it is
//not removed
exp = System.currentTimeMillis() + ONE_DAY;
String name5 = Long.toString(exp)+"_foo_0.0.0.0_abcdefg";
File f5 = new File(testDir, name5);
if (f5.exists())
Assert.assertTrue(f5.delete());
f5.createNewFile();
//make a file that is for a different context
//that expired, but only recently - it should
//not be removed by the startup process
exp = System.currentTimeMillis() - 1000L;
String name6 = Long.toString(exp)+"_foo_0.0.0.0_abcdefg";
File f6 = new File(testDir, name6);
if (f6.exists())
Assert.assertTrue(f6.delete());
f6.createNewFile();
handler.setSessionIdManager(idmgr);
handler.start();
Assert.assertTrue(!f1.exists());
Assert.assertTrue(!f2.exists());
Assert.assertTrue(f3.exists());
Assert.assertTrue(!f4.exists());
Assert.assertTrue(f5.exists());
Assert.assertTrue(f6.exists());
}
/**
* Tests that only the most recent file will be
* loaded into the cache, even if it is already
* expired. Other recently expired files for
* same session should be deleted.
* @throws Exception
*/
@Test
public void testLoadOnlyMostRecent() throws Exception
{
Server server = new Server();
SessionHandler handler = new SessionHandler();
handler.setServer(server);
final DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server);
idmgr.setServer(server);
server.setSessionIdManager(idmgr);
FileSessionDataStore ds = new FileSessionDataStore();
ds.setGracePeriodSec(100); //set graceperiod to 100sec to control what we consider as very old
ds.setDeleteUnrestorableFiles(false); //turn off deletion of unreadable session files
DefaultSessionCache ss = new DefaultSessionCache(handler);
handler.setSessionCache(ss);
ss.setSessionDataStore(ds);
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
FS.ensureEmpty(testDir);
ds.setStoreDir(testDir);
long now = System.currentTimeMillis();
//create a file for session abc that expired 5sec ago
long exp = now - 5000L;
String name1 = Long.toString(exp)+"__0.0.0.0_abc";
File f1 = new File(testDir, name1);
if (f1.exists())
Assert.assertTrue(f1.delete());
f1.createNewFile();
//create a file for same session that expired 4 sec ago
exp = now - 4000L;
String name2 = Long.toString(exp)+"__0.0.0.0_abc";
File f2 = new File(testDir, name2);
if (f2.exists())
Assert.assertTrue(f2.delete());
f2.createNewFile();
//make a file for same session that expired 3 sec ago
exp = now - 3000L;
String name3 = Long.toString(exp)+"__0.0.0.0_abc";
File f3 = new File(testDir, name3);
if (f3.exists())
Assert.assertTrue(f3.delete());
f3.createNewFile();
handler.setSessionIdManager(idmgr);
handler.start();
Assert.assertFalse(f1.exists());
Assert.assertFalse(f2.exists());
Assert.assertTrue(f3.exists());
}
@Test
public void testUnrestorableFileRemoval() throws Exception
{
Server server = new Server();
SessionHandler handler = new SessionHandler();
handler.setServer(server);
final DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server);
idmgr.setServer(server);
server.setSessionIdManager(idmgr);
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
FS.ensureEmpty(testDir);
String expectedFilename = (System.currentTimeMillis() + 10000)+"__0.0.0.0_validFile123";
Assert.assertTrue(new File(testDir, expectedFilename).createNewFile());
Assert.assertTrue("File should exist!", new File(testDir, expectedFilename).exists());
DefaultSessionCache ss = new DefaultSessionCache(handler);
FileSessionDataStore ds = new FileSessionDataStore();
ss.setSessionDataStore(ds);
handler.setSessionCache(ss);
ds.setDeleteUnrestorableFiles(true); //invalid file will be removed
handler.setSessionIdManager(idmgr);
ds.setStoreDir(testDir);
handler.start();
handler.getSession("validFile123");
Assert.assertTrue("File shouldn't exist!", !new File(testDir,expectedFilename).exists());
}
@Test
public void testHashSession() throws Exception
{
File testDir = MavenTestingUtils.getTargetTestingDir("saved");
FS.ensureEmpty(testDir);
Server server = new Server();
SessionHandler handler = new SessionHandler();
handler.setServer(server);
DefaultSessionCache ss = new DefaultSessionCache(handler);
FileSessionDataStore ds = new FileSessionDataStore();
ss.setSessionDataStore(ds);
handler.setSessionCache(ss);
ds.setStoreDir(testDir);
handler.setMaxInactiveInterval(5);
Assert.assertTrue(testDir.exists());
Assert.assertTrue(testDir.canWrite());
DefaultSessionIdManager idManager = new DefaultSessionIdManager(server);
idManager.setServer(server);
idManager.setWorkerName("foo");
handler.setSessionIdManager(idManager);
server.setSessionIdManager(idManager);
server.start();
handler.start();
Session session = (Session)handler.newHttpSession(new Request(null, null));
String sessionId = session.getId();
session.setAttribute("one", new Integer(1));
session.setAttribute("two", new Integer(2));
//stop will persist sessions
handler.setMaxInactiveInterval(30); // change max inactive interval for *new* sessions
handler.stop();
final String expectedFilename = "_0.0.0.0_"+session.getId();
File[] files = testDir.listFiles(new FilenameFilter(){
@Override
public boolean accept(File dir, String name)
{
return name.contains(expectedFilename);
}
});
Assert.assertNotNull(files);
Assert.assertEquals(1, files.length);
Assert.assertTrue("File should exist!", files[0].exists());
handler.start();
//restore session
Session restoredSession = (Session)handler.getSession(sessionId);
Assert.assertNotNull(restoredSession);
Object o = restoredSession.getAttribute("one");
Assert.assertNotNull(o);
Assert.assertEquals(1, ((Integer)o).intValue());
Assert.assertEquals(5, restoredSession.getMaxInactiveInterval());
server.stop();
}
@Test
public void testIrregularFilenames() throws Exception
{
Server server = new Server();
SessionHandler handler = new SessionHandler();
handler.setServer(server);
final DefaultSessionIdManager idmgr = new DefaultSessionIdManager(server);
idmgr.setServer(server);
server.setSessionIdManager(idmgr);
FileSessionDataStore ds = new FileSessionDataStore();
ds.setDeleteUnrestorableFiles(true);
DefaultSessionCache ss = new DefaultSessionCache(handler);
handler.setSessionCache(ss);
ss.setSessionDataStore(ds);
File testDir = MavenTestingUtils.getTargetTestingDir("hashes");
FS.ensureEmpty(testDir);
ds.setStoreDir(testDir);
handler.setSessionIdManager(idmgr);
handler.start();
//Create a file in the session storeDir that has no underscore.
File noUnderscore = new File(testDir, "spuriousFile");
noUnderscore.createNewFile();
try
{
Assert.assertTrue("Expired should be empty!", ds.getExpired(Collections.emptySet()).isEmpty());
}
finally
{
noUnderscore.delete();
}
//Create a file that starts with a non-number before an underscore
File nonNumber = new File(testDir, "nonNumber_0.0.0.0_spuriousFile");
nonNumber.createNewFile();
try
{
Assert.assertTrue("Expired should be empty!", ds.getExpired(Collections.emptySet()).isEmpty());
}
finally
{
nonNumber.delete();
}
}
}

View File

@ -46,80 +46,49 @@ public class SessionCookieTest
super(manager);
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#shutdown()
*/
@Override
public void shutdown()
{
// TODO Auto-generated method stub
{
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(org.eclipse.jetty.server.session.SessionData)
*/
@Override
public Session newSession(SessionData data)
{
// TODO Auto-generated method stub
return null;
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doGet(String)
*/
@Override
public Session doGet(String key)
{
// TODO Auto-generated method stub
return null;
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doPutIfAbsent(String, Session)
*/
@Override
public Session doPutIfAbsent(String key, Session session)
{
return null;
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doDelete(String)
*/
@Override
public Session doDelete(String key)
{
return null;
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doReplace(java.lang.String, org.eclipse.jetty.server.session.Session, org.eclipse.jetty.server.session.Session)
*/
@Override
public boolean doReplace(String id, Session oldValue, Session newValue)
{
// TODO Auto-generated method stub
return false;
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(javax.servlet.http.HttpServletRequest, org.eclipse.jetty.server.session.SessionData)
*/
@Override
public Session newSession(HttpServletRequest request, SessionData data)
{
// TODO Auto-generated method stub
return null;
}
}
@ -131,18 +100,12 @@ public class SessionCookieTest
super(server);
}
/**
* @see org.eclipse.jetty.server.SessionIdManager#isIdInUse(java.lang.String)
*/
@Override
public boolean isIdInUse(String id)
{
return false;
}
/**
* @see org.eclipse.jetty.server.SessionIdManager#expireAll(java.lang.String)
*/
@Override
public void expireAll(String id)
{
@ -206,8 +169,5 @@ public class SessionCookieTest
//cookie is not secure: not on secured requests and request is secure
cookie = mgr.getSessionCookie(session, "/foo", true);
assertFalse(cookie.isSecure());
}
}

36
pom.xml
View File

@ -448,7 +448,7 @@
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-invoker-plugin</artifactId>
<version>3.0.1</version>
<version>3.0.2-SNAPSHOT</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
@ -1068,16 +1068,6 @@
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>apache.snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
@ -1814,6 +1804,30 @@
</repository>
</repositories>
-->
<repositories>
<repository>
<id>apache.snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>apache.snapshots</id>
<url>https://repository.apache.org/content/repositories/snapshots</url>
<releases>
<enabled>false</enabled>
</releases>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
<distributionManagement>
<repository>

View File

@ -14,7 +14,6 @@
</build>
<modules>
<module>test-sessions-common</module>
<module>test-hash-sessions</module>
<module>test-file-sessions</module>
<module>test-jdbc-sessions</module>
<module>test-mongodb-sessions</module>

View File

@ -19,19 +19,16 @@
package org.eclipse.jetty.server.session;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* ProxySerializationTest
* FileSessionDataStoreTest
*
*
*/
public class ProxySerializationTest extends AbstractProxySerializationTest
{
public class FileSessionDataStoreTest extends AbstractSessionDataStoreTest
{
@Before
public void before() throws Exception
{
@ -43,35 +40,44 @@ public class ProxySerializationTest extends AbstractProxySerializationTest
{
FileTestHelper.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return FileTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testProxySerialization() throws Exception
public void persistSession(SessionData data) throws Exception
{
super.testProxySerialization();
FileTestHelper.createFile(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(), data.getCookieSet(), data.getAllAttributes());
}
@Override
public void persistUnreadableSession(SessionData data) throws Exception
{
FileTestHelper.createFile(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(), data.getCookieSet(), null);
}
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
return (FileTestHelper.getFile(data.getId()) != null);
}
/**
* @see org.eclipse.jetty.server.session.AbstractProxySerializationTest#customizeContext(org.eclipse.jetty.servlet.ServletContextHandler)
*
*/
@Override
public void customizeContext(ServletContextHandler c)
public boolean checkSessionPersisted(SessionData data) throws Exception
{
// TODO Auto-generated method stub
return FileTestHelper.checkSessionPersisted(data);
}
}

View File

@ -23,10 +23,20 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.IO;
/**
@ -142,6 +152,105 @@ public class FileTestHelper
}
public static void createFile (String id, String contextPath, String vhost,
String lastNode, long created, long accessed,
long lastAccessed, long maxIdle, long expiry,
long cookieSet, Map<String,Object> attributes)
throws Exception
{
String filename = ""+expiry+"_"+contextPath+"_"+vhost+"_"+id;
File file = new File(_tmpDir, filename);
try(FileOutputStream fos = new FileOutputStream(file,false))
{
DataOutputStream out = new DataOutputStream(fos);
out.writeUTF(id);
out.writeUTF(contextPath);
out.writeUTF(vhost);
out.writeUTF(lastNode);
out.writeLong(created);
out.writeLong(accessed);
out.writeLong(lastAccessed);
out.writeLong(cookieSet);
out.writeLong(expiry);
out.writeLong(maxIdle);
if (attributes != null)
{
List<String> keys = new ArrayList<String>(attributes.keySet());
out.writeInt(keys.size());
ObjectOutputStream oos = new ObjectOutputStream(out);
for (String name:keys)
{
oos.writeUTF(name);
oos.writeObject(attributes.get(name));
}
}
}
}
public static boolean checkSessionPersisted (SessionData data)
throws Exception
{
String filename = ""+data.getExpiry()+"_"+data.getContextPath()+"_"+data.getVhost()+"_"+data.getId();
File file = new File(_tmpDir, filename);
assertTrue(file.exists());
try (FileInputStream in = new FileInputStream(file))
{
DataInputStream di = new DataInputStream(in);
String id = di.readUTF();
String contextPath = di.readUTF();
String vhost = di.readUTF();
String lastNode = di.readUTF();
long created = di.readLong();
long accessed = di.readLong();
long lastAccessed = di.readLong();
long cookieSet = di.readLong();
long expiry = di.readLong();
long maxIdle = di.readLong();
assertEquals(data.getId(), id);
assertEquals(data.getContextPath(), contextPath);
assertEquals(data.getVhost(), vhost);
assertEquals(data.getLastNode(), lastNode);
assertEquals(data.getCreated(), created);
assertEquals(data.getAccessed(), accessed);
assertEquals(data.getLastAccessed(), lastAccessed);
assertEquals(data.getCookieSet(), cookieSet);
assertEquals(data.getExpiry(), expiry);
assertEquals(data.getMaxInactiveMs(), maxIdle);
Map<String,Object> attributes = new HashMap<>();
int size = di.readInt();
if (size > 0)
{
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(di);
for (int i=0; i<size;i++)
{
String key = ois.readUTF();
Object value = ois.readObject();
attributes.put(key,value);
}
}
//same number of attributes
assertEquals(data.getAllAttributes().size(), attributes.size());
//same keys
assertTrue(data.getKeys().equals(attributes.keySet()));
//same values
for (String name:data.getKeys())
{
assertTrue(data.getAttribute(name).equals(attributes.get(name)));
}
}
return true;
}
public static void deleteFile (String sessionId)
{
assertNotNull(_tmpDir);

View File

@ -1,63 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.junit.After;
import org.junit.Before;
import org.junit.Test;
/**
* NonClusteredSessionScavengingTest
*/
public class NonClusteredSessionScavengingTest extends AbstractNonClusteredSessionScavengingTest
{
@Before
public void before() throws Exception
{
FileTestHelper.setup();
}
@After
public void after()
{
FileTestHelper.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession(String id, boolean exists)
{
FileTestHelper.assertSessionExists(id, exists);
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return FileTestHelper.newSessionDataStoreFactory();
}
}

View File

@ -1,56 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.junit.After;
import org.junit.Before;
import org.junit.Test;
public class SessionInvalidateCreateScavengeTest extends AbstractSessionInvalidateCreateScavengeTest
{
@Before
public void before() throws Exception
{
FileTestHelper.setup();
}
@After
public void after()
{
FileTestHelper.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return FileTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testSessionScavenge() throws Exception
{
super.testSessionScavenge();
}
}

View File

@ -21,21 +21,14 @@ package org.eclipse.jetty.server.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeUnit;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@ -60,205 +53,396 @@ public class TestFileSessions extends AbstractTestBase
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return FileTestHelper.newSessionDataStoreFactory();
}
/**
* Test that passing in a filename that contains ".." chars does not
* remove a file outside of the store dir.
*
* @throws Exception
*/
@Test
public void testLoadForeignContext() throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(10);
FileSessionDataStore store = (FileSessionDataStore)factory.getSessionDataStore(context.getSessionHandler());
store.setDeleteUnrestorableFiles(true);
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
//make a file for foobar context
FileTestHelper.createFile((System.currentTimeMillis()+TimeUnit.DAYS.toMillis(1))+"__foobar_0.0.0.0_1234");
store.start();
//test this context can't load it
assertNull(store.load("1234"));
}
@Test
public void testSweep () throws Exception
public void testFilenamesWithContext() throws Exception
{
int scavengePeriod = 2;
String contextPath = "/test";
String servletMapping = "/server";
int inactivePeriod = 5;
int gracePeriod = 10;
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
FileSessionDataStoreFactory storeFactory = (FileSessionDataStoreFactory)createSessionDataStoreFactory();
storeFactory.setGracePeriodSec(gracePeriod);
TestServer server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(10);
FileSessionDataStore store = (FileSessionDataStore)factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
String s = store.getIdWithContext("1234");
assertEquals("_test_0.0.0.0_1234", s);
s = store.getIdFromFilename("0__test_0.0.0.0_1234");
assertEquals("1234", s);
s = store.getIdFromFilename(null);
assertNull(s);
long l = store.getExpiryFromFilename("100__test_0.0.0.0_1234");
assertEquals(100, l);
try
{
server1.start();
//create file not for our context that expired long ago and should be removed by sweep
FileTestHelper.createFile("101_foobar_0.0.0.0_sessiona");
FileTestHelper.assertSessionExists("sessiona", true);
//create a file not for our context that is not expired and should be ignored
String nonExpiredForeign = (System.currentTimeMillis()+TimeUnit.DAYS.toMillis(1))+"_foobar_0.0.0.0_sessionb";
FileTestHelper.createFile(nonExpiredForeign);
FileTestHelper.assertFileExists(nonExpiredForeign, true);
//create a file not for our context that is recently expired, a thus ignored by sweep
String expiredForeign = (System.currentTimeMillis()-TimeUnit.SECONDS.toMillis(1))+"_foobar_0.0.0.0_sessionc";
FileTestHelper.createFile(expiredForeign);
FileTestHelper.assertFileExists(expiredForeign, true);
//create a file that is not a session file, it should be ignored
FileTestHelper.createFile("whatever.txt");
FileTestHelper.assertFileExists("whatever.txt", true);
//create a file that is a non-expired session file for our context that should be ignored
String nonExpired = (System.currentTimeMillis()+TimeUnit.DAYS.toMillis(1))+"_test_0.0.0.0_sessionb";
FileTestHelper.createFile(nonExpired);
FileTestHelper.assertFileExists(nonExpired, true);
//create a file that is a never-expire session file for our context that should be ignored
String neverExpired = "0_test_0.0.0.0_sessionc";
FileTestHelper.createFile(neverExpired);
FileTestHelper.assertFileExists(neverExpired, true);
//create a file that is a never-expire session file for another context that should be ignored
String foreignNeverExpired = "0_test_0.0.0.0_sessionc";
FileTestHelper.createFile(foreignNeverExpired);
FileTestHelper.assertFileExists(foreignNeverExpired, true);
//need to wait to ensure scavenge runs so sweeper runs
Thread.currentThread().sleep(2000L*scavengePeriod);
FileTestHelper.assertSessionExists("sessiona", false);
FileTestHelper.assertFileExists("whatever.txt", true);
FileTestHelper.assertFileExists(nonExpired, true);
FileTestHelper.assertFileExists(nonExpiredForeign, true);
FileTestHelper.assertFileExists(expiredForeign, true);
FileTestHelper.assertFileExists(neverExpired, true);
FileTestHelper.assertFileExists(foreignNeverExpired, true);
long ll = store.getExpiryFromFilename("nonnumber__test_0.0.0.0_1234");
fail ("Should be non numeric");
}
finally
catch (Exception e)
{
server1.stop();
//expected
}
}
@Test
public void test () throws Exception
{
String contextPath = "/test";
String servletMapping = "/server";
int inactivePeriod = 5;
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
SessionDataStoreFactory storeFactory = createSessionDataStoreFactory();
TestServer server1 = new TestServer(0, inactivePeriod, 2, cacheFactory, storeFactory);
server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
try
{
server1.start();
int port1 = server1.getPort();
HttpClient client = new HttpClient();
client.start();
try
{
// Connect to server1 to create a session and get its session cookie
ContentResponse response1 = client.GET("http://localhost:" + port1 + contextPath + servletMapping + "?action=init");
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
String sessionCookie = response1.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null);
// Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
//check that the file for the session exists after creating the session
FileTestHelper.assertSessionExists(TestServer.extractSessionId(sessionCookie), true);
File file1 = FileTestHelper.getFile(TestServer.extractSessionId(sessionCookie));
//request the session and check that the file for the session was changed
Request request = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=check");
request.header("Cookie", sessionCookie);
ContentResponse response2 = request.send();
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
FileTestHelper.assertSessionExists(TestServer.extractSessionId(sessionCookie), true);
File file2 = FileTestHelper.getFile(TestServer.extractSessionId(sessionCookie));
assertFalse (file1.exists());
assertTrue(file2.exists());
//check expiry time in filename changed
String tmp = file1.getName();
tmp = tmp.substring(0, tmp.indexOf("_"));
long f1 = Long.valueOf(tmp);
tmp = file2.getName();
tmp = tmp.substring(0, tmp.indexOf("_"));
long f2 = Long.valueOf(tmp);
assertTrue (f2>f1);
//invalidate the session and verify that the session file is deleted
request = client.newRequest("http://localhost:" + port1 + contextPath + servletMapping + "?action=remove");
request.header("Cookie", sessionCookie);
response2 = request.send();
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
FileTestHelper.assertSessionExists(TestServer.extractSessionId(sessionCookie), false);
//make another session
response1 = client.GET("http://localhost:" + port1 + contextPath + servletMapping + "?action=init");
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
sessionCookie = response1.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null);
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
FileTestHelper.assertSessionExists(TestServer.extractSessionId(sessionCookie), true);
//wait for it to be scavenged
Thread.currentThread().sleep((inactivePeriod + 2)*1000);
FileTestHelper.assertSessionExists(TestServer.extractSessionId(sessionCookie), false);
}
finally
{
client.stop();
}
long ll = store.getExpiryFromFilename(null);
fail("Should throw ISE");
}
finally
catch (Exception e)
{
server1.stop();
//expected;
}
try
{
long ll = store.getExpiryFromFilename("thisisnotavalidsessionfilename");
fail("Should throw ISE");
}
catch (IllegalStateException e)
{
//expected;
}
s = store.getContextFromFilename("100__test_0.0.0.0_1234");
assertEquals("_test_0.0.0.0", s);
assertNull (store.getContextFromFilename(null));
try
{
s = store.getContextFromFilename("thisisnotavalidfilename");
fail("Should throw exception");
}
catch (StringIndexOutOfBoundsException e)
{
//expected;
}
s = store.getIdWithContextFromFilename("100__test_0.0.0.0_1234");
assertEquals("_test_0.0.0.0_1234",s);
assertNull(store.getIdWithContextFromFilename(null));
assertNull(store.getIdWithContextFromFilename("thisisnotavalidfilename"));
assertTrue(store.isOurContextSessionFilename("100__test_0.0.0.0_1234"));
assertFalse(store.isOurContextSessionFilename("100__other_0.0.0.0_1234"));
}
public static class TestServlet extends HttpServlet
@Test
public void testFilenamesWithDefaultContext() throws Exception
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(10);
FileSessionDataStore store = (FileSessionDataStore)factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
String s = store.getIdWithContext("1234");
assertEquals("_0.0.0.0_1234", s);
s = store.getIdFromFilename("0__0.0.0.0_1234");
assertEquals("1234", s);
long l = store.getExpiryFromFilename("100__0.0.0.0_1234");
assertEquals(100, l);
try
{
String action = request.getParameter("action");
if ("init".equals(action))
{
HttpSession session = request.getSession(true);
session.setAttribute("A", "A");
}
else if ("remove".equals(action))
{
HttpSession session = request.getSession(false);
session.invalidate();
}
else if ("check".equals(action))
{
HttpSession session = request.getSession(false);
assertTrue(session != null);
try {Thread.currentThread().sleep(1);}catch (Exception e) {e.printStackTrace();}
}
long ll = store.getExpiryFromFilename("nonnumber__0.0.0.0_1234");
fail ("Should be non numeric");
}
catch (Exception e)
{
//expected
}
s = store.getContextFromFilename("100__0.0.0.0_1234");
assertEquals("_0.0.0.0", s);
s = store.getIdWithContextFromFilename("100__0.0.0.0_1234");
assertEquals("_0.0.0.0_1234",s);
assertTrue(store.isOurContextSessionFilename("100__0.0.0.0_1234"));
assertFalse(store.isOurContextSessionFilename("100__other_0.0.0.0_1234"));
}
/**
* Test the FileSessionDataStore sweeper function
*
* @throws Exception
*/
@Test
public void testSweep () throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(10);
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
store.start();
//create file not for our context that expired long ago and should be removed by sweep
FileTestHelper.createFile("101__foobar_0.0.0.0_sessiona");
FileTestHelper.assertSessionExists("sessiona", true);
//create a file not for our context that is not expired and should be ignored
String nonExpiredForeign = (System.currentTimeMillis()+TimeUnit.DAYS.toMillis(1))+"__foobar_0.0.0.0_sessionb";
FileTestHelper.createFile(nonExpiredForeign);
FileTestHelper.assertFileExists(nonExpiredForeign, true);
//create a file not for our context that is recently expired, a thus ignored by sweep
String expiredForeign = (System.currentTimeMillis()-TimeUnit.SECONDS.toMillis(1))+"__foobar_0.0.0.0_sessionc";
FileTestHelper.createFile(expiredForeign);
FileTestHelper.assertFileExists(expiredForeign, true);
//create a file that is not a session file, it should be ignored
FileTestHelper.createFile("whatever.txt");
FileTestHelper.assertFileExists("whatever.txt", true);
//create a file that is not a valid session filename, should be ignored
FileTestHelper.createFile("nonNumber__0.0.0.0_spuriousFile");
FileTestHelper.assertFileExists("nonNumber__0.0.0.0_spuriousFile", true);
//create a file that is a non-expired session file for our context that should be ignored
String nonExpired = (System.currentTimeMillis()+TimeUnit.DAYS.toMillis(1))+"__test_0.0.0.0_sessionb";
FileTestHelper.createFile(nonExpired);
FileTestHelper.assertFileExists(nonExpired, true);
//create a file that is a never-expire session file for our context that should be ignored
String neverExpired = "0__test_0.0.0.0_sessionc";
FileTestHelper.createFile(neverExpired);
FileTestHelper.assertFileExists(neverExpired, true);
//create a file that is a never-expire session file for another context that should be ignored
String foreignNeverExpired = "0__other_0.0.0.0_sessionc";
FileTestHelper.createFile(foreignNeverExpired);
FileTestHelper.assertFileExists(foreignNeverExpired, true);
//sweep
((FileSessionDataStore)store).sweepDisk();
//check results
FileTestHelper.assertSessionExists("sessiona", false);
FileTestHelper.assertFileExists("whatever.txt", true);
FileTestHelper.assertFileExists("nonNumber__0.0.0.0_spuriousFile", true);
FileTestHelper.assertFileExists(nonExpired, true);
FileTestHelper.assertFileExists(nonExpiredForeign, true);
FileTestHelper.assertFileExists(expiredForeign, true);
FileTestHelper.assertFileExists(neverExpired, true);
FileTestHelper.assertFileExists(foreignNeverExpired, true);
}
/**
* Test that when it initializes, the FileSessionDataStore deletes old expired sessions.
*
* @throws Exception
*/
@Test
public void testInitialize ()
throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(10);
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
//create file not for our context that expired long ago and should be removed
FileTestHelper.createFile("101_foobar_0.0.0.0_sessiona");
FileTestHelper.assertSessionExists("sessiona", true);
//create a file not for our context that is not expired and should be ignored
String nonExpiredForeign = (System.currentTimeMillis()+TimeUnit.DAYS.toMillis(1))+"_foobar_0.0.0.0_sessionb";
FileTestHelper.createFile(nonExpiredForeign);
FileTestHelper.assertFileExists(nonExpiredForeign, true);
//create a file not for our context that is recently expired, a thus ignored
String expiredForeign = (System.currentTimeMillis()-TimeUnit.SECONDS.toMillis(1))+"_foobar_0.0.0.0_sessionc";
FileTestHelper.createFile(expiredForeign);
FileTestHelper.assertFileExists(expiredForeign, true);
//create a file that is not a session file, it should be ignored
FileTestHelper.createFile("whatever.txt");
FileTestHelper.assertFileExists("whatever.txt", true);
//create a file that is not a valid session filename, should be ignored
FileTestHelper.createFile("nonNumber_0.0.0.0_spuriousFile");
FileTestHelper.assertFileExists("nonNumber_0.0.0.0_spuriousFile", true);
//create a file that is a non-expired session file for our context that should be ignored
String nonExpired = (System.currentTimeMillis()+TimeUnit.DAYS.toMillis(1))+"_test_0.0.0.0_sessionb";
FileTestHelper.createFile(nonExpired);
FileTestHelper.assertFileExists(nonExpired, true);
//create a file that is a never-expire session file for our context that should be ignored
String neverExpired = "0_test_0.0.0.0_sessionc";
FileTestHelper.createFile(neverExpired);
FileTestHelper.assertFileExists(neverExpired, true);
//create a file that is a never-expire session file for another context that should be ignored
String foreignNeverExpired = "0_test_0.0.0.0_sessionc";
FileTestHelper.createFile(foreignNeverExpired);
FileTestHelper.assertFileExists(foreignNeverExpired, true);
//walk all files in the store
((FileSessionDataStore)store).initializeStore();
//check results
FileTestHelper.assertSessionExists("sessiona", false);
FileTestHelper.assertFileExists("whatever.txt", true);
FileTestHelper.assertFileExists("nonNumber_0.0.0.0_spuriousFile", true);
FileTestHelper.assertFileExists(nonExpired, true);
FileTestHelper.assertFileExists(nonExpiredForeign, true);
FileTestHelper.assertFileExists(expiredForeign, true);
FileTestHelper.assertFileExists(neverExpired, true);
FileTestHelper.assertFileExists(foreignNeverExpired, true);
}
/**
* If deleteUnrestorableFiles option is true, a damaged or unrestorable
* file should be deleted.
*
* @throws Exception
*/
@Test
public void testDeleteUnrestorableFiles ()
throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(10);
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
((FileSessionDataStore)store).setDeleteUnrestorableFiles(true); //invalid file will be removed
store.initialize(sessionContext);
String expectedFilename = (System.currentTimeMillis() + 10000)+"__test_0.0.0.0_validFile123";
FileTestHelper.createFile(expectedFilename);
FileTestHelper.assertFileExists(expectedFilename, true);
store.start();
try
{
store.load("validFile123");
fail("Load should fail");
}
catch (Exception e)
{
//expected exception
}
FileTestHelper.assertFileExists(expectedFilename, false);
}
/**
* Tests that only the most recent file will be
* loaded into the cache, even if it is already
* expired. Other recently expired files for
* same session should be deleted.
* @throws Exception
*/
@Test
public void testLoadOnlyMostRecentFiles ()
throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(100);
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
long now = System.currentTimeMillis();
//create a file for session abc that expired 5sec ago
long exp = now - 5000L;
String name1 = Long.toString(exp)+"__test_0.0.0.0_abc";
FileTestHelper.createFile(name1);
//create a file for same session that expired 4 sec ago
exp = now - 4000L;
String name2 = Long.toString(exp)+"__test_0.0.0.0_abc";
FileTestHelper.createFile(name2);
//make a file for same session that expired 3 sec ago
exp = now - 3000L;
String name3 = Long.toString(exp)+"__test_0.0.0.0_abc";
FileTestHelper.createFile(name3);
store.start();
FileTestHelper.assertFileExists(name1, false);
FileTestHelper.assertFileExists(name2, false);
FileTestHelper.assertFileExists(name3, true);
}
}

View File

@ -1,59 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractClusteredLastAccessTimeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.Test;
/**
* ClusteredLastAccessTimeTest
*
*
*/
public class ClusteredLastAccessTimeTest extends AbstractClusteredLastAccessTimeTest
{
@AfterClass
public static void teardown () throws Exception
{
GCloudTestSuite.__testSupport.deleteSessions();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
@Test
@Override
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();
}
}

View File

@ -1,56 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractClusteredSessionMigrationTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.Test;
/**
* ClusteredSessionMigrationTest
*
*
*/
public class ClusteredSessionMigrationTest extends AbstractClusteredSessionMigrationTest
{
@AfterClass
public static void teardown () throws Exception
{
GCloudTestSuite.__testSupport.deleteSessions();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
@Test
@Override
public void testSessionMigration() throws Exception
{
super.testSessionMigration();
}
}

View File

@ -48,12 +48,5 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
@Test
@Override
public void testLocalSessionsScavenging() throws Exception
{
super.testLocalSessionsScavenging();
}
}

View File

@ -0,0 +1,85 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreTest;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
/**
* GCloudSessionDataStoreTest
*
*
*/
public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest
{
@After
public void teardown () throws Exception
{
GCloudTestSuite.__testSupport.deleteSessions();
}
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
@Override
public void persistSession(SessionData data) throws Exception
{
GCloudTestSuite.__testSupport.createSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(),
data.getCookieSet(), data.getLastSaved(), data.getAllAttributes());
}
@Override
public void persistUnreadableSession(SessionData data) throws Exception
{
GCloudTestSuite.__testSupport.createSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(),
data.getCookieSet(), data.getLastSaved(), null);
}
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
return GCloudTestSuite.__testSupport.checkSessionExists(data.getId());
}
/**
*
*/
@Override
public boolean checkSessionPersisted(SessionData data) throws Exception
{
return GCloudTestSuite.__testSupport.checkSessionPersisted(data);
}
}

View File

@ -21,24 +21,36 @@ package org.eclipse.jetty.gcloud.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.jetty.gcloud.session.GCloudSessionDataStore.EntityDataModel;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.threeten.bp.Duration;
import com.google.cloud.datastore.Blob;
import com.google.cloud.datastore.BlobValue;
import com.google.cloud.datastore.Datastore;
import com.google.cloud.datastore.DatastoreOptions;
import com.google.cloud.datastore.Entity;
import com.google.cloud.datastore.GqlQuery;
import com.google.cloud.datastore.Key;
import com.google.cloud.datastore.KeyFactory;
import com.google.cloud.datastore.Query;
import com.google.cloud.datastore.Query.ResultType;
import com.google.cloud.datastore.QueryResults;
import com.google.cloud.datastore.StructuredQuery.PropertyFilter;
import com.google.cloud.datastore.testing.LocalDatastoreHelper;
/**
@ -50,6 +62,7 @@ public class GCloudSessionTestSupport
{
LocalDatastoreHelper _helper = LocalDatastoreHelper.create(1.0);
Datastore _ds;
KeyFactory _keyFactory;
public static class TestGCloudSessionDataStoreFactory extends GCloudSessionDataStoreFactory
@ -82,6 +95,7 @@ public class GCloudSessionTestSupport
{
DatastoreOptions options = _helper.getOptions();
_ds = options.getService();
_keyFactory =_ds.newKeyFactory().setKind(EntityDataModel.KIND);
}
@ -111,6 +125,103 @@ public class GCloudSessionTestSupport
_helper.reset();
}
public void createSession (String id, String contextPath, String vhost,
String lastNode, long created, long accessed,
long lastAccessed, long maxIdle, long expiry,
long cookieset, long lastSaved,
Map<String,Object> attributes)
throws Exception
{
//serialize the attribute map
ByteArrayOutputStream baos = new ByteArrayOutputStream();
if (attributes != null)
{
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(attributes);
oos.flush();
}
//turn a session into an entity
Entity.Builder builder = Entity.newBuilder(_keyFactory.newKey(contextPath+"_"+vhost+"_"+id))
.set(EntityDataModel.ID, id)
.set(EntityDataModel.CONTEXTPATH, contextPath)
.set(EntityDataModel.VHOST, vhost)
.set(EntityDataModel.ACCESSED, accessed)
.set(EntityDataModel.LASTACCESSED, lastAccessed)
.set(EntityDataModel.CREATETIME, created)
.set(EntityDataModel.COOKIESETTIME, cookieset)
.set(EntityDataModel.LASTNODE, lastNode)
.set(EntityDataModel.EXPIRY, expiry)
.set(EntityDataModel.MAXINACTIVE, maxIdle)
.set(EntityDataModel.LASTSAVED, lastSaved);
if (attributes != null)
builder.set(EntityDataModel.ATTRIBUTES, BlobValue.newBuilder(Blob.copyFrom(baos.toByteArray())).setExcludeFromIndexes(true).build());
Entity entity = builder.build();
_ds.put(entity);
}
public boolean checkSessionPersisted (SessionData data)
throws Exception
{
Entity entity = _ds.get(_keyFactory.newKey(data.getContextPath()+"_"+data.getVhost()+"_"+data.getId()));
if (entity == null)
return false;
//turn an Entity into a Session
assertEquals(data.getId(), entity.getString(EntityDataModel.ID));
assertEquals(data.getContextPath(), entity.getString(EntityDataModel.CONTEXTPATH));
assertEquals(data.getVhost(), entity.getString(EntityDataModel.VHOST));
assertEquals(data.getAccessed(), entity.getLong(EntityDataModel.ACCESSED));
assertEquals(data.getLastAccessed(), entity.getLong(EntityDataModel.LASTACCESSED));
assertEquals(data.getCreated(), entity.getLong(EntityDataModel.CREATETIME));
assertEquals(data.getCookieSet(), entity.getLong(EntityDataModel.COOKIESETTIME));
assertEquals(data.getLastNode(), entity.getString(EntityDataModel.LASTNODE));
assertEquals(data.getLastSaved(), entity.getLong(EntityDataModel.LASTSAVED));
assertEquals(data.getExpiry(), entity.getLong(EntityDataModel.EXPIRY));
assertEquals(data.getMaxInactiveMs(), entity.getLong(EntityDataModel.MAXINACTIVE));
Blob blob = (Blob) entity.getBlob(EntityDataModel.ATTRIBUTES);
Map<String,Object> attributes = new HashMap<>();
try (ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(blob.asInputStream()))
{
Object o = ois.readObject();
attributes.putAll((Map<String,Object>)o);
}
//same number of attributes
assertEquals(data.getAllAttributes().size(), attributes.size());
//same keys
assertTrue(data.getKeys().equals(attributes.keySet()));
//same values
for (String name:data.getKeys())
{
assertTrue(data.getAttribute(name).equals(attributes.get(name)));
}
return true;
}
public boolean checkSessionExists (String id)
throws Exception
{
Query<Entity> query = Query.newEntityQueryBuilder()
.setKind(EntityDataModel.KIND)
.setFilter(PropertyFilter.eq(EntityDataModel.ID, id))
.build();
QueryResults<Entity> results = _ds.run(query);
if (results.hasNext())
{
return true;
}
return false;
}
public Set<String> getSessionIds () throws Exception
{

View File

@ -31,15 +31,10 @@ import org.junit.runners.Suite;
*/
@RunWith(Suite.class)
@Suite.SuiteClasses({
GCloudSessionDataStoreTest.class,
InvalidationSessionTest.class,
ClusteredLastAccessTimeTest.class,
ClusteredSessionScavengingTest.class,
NonClusteredSessionScavengingTest.class,
ClusteredOrphanedSessionTest.class,
SessionExpiryTest.class,
SessionInvalidateCreateScavengeTest.class,
ClusteredSessionMigrationTest.class,
ModifyMaxInactiveIntervalTest.class
ClusteredOrphanedSessionTest.class
})

View File

@ -1,50 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
/**
* ModifyMaxInactiveIntervalTest
*
*
*/
public class ModifyMaxInactiveIntervalTest extends AbstractModifyMaxInactiveIntervalTest
{
@After
public void teardown () throws Exception
{
GCloudTestSuite.__testSupport.deleteSessions();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
}

View File

@ -1,82 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.util.Set;
import org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Test;
/**
* NonClusteredSessionScavengingTest
*
*
*/
public class NonClusteredSessionScavengingTest extends AbstractNonClusteredSessionScavengingTest
{
@After
public void teardown () throws Exception
{
GCloudTestSuite.__testSupport.deleteSessions();
}
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession(String id, boolean exists)
{
try
{
Set<String> ids = GCloudTestSuite.__testSupport.getSessionIds();
if (exists)
assertTrue(ids.contains(id));
else
assertFalse(ids.contains(id));
}
catch (Exception e)
{
fail(e.getMessage());
}
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
}

View File

@ -1,75 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.After;
import org.junit.Assert;
import org.junit.Test;
/**
* SessionExpiryTest
*
*
*/
public class SessionExpiryTest extends AbstractSessionExpiryTest
{
@After
public void teardown () throws Exception
{
GCloudTestSuite.__testSupport.deleteSessions();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
@Override
public void verifySessionCreated(TestHttpSessionListener listener, String sessionId)
{
super.verifySessionCreated(listener, sessionId);
try {GCloudTestSuite.__testSupport.assertSessions(1);}catch(Exception e){ Assert.fail(e.getMessage());}
}
@Override
public void verifySessionDestroyed(TestHttpSessionListener listener, String sessionId)
{
super.verifySessionDestroyed(listener, sessionId);
//try{GCloudTestSuite.__testSupport.assertSessions(0);}catch(Exception e) {Assert.fail(e.getMessage());}
}
}

View File

@ -1,58 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractSessionInvalidateCreateScavengeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.Test;
/**
* SessionInvalidateCreateScavengeTest
*
*
*/
public class SessionInvalidateCreateScavengeTest extends AbstractSessionInvalidateCreateScavengeTest
{
@AfterClass
public static void teardown () throws Exception
{
GCloudTestSuite.__testSupport.deleteSessions();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return GCloudSessionTestSupport.newSessionDataStoreFactory(GCloudTestSuite.__testSupport.getDatastore());
}
@Test
@Override
public void testSessionScavenge() throws Exception
{
super.testSessionScavenge();
}
}

View File

@ -1,55 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-parent</artifactId>
<version>9.4.10-SNAPSHOT</version>
</parent>
<artifactId>test-hash-sessions</artifactId>
<name>Jetty Tests :: Sessions :: Hash</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.sessions.hash</bundle-symbolic-name>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<!-- DO NOT DEPLOY (or Release) -->
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<!-- Leaving at compile scope for intellij bug reasons -->
<scope>compile</scope>
</dependency>
</dependencies>
</project>

View File

@ -1,56 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.junit.Test;
/**
* NonClusteredSessionScavengingTest
*/
public class NonClusteredSessionScavengingTest extends AbstractNonClusteredSessionScavengingTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession(String id, boolean exists)
{
//noop, as we do not have a session store
}
@Test
@Override
public void testNewSession() throws Exception
{
super.testNewSession();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return HashTestHelper.newSessionDataStoreFactory();
}
}

View File

@ -1,50 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.AbstractClusteredLastAccessTimeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
public class ClusteredLastAccessTimeTest
extends AbstractClusteredLastAccessTimeTest
{
HazelcastSessionDataStoreFactory factory;
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
}
}

View File

@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.AbstractClusteredOrphanedSessionTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
/**
* ClusteredOrphanedSessionTest
@ -34,20 +35,26 @@ public class ClusteredOrphanedSessionTest
HazelcastSessionDataStoreFactory factory;
HazelcastTestHelper _testHelper;
@Before
public void setUp()
{
_testHelper = new HazelcastTestHelper();
}
@After
public void shutdown()
{
_testHelper.tearDown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
return _testHelper.createSessionDataStoreFactory(false);
}
}

View File

@ -1,52 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.AbstractClusteredSessionMigrationTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
/**
* ClusteredSessionMigrationTest
*/
public class ClusteredSessionMigrationTest
extends AbstractClusteredSessionMigrationTest
{
HazelcastSessionDataStoreFactory factory;
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
}
}

View File

@ -24,6 +24,7 @@ import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.AbstractClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
/**
* ClusteredSessionScavengingTest
@ -34,20 +35,27 @@ public class ClusteredSessionScavengingTest
HazelcastSessionDataStoreFactory factory;
HazelcastTestHelper _testHelper;
@Before
public void setUp()
{
_testHelper = new HazelcastTestHelper();
}
@After
public void shutdown()
{
_testHelper.tearDown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
return _testHelper.createSessionDataStoreFactory(false);
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
}
}

View File

@ -0,0 +1,157 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import static org.junit.Assert.fail;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreTest;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.server.session.UnreadableSessionDataException;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.After;
import org.junit.Before;
/**
* HazelcastSessionDataStoreTest
*
*
*/
public class HazelcastSessionDataStoreTest extends AbstractSessionDataStoreTest
{
HazelcastTestHelper _testHelper;
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return _testHelper.createSessionDataStoreFactory(false);
}
@Before
public void setUp()
{
_testHelper = new HazelcastTestHelper();
}
@After
public void shutdown()
{
_testHelper.tearDown();
}
@Override
public void persistSession(SessionData data) throws Exception
{
_testHelper.createSession(data);
}
@Override
public void persistUnreadableSession(SessionData data) throws Exception
{
//not used by testLoadSessionFails()
}
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
return _testHelper.checkSessionExists(data);
}
/**
*
* This test deliberately sets the sessionDataMap to null
* for the HazelcastSessionDataStore to provoke an exception
* in the load() method.
*/
@Override
public void testLoadSessionFails() throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
//persist a session
long now = System.currentTimeMillis();
SessionData data = store.newSessionData("222", 100, now, now-1, -1);
data.setLastNode(sessionContext.getWorkerName());
persistSession(data);
store.start();
((HazelcastSessionDataStore)store).setSessionDataMap(null);
//test that loading it fails
try
{
store.load("222");
fail("Session should be unreadable");
}
catch (UnreadableSessionDataException e)
{
//expected exception
}
}
/**
* This test currently won't work for Hazelcast - there is currently no
* means to query it to find sessions that have expired.
*
*/
@Override
public void testGetExpiredPersistedAndExpiredOnly() throws Exception
{
//ignore
}
/**
* This test currently won't work for Hazelcast - there is currently no
* means to query it to find sessions that have expired.
*/
@Override
public void testGetExpiredDifferentNode() throws Exception
{
//ignore
}
@Override
public boolean checkSessionPersisted(SessionData data) throws Exception
{
return _testHelper.checkSessionPersisted(data);
}
}

View File

@ -0,0 +1,122 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
/**
* HazelcastTestHelper
*
*
*/
public class HazelcastTestHelper
{
static String _hazelcastInstanceName = "SESSION_TEST_"+Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()));
static String _name = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
static HazelcastInstance _instance;
static {
MapConfig mapConfig = new MapConfig();
mapConfig.setName(_name);
Config config = new Config();
config.setInstanceName(_hazelcastInstanceName );
config.addMapConfig( mapConfig );
_instance = Hazelcast.getOrCreateHazelcastInstance( config );
}
public HazelcastTestHelper ()
{
// noop
}
// definitely not thread safe so tests cannot be executed in parallel
// TODO use ThreadContext variable for this Map name
public SessionDataStoreFactory createSessionDataStoreFactory(boolean onlyClient)
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
_name = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
factory.setOnlyClient( onlyClient );
factory.setMapName(_name);
factory.setHazelcastInstance(_instance);
return factory;
}
public void tearDown()
{
_instance.getMap(_name).clear();
}
public void createSession (SessionData data)
{
_instance.getMap(_name).put(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId(), data);
}
public boolean checkSessionExists (SessionData data)
{
return (_instance.getMap(_name).get(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId()) != null);
}
public boolean checkSessionPersisted (SessionData data)
{
Object obj = _instance.getMap(_name).get(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId());
if (obj == null)
return false;
SessionData saved = (SessionData)obj;
assertEquals(data.getId(),saved.getId());
assertEquals(data.getContextPath(), saved.getContextPath());
assertEquals(data.getVhost(), saved.getVhost());
assertEquals(data.getLastNode(), saved.getLastNode());
assertEquals(data.getCreated(), saved.getCreated());
assertEquals(data.getAccessed(), saved.getAccessed());
assertEquals(data.getLastAccessed(), saved.getLastAccessed());
assertEquals(data.getCookieSet(), saved.getCookieSet());
assertEquals(data.getExpiry(), saved.getExpiry());
assertEquals(data.getMaxInactiveMs(), saved.getMaxInactiveMs());
//same number of attributes
assertEquals(data.getAllAttributes().size(),saved.getAllAttributes().size());
//same keys
assertTrue(data.getKeys().equals(saved.getKeys()));
//same values
for (String name:data.getKeys())
{
assertTrue(data.getAttribute(name).equals(saved.getAttribute(name)));
}
return true;
}
}

View File

@ -1,54 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
/**
* ModifyMaxInactiveIntervalTest
*/
public class ModifyMaxInactiveIntervalTest
extends AbstractModifyMaxInactiveIntervalTest
{
HazelcastSessionDataStoreFactory factory;
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
}
}

View File

@ -1,81 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import static org.junit.Assert.*;
import java.util.concurrent.TimeUnit;
/**
* NonClusteredSessionScavengingTest
*/
public class NonClusteredSessionScavengingTest
extends AbstractNonClusteredSessionScavengingTest
{
HazelcastSessionDataStoreFactory factory;
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession( String id, boolean exists )
{
assertNotNull( _dataStore );
try
{
boolean inmap = _dataStore.exists( id );
if ( exists )
{
assertTrue( inmap );
}
else
{
assertFalse( inmap );
}
}
catch ( Exception e )
{
fail( e.getMessage() );
}
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
}
}

View File

@ -1,52 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Test;
public class SessionExpiryTest
extends AbstractSessionExpiryTest
{
HazelcastSessionDataStoreFactory factory;
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
}
}

View File

@ -1,53 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.server.session.AbstractSessionInvalidateCreateScavengeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
/**
* SessionInvalidateCreateScavengeTest
*/
public class SessionInvalidateCreateScavengeTest
extends AbstractSessionInvalidateCreateScavengeTest
{
HazelcastSessionDataStoreFactory factory;
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
factory = new HazelcastSessionDataStoreFactory();
factory.setMapName( Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) ) );
return factory;
}
@After
public void shutdown()
{
factory.getHazelcastInstance().getMap( factory.getMapName() ).clear();
}
}

View File

@ -1,71 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session.client;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractClusteredLastAccessTimeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
public class ClientLastAccessTimeTest
extends AbstractClusteredLastAccessTimeTest
{
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
}
}

View File

@ -1,75 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session.client;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
/**
* ModifyMaxInactiveIntervalTest
*/
public class ClientModifyMaxInactiveIntervalTest
extends AbstractModifyMaxInactiveIntervalTest
{
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
}
}

View File

@ -1,98 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session.client;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
import static org.junit.Assert.*;
import java.util.concurrent.TimeUnit;
public class ClientNonClusteredSessionScavengingTest
extends AbstractNonClusteredSessionScavengingTest
{
/**
* @see AbstractNonClusteredSessionScavengingTest#assertSession(String, boolean)
*/
@Override
public void assertSession( String id, boolean exists )
{
assertNotNull( _dataStore );
try
{
boolean inmap = _dataStore.exists( id );
if ( exists )
{
assertTrue( inmap );
}
else
{
assertFalse( inmap );
}
}
catch ( Exception e )
{
fail( e.getMessage() );
}
}
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
}
}

View File

@ -27,6 +27,7 @@ import com.hazelcast.core.HazelcastInstance;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.hazelcast.session.HazelcastTestHelper;
import org.eclipse.jetty.server.session.AbstractClusteredOrphanedSessionTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
@ -36,37 +37,24 @@ public class ClientOrphanedSessionTest
extends AbstractClusteredOrphanedSessionTest
{
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
HazelcastTestHelper _testHelper;
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
return _testHelper.createSessionDataStoreFactory(true);
}
@Before
public void setUp()
{
_testHelper = new HazelcastTestHelper();
}
@After
public void shutdown()
{
_testHelper.tearDown();
}
}

View File

@ -1,73 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session.client;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
public class ClientSessionExpiryTest
extends AbstractSessionExpiryTest
{
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
}
}

View File

@ -1,71 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session.client;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractSessionInvalidateCreateScavengeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
public class ClientSessionInvalidateCreateScavengeTest
extends AbstractSessionInvalidateCreateScavengeTest
{
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
}
}

View File

@ -1,74 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.hazelcast.session.client;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractClusteredSessionMigrationTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
/**
* ClusteredSessionMigrationTest
*/
public class ClientSessionMigrationTest
extends AbstractClusteredSessionMigrationTest
{
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
}
}

View File

@ -27,6 +27,7 @@ import com.hazelcast.core.HazelcastInstance;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.hazelcast.session.HazelcastTestHelper;
import org.eclipse.jetty.server.session.AbstractClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
@ -36,37 +37,23 @@ public class ClientSessionScavengingTest
extends AbstractClusteredSessionScavengingTest
{
private static final String MAP_NAME = Long.toString( TimeUnit.NANOSECONDS.toMillis(System.nanoTime()) );
HazelcastTestHelper _testHelper;
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( Long.toString( System.currentTimeMillis() ) );
// start Hazelcast instance
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
@After
public void stopHazelcast()
throws Exception
{
hazelcastInstance.shutdown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
factory.setOnlyClient( true );
factory.setMapName( MAP_NAME );
return factory;
return _testHelper.createSessionDataStoreFactory(true);
}
@Before
public void setUp()
{
_testHelper = new HazelcastTestHelper();
}
@After
public void shutdown()
{
_testHelper.tearDown();
}
}

View File

@ -1,62 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.session.infinispan.InfinispanSessionDataStoreFactory;
import org.eclipse.jetty.toolchain.test.JDK;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class ClusteredLastAccessTimeTest extends AbstractClusteredLastAccessTimeTest
{
public static InfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new InfinispanTestSupport();
__testSupport.setUseFileStore(true);
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
if (__testSupport != null)
__testSupport.teardown();
}
@Override
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
}

View File

@ -1,68 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* ClusteredSessionMigrationTest
*
*
*/
public class ClusteredSessionMigrationTest extends AbstractClusteredSessionMigrationTest
{
public static InfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new InfinispanTestSupport();
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Override
public void testSessionMigration() throws Exception
{
super.testSessionMigration();
}
}

View File

@ -20,7 +20,6 @@
package org.eclipse.jetty.server.session;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.eclipse.jetty.toolchain.test.JDK;
import org.junit.AfterClass;
import org.junit.BeforeClass;

View File

@ -0,0 +1,158 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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 static org.junit.Assert.fail;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStore;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
/**
* InfinispanSessionDataStoreTest
*
*
*/
public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
{
public InfinispanTestSupport __testSupport;
@Before
public void setup () throws Exception
{
__testSupport = new InfinispanTestSupport();
__testSupport.setup();
}
@After
public void teardown () throws Exception
{
__testSupport.teardown();
}
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Override
public void persistSession(SessionData data) throws Exception
{
__testSupport.createSession(data);
}
@Override
public void persistUnreadableSession(SessionData data) throws Exception
{
//Not used by testLoadSessionFails()
}
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
return __testSupport.checkSessionExists(data);
}
/**
* This test deliberately sets the infinispan cache to null to
* try and provoke an exception in the InfinispanSessionDataStore.load() method.
*/
@Override
public void testLoadSessionFails() throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
//persist a session
long now = System.currentTimeMillis();
SessionData data = store.newSessionData("222", 100, now, now-1, -1);
data.setLastNode(sessionContext.getWorkerName());
persistSession(data);
store.start();
((InfinispanSessionDataStore)store).setCache(null);
//test that loading it fails
try
{
store.load("222");
fail("Session should be unreadable");
}
catch (UnreadableSessionDataException e)
{
//expected exception
}
}
/**
* This test currently won't work for Infinispan - there is currently no
* means to query it to find sessions that have expired.
*
* @see org.eclipse.jetty.server.session.AbstractSessionDataStoreTest#testGetExpiredPersistedAndExpiredOnly()
*/
@Override
public void testGetExpiredPersistedAndExpiredOnly() throws Exception
{
}
/**
* This test won't work for Infinispan - there is currently no
* means to query infinispan to find other expired sessions.
*/
@Override
public void testGetExpiredDifferentNode() throws Exception
{
//Ignore
}
/**
*
*/
@Override
public boolean checkSessionPersisted(SessionData data) throws Exception
{
return __testSupport.checkSessionPersisted(data);
}
}

View File

@ -19,6 +19,9 @@
package org.eclipse.jetty.server.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.File;
import org.eclipse.jetty.util.IO;
@ -104,6 +107,7 @@ public class InfinispanTestSupport
public void teardown () throws Exception
{
_cache.clear();
_manager.removeCache(_name);
if (_useFileStore)
{
@ -113,4 +117,62 @@ public class InfinispanTestSupport
}
}
}
@SuppressWarnings("unchecked")
public void createSession (SessionData data)
throws Exception
{
_cache.put(data.getContextPath()+"_"+data.getVhost()+"_"+data.getId(), data);
}
public void createUnreadableSession (SessionData data)
{
}
public boolean checkSessionExists (SessionData data)
throws Exception
{
return (_cache.get(data.getContextPath()+"_"+data.getVhost()+"_"+data.getId()) != null);
}
public boolean checkSessionPersisted (SessionData data)
throws Exception
{
Object obj = _cache.get(data.getContextPath()+"_"+data.getVhost()+"_"+data.getId());
if (obj == null)
return false;
SessionData saved = (SessionData)obj;
//turn an Entity into a Session
assertEquals(data.getId(), saved.getId());
assertEquals(data.getContextPath(), saved.getContextPath());
assertEquals(data.getVhost(), saved.getVhost());
assertEquals(data.getAccessed(), saved.getAccessed());
assertEquals(data.getLastAccessed(), saved.getLastAccessed());
assertEquals(data.getCreated(), saved.getCreated());
assertEquals(data.getCookieSet(), saved.getCookieSet());
assertEquals(data.getLastNode(), saved.getLastNode());
//don't test lastSaved, because that is set only on the SessionData after it returns from SessionDataStore.save()
assertEquals(data.getExpiry(), saved.getExpiry());
assertEquals(data.getMaxInactiveMs(), saved.getMaxInactiveMs());
//same number of attributes
assertEquals(data.getAllAttributes().size(), saved.getAllAttributes().size());
//same keys
assertTrue(data.getKeys().equals(saved.getKeys()));
//same values
for (String name:data.getKeys())
{
assertTrue(data.getAttribute(name).equals(saved.getAttribute(name)));
}
return true;
}
}

View File

@ -1,61 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* ModifyMaxInactiveIntervalTest
*
*
*/
public class ModifyMaxInactiveIntervalTest extends AbstractModifyMaxInactiveIntervalTest
{
public static InfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new InfinispanTestSupport();
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
}

View File

@ -1,91 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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 static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* NonClusteredSessionScavengingTest
*
*
*/
public class NonClusteredSessionScavengingTest extends AbstractNonClusteredSessionScavengingTest
{
public static InfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new InfinispanTestSupport();
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession(String id, boolean exists)
{
assertNotNull(_dataStore);
try
{
boolean inmap = _dataStore.exists(id);
if (exists)
assertTrue(inmap);
else
assertFalse(inmap);
}
catch (Exception e)
{
fail(e.getMessage());
}
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
}

View File

@ -1,76 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class SessionExpiryTest extends AbstractSessionExpiryTest
{
public static InfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new InfinispanTestSupport();
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Test
@Override
public void testSessionNotExpired() throws Exception
{
super.testSessionNotExpired();
}
@Test
@Override
public void testSessionExpiry() throws Exception
{
super.testSessionExpiry();
}
@Override
public void verifySessionDestroyed (TestHttpSessionListener listener, String sessionId)
{
//noop - sessions that expired when the InfinispanSessionManager was not running are not reloaded and do not have their listeners called on them.
}
}

View File

@ -1,70 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* SessionInvalidateCreateScavengeTest
*
*
*/
public class SessionInvalidateCreateScavengeTest extends AbstractSessionInvalidateCreateScavengeTest
{
public static InfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new InfinispanTestSupport();
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Override
public void testSessionScavenge() throws Exception
{
super.testSessionScavenge();
}
}

View File

@ -1,63 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.remote;
import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* ModifyMaxInactiveIntervalTest
*
*
*/
public class ModifyMaxInactiveIntervalTest extends AbstractModifyMaxInactiveIntervalTest
{
public static RemoteInfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new RemoteInfinispanTestSupport("remote-session-test");
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
}

View File

@ -1,94 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.remote;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* NonClusteredSessionScavengingTest
*
*
*/
public class NonClusteredSessionScavengingTest extends AbstractNonClusteredSessionScavengingTest
{
public static RemoteInfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new RemoteInfinispanTestSupport("remote-session-test");
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession(String id, boolean exists)
{
assertNotNull(_dataStore);
try
{
boolean inmap = _dataStore.exists(id);
if (exists)
assertTrue(inmap);
else
assertFalse(inmap);
}
catch (Exception e)
{
fail(e.getMessage());
}
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
}

View File

@ -1,65 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.remote;
import org.eclipse.jetty.server.session.AbstractClusteredLastAccessTimeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class RemoteClusteredLastAccessTimeTest extends AbstractClusteredLastAccessTimeTest
{
public static RemoteInfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new RemoteInfinispanTestSupport("remote-session-test");
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Override
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();
}
}

View File

@ -1,71 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.remote;
import org.eclipse.jetty.server.session.AbstractClusteredSessionMigrationTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* RemoteClusteredSessionMigrationTest
*
*
*/
public class RemoteClusteredSessionMigrationTest extends AbstractClusteredSessionMigrationTest
{
public static RemoteInfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new RemoteInfinispanTestSupport("remote-session-test");
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Override
public void testSessionMigration() throws Exception
{
super.testSessionMigration();
}
}

View File

@ -0,0 +1,169 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.remote;
import static org.junit.Assert.fail;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreTest;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.server.session.UnreadableSessionDataException;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStore;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
/**
* RemoteInfinispanSessionDataStoreTest
*
*
*/
public class RemoteInfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
{
public static RemoteInfinispanTestSupport __testSupport;
@Before
public void setup () throws Exception
{
__testSupport = new RemoteInfinispanTestSupport("remote-session-test");
__testSupport.setup();
}
@After
public void teardown () throws Exception
{
__testSupport.teardown();
}
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Override
public void persistSession(SessionData data) throws Exception
{
__testSupport.createSession(data);
}
@Override
public void persistUnreadableSession(SessionData data) throws Exception
{
//Not used by testLoadSessionFails()
}
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
return __testSupport.checkSessionExists(data);
}
@Override
public boolean checkSessionPersisted(SessionData data) throws Exception
{
return __testSupport.checkSessionPersisted(data);
}
/**
* This test currently won't work for Infinispan - there is currently no
* means to query it to find sessions that have expired.
*
* @see org.eclipse.jetty.server.session.AbstractSessionDataStoreTest#testGetExpiredPersistedAndExpiredOnly()
*/
@Override
public void testGetExpiredPersistedAndExpiredOnly() throws Exception
{
}
/**
* This test won't work for Infinispan - there is currently no
* means to query infinispan to find other expired sessions.
*/
@Override
public void testGetExpiredDifferentNode() throws Exception
{
//Ignore
}
/**
* This test deliberately sets the infinispan cache to null to
* try and provoke an exception in the InfinispanSessionDataStore.load() method.
*/
@Override
public void testLoadSessionFails() throws Exception
{
//create the SessionDataStore
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/test");
SessionDataStoreFactory factory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
SessionContext sessionContext = new SessionContext("foo", context.getServletContext());
store.initialize(sessionContext);
//persist a session
long now = System.currentTimeMillis();
SessionData data = store.newSessionData("222", 100, now, now-1, -1);
data.setLastNode(sessionContext.getWorkerName());
persistSession(data);
store.start();
((InfinispanSessionDataStore)store).setCache(null);
//test that loading it fails
try
{
store.load("222");
fail("Session should be unreadable");
}
catch (UnreadableSessionDataException e)
{
//expected exception
}
}
}

View File

@ -19,6 +19,10 @@
package org.eclipse.jetty.server.session.remote;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import org.eclipse.jetty.server.session.SessionData;
import org.infinispan.client.hotrod.RemoteCache;
import org.infinispan.client.hotrod.RemoteCacheManager;
@ -73,7 +77,65 @@ public class RemoteInfinispanTestSupport
public void teardown () throws Exception
{
_cache.clear();
}
@SuppressWarnings("unchecked")
public void createSession (SessionData data)
throws Exception
{
_cache.put(data.getContextPath()+"_"+data.getVhost()+"_"+data.getId(), data);
}
public void createUnreadableSession (SessionData data)
{
}
public boolean checkSessionExists (SessionData data)
throws Exception
{
return (_cache.get(data.getContextPath()+"_"+data.getVhost()+"_"+data.getId()) != null);
}
public boolean checkSessionPersisted (SessionData data)
throws Exception
{
Object obj = _cache.get(data.getContextPath()+"_"+data.getVhost()+"_"+data.getId());
if (obj == null)
return false;
SessionData saved = (SessionData)obj;
assertEquals(data.getId(), saved.getId());
assertEquals(data.getContextPath(), saved.getContextPath());
assertEquals(data.getVhost(), saved.getVhost());
assertEquals(data.getAccessed(), saved.getAccessed());
assertEquals(data.getLastAccessed(), saved.getLastAccessed());
assertEquals(data.getCreated(), saved.getCreated());
assertEquals(data.getCookieSet(), saved.getCookieSet());
assertEquals(data.getLastNode(), saved.getLastNode());
//don't test lastSaved because that is set on SessionData only after return from SessionDataStore.save()
assertEquals(data.getExpiry(), saved.getExpiry());
assertEquals(data.getMaxInactiveMs(), saved.getMaxInactiveMs());
//same number of attributes
assertEquals(data.getAllAttributes().size(), saved.getAllAttributes().size());
//same keys
assertTrue(data.getKeys().equals(saved.getKeys()));
//same values
for (String name:data.getKeys())
{
assertTrue(data.getAttribute(name).equals(saved.getAttribute(name)));
}
return true;
}
}

View File

@ -1,78 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.remote;
import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class RemoteSessionExpiryTest extends AbstractSessionExpiryTest
{
public static RemoteInfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new RemoteInfinispanTestSupport("remote-session-test");
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Test
@Override
public void testSessionNotExpired() throws Exception
{
super.testSessionNotExpired();
}
@Test
@Override
public void testSessionExpiry() throws Exception
{
super.testSessionExpiry();
}
@Override
public void verifySessionDestroyed (TestHttpSessionListener listener, String sessionId)
{
//noop - sessions that expired when the InfinispanSessionManager was not running are not reloaded and do not have their listeners called on them.
}
}

View File

@ -1,72 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.remote;
import org.eclipse.jetty.server.session.AbstractSessionInvalidateCreateScavengeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* SessionInvalidateCreateScavengeTest
*
*
*/
public class RemoteSessionInvalidateCreateScavengeTest extends AbstractSessionInvalidateCreateScavengeTest
{
public static RemoteInfinispanTestSupport __testSupport;
@BeforeClass
public static void setup () throws Exception
{
__testSupport = new RemoteInfinispanTestSupport("remote-session-test");
__testSupport.setup();
}
@AfterClass
public static void teardown () throws Exception
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
factory.setCache(__testSupport.getCache());
return factory;
}
@Override
public void testSessionScavenge() throws Exception
{
super.testSessionScavenge();
}
}

View File

@ -28,13 +28,6 @@ import org.junit.Test;
public class ClusteredInvalidationSessionTest extends AbstractClusteredInvalidationSessionTest
{
@Test
@Override
public void testInvalidation() throws Exception
{
super.testInvalidation();
}
@After
public void tearDown() throws Exception

View File

@ -1,50 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.junit.After;
import org.junit.Test;
/**
* ClusteredLastAccessTimeTest
*/
public class ClusteredLastAccessTimeTest extends AbstractClusteredLastAccessTimeTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return JdbcTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();
}
@After
public void tearDown() throws Exception
{
JdbcTestHelper.shutdown(null);
}
}

View File

@ -35,12 +35,7 @@ public class ClusteredOrphanedSessionTest extends AbstractClusteredOrphanedSessi
return JdbcTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testOrphanedSession() throws Exception
{
super.testOrphanedSession();
}
@After
public void tearDown() throws Exception

View File

@ -18,33 +18,152 @@
package org.eclipse.jetty.server.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.junit.After;
import org.junit.Test;
/**
* ClusteredSessionMigrationTest
*
* Test that a session that is active on node 1 can be loaded by node 2.
*
* This test is applicable to any of the SessionDataStores that support
* clustering, but does not test the actual SessionDataStore itself.
* Rather, it tests all of the machinery above the SessionDataStore. Thus,
* to reduce test time, we only apply it to the JDBCSessionDataStore.
*/
public class ClusteredSessionMigrationTest extends AbstractClusteredSessionMigrationTest
public class ClusteredSessionMigrationTest extends AbstractTestBase
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return JdbcTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testSessionMigration() throws Exception
{
super.testSessionMigration();
}
@After
public void tearDown() throws Exception
{
JdbcTestHelper.shutdown(null);
}
@Test
public void testSessionMigration() throws Exception
{
String contextPath = "/";
String servletMapping = "/server";
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
SessionDataStoreFactory storeFactory = createSessionDataStoreFactory();
((AbstractSessionDataStoreFactory)storeFactory).setGracePeriodSec(TestServer.DEFAULT_SCAVENGE_SEC);
TestServer server1 = new TestServer(0, TestServer.DEFAULT_MAX_INACTIVE, TestServer.DEFAULT_SCAVENGE_SEC,
cacheFactory, storeFactory);
server1.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
try
{
server1.start();
int port1=server1.getPort();
TestServer server2 = new TestServer(0, TestServer.DEFAULT_MAX_INACTIVE, TestServer.DEFAULT_SCAVENGE_SEC,
cacheFactory, storeFactory);
server2.addContext(contextPath).addServlet(TestServlet.class, servletMapping);
try
{
server2.start();
int port2=server2.getPort();
HttpClient client = new HttpClient();
client.start();
try
{
// Perform one request to server1 to create a session
int value = 1;
Request request1 = client.POST("http://localhost:" + port1 + contextPath + servletMapping.substring(1) + "?action=set&value=" + value);
ContentResponse response1 = request1.send();
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
String sessionCookie = response1.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null);
// Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
// Perform a request to server2 using the session cookie from the previous request
// This should migrate the session from server1 to server2.
Request request2 = client.newRequest("http://localhost:" + port2 + contextPath + servletMapping.substring(1) + "?action=get");
request2.header("Cookie", sessionCookie);
ContentResponse response2 = request2.send();
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
String response = response2.getContentAsString();
assertEquals(response.trim(),String.valueOf(value)); }
finally
{
client.stop();
}
}
finally
{
server2.stop();
}
}
finally
{
server1.stop();
}
}
public static class TestServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
doPost(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
HttpSession session = request.getSession(false);
String action = request.getParameter("action");
if ("set".equals(action))
{
if (session == null) session = request.getSession(true);
int value = Integer.parseInt(request.getParameter("value"));
session.setAttribute("value", value);
PrintWriter writer = response.getWriter();
writer.println(value);
writer.flush();
}
else if ("get".equals(action))
{
int value = (Integer)session.getAttribute("value");
int x = session.getMaxInactiveInterval();
assertTrue(x > 0);
PrintWriter writer = response.getWriter();
writer.println(value);
writer.flush();
}
}
}
}

View File

@ -19,31 +19,12 @@
package org.eclipse.jetty.server.session;
import org.junit.After;
import org.junit.Test;
/**
* ClusteredSessionScavengingTest
*/
public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScavengingTest
{
@Override
public void pause (int scavenge)
{
//Wait a little longer for the scavenging to happen with the JDBCSession handling.
//The scavenging happens at about +10% longer than the scavenge interval, so that
//not all nodes sync up and start trying to scavenge for the same sessions at the
//same time.
//So, we wait 3 times the scavenging interval.
try
{
Thread.sleep(scavenge * 3000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@ -53,21 +34,6 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav
return JdbcTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testNoScavenging() throws Exception
{
super.testNoScavenging();
}
@Test
@Override
public void testLocalSessionsScavenging() throws Exception
{
super.testLocalSessionsScavenging();
}
@After
public void tearDown() throws Exception

View File

@ -0,0 +1,95 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.junit.After;
import org.junit.Before;
/**
* JDBCSessionDataStoreTest
*
*
*/
public class JDBCSessionDataStoreTest extends AbstractSessionDataStoreTest
{
@Before
public void setUp() throws Exception
{
JdbcTestHelper.prepareTables();
}
@After
public void tearDown() throws Exception
{
JdbcTestHelper.shutdown(null);
}
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return JdbcTestHelper.newSessionDataStoreFactory();
}
@Override
public void persistSession(SessionData data)
throws Exception
{
JdbcTestHelper.insertSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(),
data.getCreated(), data.getAccessed(), data.getLastAccessed(),
data.getMaxInactiveMs(), data.getExpiry(), data.getCookieSet(),
data.getLastSaved(), data.getAllAttributes());
}
@Override
public void persistUnreadableSession(SessionData data) throws Exception
{
JdbcTestHelper.insertSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(),
data.getCreated(), data.getAccessed(), data.getLastAccessed(),
data.getMaxInactiveMs(), data.getExpiry(), data.getCookieSet(),
data.getLastSaved(), null);
}
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
return JdbcTestHelper.existsInSessionTable(data.getId(), false);
}
@Override
public boolean checkSessionPersisted(SessionData data) throws Exception
{
return JdbcTestHelper.checkSessionPersisted(data);
}
}

View File

@ -20,19 +20,25 @@ 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.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
/**
* JdbcTestHelper
@ -124,6 +130,18 @@ public class JdbcTestHelper
sessionTableSchema.setMaxIntervalColumn(MAX_IDLE_COL);
return sessionTableSchema;
}
public static void prepareTables () throws SQLException
{
DatabaseAdaptor da = new DatabaseAdaptor();
da.setDriverInfo(DRIVER_CLASS, DEFAULT_CONNECTION_URL);
JDBCSessionDataStore.SessionTableSchema sessionTableSchema = newSessionTableSchema();
sessionTableSchema.setDatabaseAdaptor(da);
sessionTableSchema.prepareTables();
}
public static boolean existsInSessionTable(String id, boolean verbose)
throws Exception
@ -158,6 +176,71 @@ public class JdbcTestHelper
}
@SuppressWarnings("unchecked")
public static boolean checkSessionPersisted (SessionData data)
throws Exception
{
Class.forName(DRIVER_CLASS);
PreparedStatement statement = null;
ResultSet result = null;
try (Connection con=DriverManager.getConnection(DEFAULT_CONNECTION_URL);)
{
statement = con.prepareStatement("select * from "+TABLE+
" where "+ID_COL+" = ? and "+CONTEXT_COL+
" = ? and virtualHost = ?");
statement.setString(1, data.getId());
statement.setString(2, data.getContextPath());
statement.setString(3, data.getVhost());
result = statement.executeQuery();
if (!result.next())
return false;
assertEquals(data.getCreated(),result.getLong(CREATE_COL));
assertEquals(data.getAccessed(), result.getLong(ACCESS_COL));
assertEquals(data.getLastAccessed(), result.getLong(LAST_ACCESS_COL));
assertEquals(data.getMaxInactiveMs(), result.getLong(MAX_IDLE_COL));
assertEquals(data.getCookieSet(), result.getLong(COOKIE_COL));
assertEquals(data.getLastNode(), result.getString(LAST_NODE_COL));
assertEquals(data.getExpiry(), result.getLong(EXPIRY_COL));
assertEquals(data.getContextPath(), result.getString(CONTEXT_COL));
assertEquals(data.getVhost(), result.getString("virtualHost"));
Map<String,Object> attributes = new HashMap<>();
Blob blob = result.getBlob(MAP_COL);
try (InputStream is = blob.getBinaryStream();
ClassLoadingObjectInputStream ois = new ClassLoadingObjectInputStream(is))
{
Object o = ois.readObject();
attributes.putAll((Map<String,Object>)o);
}
//same number of attributes
assertEquals(data.getAllAttributes().size(), attributes.size());
//same keys
assertTrue(data.getKeys().equals(attributes.keySet()));
//same values
for (String name:data.getKeys())
{
assertTrue(data.getAttribute(name).equals(attributes.get(name)));
}
}
finally
{
if (result != null)
result.close();
if (statement != null)
statement.close();
}
return true;
}
public static void insertSession (String id, String contextPath, String vhost)
throws Exception
{
@ -189,6 +272,58 @@ public class JdbcTestHelper
}
public static void insertSession (String id, String contextPath, String vhost,
String lastNode, long created, long accessed,
long lastAccessed, long maxIdle, long expiry,
long cookieSet, long lastSaved, Map<String,Object> attributes)
throws Exception
{
Class.forName(DRIVER_CLASS);
try (Connection con=DriverManager.getConnection(DEFAULT_CONNECTION_URL);)
{
PreparedStatement statement = con.prepareStatement("insert into "+TABLE+
" ("+ID_COL+", "+CONTEXT_COL+", virtualHost, "+LAST_NODE_COL+
", "+ACCESS_COL+", "+LAST_ACCESS_COL+", "+CREATE_COL+", "+COOKIE_COL+
", "+LAST_SAVE_COL+", "+EXPIRY_COL+", "+MAX_IDLE_COL+","+MAP_COL+" ) "+
" values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
statement.setString(1, id);
statement.setString(2, contextPath);
statement.setString(3, vhost);
statement.setString(4, lastNode);
statement.setLong(5, accessed);
statement.setLong(6, lastAccessed);
statement.setLong(7, created);
statement.setLong(8, cookieSet);
statement.setLong(9, lastSaved);
statement.setLong(10, expiry);
statement.setLong(11, maxIdle);
if (attributes != null)
{
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(baos);
Map<String,Object> emptyMap = Collections.emptyMap();
oos.writeObject(emptyMap);
oos.flush();
byte[] bytes = baos.toByteArray();
ByteArrayInputStream bais = new ByteArrayInputStream(bytes);
statement.setBinaryStream(12, bais, bytes.length);//attribute map as blob
}
else
statement.setBinaryStream(12, new ByteArrayInputStream("".getBytes()), 0);
statement.execute();
assertEquals(1,statement.getUpdateCount());
}
}
public static Set<String> getSessionIds ()
throws Exception
{

View File

@ -1,74 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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 static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import org.junit.After;
import org.junit.Test;
/**
* NonClusteredSessionScavengingTest
*/
public class NonClusteredSessionScavengingTest extends AbstractNonClusteredSessionScavengingTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return JdbcTestHelper.newSessionDataStoreFactory();
}
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession(String id, boolean exists)
{
try
{
boolean inDb = JdbcTestHelper.existsInSessionTable(id, false);
if (exists)
assertTrue(inDb);
else
assertFalse(inDb);
}
catch (Exception e)
{
fail(e.getMessage());
}
}
@After
public void tearDown() throws Exception
{
JdbcTestHelper.shutdown(null);
}
}

View File

@ -1,69 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.servlet.ServletContextHandler;
import org.junit.After;
import org.junit.Test;
/**
* ProxySerializationTest
*
*
*/
public class ProxySerializationTest extends AbstractProxySerializationTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return JdbcTestHelper.newSessionDataStoreFactory();
}
/**
* @see org.eclipse.jetty.server.session.AbstractProxySerializationTest#customizeContext(org.eclipse.jetty.servlet.ServletContextHandler)
*/
@Override
public void customizeContext(ServletContextHandler c)
{
}
@Test
@Override
public void testProxySerialization() throws Exception
{
super.testProxySerialization();
}
@After
public void tearDown() throws Exception
{
JdbcTestHelper.shutdown(null);
}
}

View File

@ -19,9 +19,9 @@
package org.eclipse.jetty.server.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.assertFalse;
import java.io.File;
import java.io.FileWriter;

View File

@ -1,80 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.util.log.Log;
import org.eclipse.jetty.util.log.StacklessLogging;
import org.junit.After;
import org.junit.Test;
/**
* SessionExpiryTest
*
*
*
*/
public class SessionExpiryTest extends AbstractSessionExpiryTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return JdbcTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testSessionExpiry() throws Exception
{
try(StacklessLogging stackless=new StacklessLogging(Log.getLogger("org.eclipse.jetty.server.session")))
{
super.testSessionExpiry();
}
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionExpiryTest#testSessionExpiresWithListener()
*/
@Test
@Override
public void testSessionExpiresWithListener() throws Exception
{
super.testSessionExpiresWithListener();
}
@Test
@Override
public void testSessionNotExpired() throws Exception
{
super.testSessionNotExpired();
}
@After
public void tearDown() throws Exception
{
JdbcTestHelper.shutdown(null);
}
}

View File

@ -1,52 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 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.junit.After;
import org.junit.Test;
public class SessionInvalidateCreateScavengeTest extends AbstractSessionInvalidateCreateScavengeTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return JdbcTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testSessionScavenge() throws Exception
{
super.testSessionScavenge();
}
@After
public void tearDown() throws Exception
{
JdbcTestHelper.shutdown(null);
}
}

View File

@ -42,7 +42,6 @@ public class WebAppObjectInSessionTest extends AbstractWebAppObjectInSessionTest
@Test
@Override
public void testWebappObjectInSession() throws Exception
{
super.testWebappObjectInSession();

View File

@ -11,6 +11,7 @@
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.sessions.mongo</bundle-symbolic-name>
<embedmongo.host>localhost</embedmongo.host>
</properties>
<build>
<plugins>
@ -110,9 +111,50 @@
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<systemPropertyVariables>
<embedmongoPort>${embedmongo.port}</embedmongoPort>
<embedmongoHost>${embedmongo.host}</embedmongoHost>
</systemPropertyVariables>
<skipTests>false</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>com.github.joelittlejohn.embedmongo</groupId>
<artifactId>embedmongo-maven-plugin</artifactId>
<version>0.3.5</version>
<configuration>
<!--port>37017</port-->
<!-- allocates a random port and overrides embedmongo.port -->
<randomPort>true</randomPort>
<databaseDirectory>${project.build.directory}/mongotest</databaseDirectory>
<!-- optional (file|console|none), default console -->
<logging>file</logging>
<!-- optional, can be used when logging=file, default is ./embedmongo.log -->
<logFile>${project.build.directory}/embedmongo.log</logFile>
<!--optional, one of wiredTiger or mmapv1 (default is mmapv1) -->
<!--storageEngine>wiredTiger</storageEngine-->
<!-- optional, skips this plugin entirely, use on the command line like -Dembedmongo.skip -->
<skip>false</skip>
</configuration>
<executions>
<execution>
<id>start</id>
<phase>process-test-classes</phase>
<goals>
<goal>start</goal>
</goals>
</execution>
<execution>
<id>stop</id>
<phase>test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

View File

@ -117,7 +117,7 @@ public class AttributeNameTest
//Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=","$1\\$Path=");
//Make a request to the 2nd server which will do a refresh, use TestServlet to ensure that the
//Make a request to the 2nd server which will do a refresh, use TestFooServlet to ensure that the
//session attribute with dotted name is not removed
Request request2 = client.newRequest("http://localhost:" + port2 + contextPath + servletMapping + "?action=get");
request2.header("Cookie", sessionCookie);

View File

@ -1,64 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import org.eclipse.jetty.server.session.AbstractClusteredLastAccessTimeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class ClusteredLastAccessTimeTest extends AbstractClusteredLastAccessTimeTest
{
@BeforeClass
public static void beforeClass() throws Exception
{
MongoTestHelper.dropCollection();
MongoTestHelper.createCollection();
}
@AfterClass
public static void afterClass() throws Exception
{
MongoTestHelper.dropCollection();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return MongoTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();
}
}

View File

@ -1,61 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import org.eclipse.jetty.server.session.AbstractClusteredSessionMigrationTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class ClusteredSessionMigrationTest extends AbstractClusteredSessionMigrationTest
{
@BeforeClass
public static void beforeClass() throws Exception
{
MongoTestHelper.dropCollection();
MongoTestHelper.createCollection();
}
@AfterClass
public static void afterClass() throws Exception
{
MongoTestHelper.dropCollection();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return MongoTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testSessionMigration() throws Exception
{
super.testSessionMigration();
}
}

View File

@ -49,13 +49,4 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav
return MongoTestHelper.newSessionDataStoreFactory();
}
@Override
public void testLocalSessionsScavenging() throws Exception
{
super.testLocalSessionsScavenging();
}
}

View File

@ -1,57 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* ModifyMaxInactiveIntervalTest
*
*
*/
public class ModifyMaxInactiveIntervalTest extends AbstractModifyMaxInactiveIntervalTest
{
@BeforeClass
public static void beforeClass() throws Exception
{
MongoTestHelper.dropCollection();
MongoTestHelper.createCollection();
}
@AfterClass
public static void afterClass() throws Exception
{
MongoTestHelper.dropCollection();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return MongoTestHelper.newSessionDataStoreFactory();
}
}

View File

@ -0,0 +1,84 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreTest;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
/**
* MongoSessionDataStoreTest
*
*
*/
public class MongoSessionDataStoreTest extends AbstractSessionDataStoreTest
{
@Before
public void beforeClass() throws Exception
{
MongoTestHelper.dropCollection();
MongoTestHelper.createCollection();
}
@After
public void afterClass() throws Exception
{
MongoTestHelper.dropCollection();
}
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return MongoTestHelper.newSessionDataStoreFactory();
}
@Override
public void persistSession(SessionData data) throws Exception
{
MongoTestHelper.createSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(), data.getAllAttributes());
}
@Override
public void persistUnreadableSession(SessionData data) throws Exception
{
MongoTestHelper.createUnreadableSession(data.getId(), data.getContextPath(), data.getVhost(), data.getLastNode(), data.getCreated(),
data.getAccessed(), data.getLastAccessed(), data.getMaxInactiveMs(), data.getExpiry(), null);
}
@Override
public boolean checkSessionExists(SessionData data) throws Exception
{
return MongoTestHelper.checkSessionExists(data.getId());
}
@Override
public boolean checkSessionPersisted(SessionData data) throws Exception
{
return MongoTestHelper.checkSessionPersisted(data);
}
}

View File

@ -1,64 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import java.util.Set;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.WriteResult;
public class MongoTest
{
public static void main(String... args) throws Exception
{
Mongo m = new Mongo( "127.0.0.1" , 27017 );
DB db = m.getDB( "mydb" );
Set<String> colls = db.getCollectionNames();
System.err.println("Colls="+colls);
DBCollection coll = db.getCollection("testCollection");
BasicDBObject key = new BasicDBObject("id","1234");
BasicDBObject sets = new BasicDBObject("name","value");
BasicDBObject upsert=new BasicDBObject("$set",sets);
WriteResult result =coll.update(key,upsert,true,false);
System.err.println(result.getLastError());
while (coll.count()>0)
{
DBObject docZ = coll.findOne();
System.err.println("removing "+ docZ);
if (docZ!=null)
coll.remove(docZ);
}
}
}

View File

@ -18,11 +18,30 @@
package org.eclipse.jetty.nosql.mongodb;
import java.net.UnknownHostException;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.net.UnknownHostException;
import java.sql.Date;
import java.util.HashMap;
import java.util.Map;
import com.mongodb.MongoClient;
import org.eclipse.jetty.nosql.NoSqlSessionDataStore.NoSqlSessionData;
import org.eclipse.jetty.server.session.SessionData;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
import com.mongodb.WriteConcern;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
@ -31,35 +50,240 @@ import com.mongodb.MongoException;
*/
public class MongoTestHelper
{
private final static Logger LOG = Log.getLogger(MongoTestHelper.class);
static int __workers=0;
public static final String DB_NAME = "HttpSessions";
public static final String COLLECTION_NAME = "testsessions";
static MongoClient _mongoClient;
static
{
try
{
_mongoClient =
new MongoClient( System.getProperty( "embedmongo.host" ), Integer.getInteger( "embedmongoPort" ) );
}
catch ( UnknownHostException e )
{
e.printStackTrace();
}
}
public static void dropCollection () throws MongoException, UnknownHostException
{
new Mongo().getDB(DB_NAME).getCollection(COLLECTION_NAME).drop();
_mongoClient.getDB(DB_NAME).getCollection(COLLECTION_NAME).drop();
}
public static void createCollection() throws UnknownHostException, MongoException
{
new Mongo().getDB(DB_NAME).createCollection(COLLECTION_NAME, null);
_mongoClient.getDB(DB_NAME).createCollection(COLLECTION_NAME, null);
}
public static DBCollection getCollection () throws UnknownHostException, MongoException
{
return new Mongo().getDB(DB_NAME).getCollection(COLLECTION_NAME);
return _mongoClient.getDB(DB_NAME).getCollection(COLLECTION_NAME);
}
public static MongoSessionDataStoreFactory newSessionDataStoreFactory()
{
MongoSessionDataStoreFactory storeFactory = new MongoSessionDataStoreFactory();
storeFactory.setHost( System.getProperty( "embedmongoHost" ) );
storeFactory.setPort( Integer.getInteger( "embedmongoPort" ) );
storeFactory.setCollectionName(COLLECTION_NAME);
storeFactory.setDbName(DB_NAME);
return storeFactory;
}
public static boolean checkSessionExists (String id)
throws Exception
{
DBCollection collection = _mongoClient.getDB(DB_NAME).getCollection(COLLECTION_NAME);
DBObject fields = new BasicDBObject();
fields.put(MongoSessionDataStore.__EXPIRY, 1);
fields.put(MongoSessionDataStore.__VALID, 1);
DBObject sessionDocument = collection.findOne(new BasicDBObject(MongoSessionDataStore.__ID, id), fields);
if (sessionDocument == null)
return false; //doesn't exist
return true;
}
public static boolean checkSessionPersisted (SessionData data)
throws Exception
{
DBCollection collection = _mongoClient.getDB(DB_NAME).getCollection(COLLECTION_NAME);
DBObject fields = new BasicDBObject();
DBObject sessionDocument = collection.findOne(new BasicDBObject(MongoSessionDataStore.__ID, data.getId()), fields);
if (sessionDocument == null)
return false; //doesn't exist
LOG.info("{}",sessionDocument);
Boolean valid = (Boolean)sessionDocument.get(MongoSessionDataStore.__VALID);
if (valid == null || !valid)
return false;
Long created = (Long)sessionDocument.get(MongoSessionDataStore.__CREATED);
Long accessed = (Long)sessionDocument.get(MongoSessionDataStore.__ACCESSED);
Long lastAccessed = (Long)sessionDocument.get(MongoSessionDataStore.__LAST_ACCESSED);
Long maxInactive = (Long)sessionDocument.get(MongoSessionDataStore.__MAX_IDLE);
Long expiry = (Long)sessionDocument.get(MongoSessionDataStore.__EXPIRY);
Object version = MongoUtils.getNestedValue(sessionDocument,
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() +"."+MongoSessionDataStore.__VERSION);
Long lastSaved = (Long)MongoUtils.getNestedValue(sessionDocument,
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() +"."+MongoSessionDataStore.__LASTSAVED);
String lastNode = (String)MongoUtils.getNestedValue(sessionDocument,
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath() +"."+MongoSessionDataStore.__LASTNODE);
LOG.info("DA:{} MA:{}", data.getAccessed(), accessed);
LOG.info("DLA:{} DLA:{}",data.getLastAccessed(),lastAccessed);
assertEquals(data.getCreated(), created.longValue());
assertEquals(data.getAccessed(), accessed.longValue());
assertEquals(data.getLastAccessed(), lastAccessed.longValue());
assertEquals(data.getMaxInactiveMs(), maxInactive.longValue());
assertEquals(data.getExpiry(), expiry.longValue());
assertEquals(data.getLastNode(), lastNode);
assertNotNull(version);
assertNotNull(lastSaved);
// get the session for the context
DBObject sessionSubDocumentForContext =
(DBObject)MongoUtils.getNestedValue(sessionDocument,
MongoSessionDataStore.__CONTEXT + "." + data.getVhost().replace('.', '_') + ":" + data.getContextPath());
assertNotNull(sessionSubDocumentForContext);
Map<String,Object> attributes = new HashMap<>();
for (String name : sessionSubDocumentForContext.keySet())
{
//skip special metadata attribute which is not one of the actual session attributes
if (MongoSessionDataStore.__METADATA.equals(name) )
continue;
String attr = MongoUtils.decodeName(name);
Object value = MongoUtils.decodeValue(sessionSubDocumentForContext.get(name));
attributes.put(attr, value);
}
//same keys
assertTrue(data.getKeys().equals(attributes.keySet()));
//same values
for (String name:data.getKeys())
{
assertTrue(data.getAttribute(name).equals(attributes.get(name)));
}
return true;
}
public static void createUnreadableSession (String id, String contextPath, String vhost,
String lastNode, long created, long accessed,
long lastAccessed, long maxIdle, long expiry,
Map<String,Object> attributes)
throws Exception
{
DBCollection collection = _mongoClient.getDB(DB_NAME).getCollection(COLLECTION_NAME);
// Form query for upsert
BasicDBObject key = new BasicDBObject(MongoSessionDataStore.__ID, id);
// Form updates
BasicDBObject update = new BasicDBObject();
boolean upsert = false;
BasicDBObject sets = new BasicDBObject();
Object version = new Long(1);
// New session
upsert = true;
sets.put(MongoSessionDataStore.__CREATED,created);
sets.put(MongoSessionDataStore.__VALID,true);
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__VERSION,version);
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__LASTSAVED, System.currentTimeMillis());
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__LASTNODE, lastNode);
//Leaving out __MAX_IDLE to make it an invalid session object!
sets.put(MongoSessionDataStore.__EXPIRY, expiry);
sets.put(MongoSessionDataStore.__ACCESSED, accessed);
sets.put(MongoSessionDataStore.__LAST_ACCESSED, lastAccessed);
if (attributes != null)
{
for (String name : attributes.keySet())
{
Object value = attributes.get(name);
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath+ "." + MongoUtils.encodeName(name),
MongoUtils.encodeName(value));
}
}
update.put("$set",sets);
collection.update(key,update,upsert,false,WriteConcern.SAFE);
}
public static void createSession (String id, String contextPath, String vhost,
String lastNode, long created, long accessed,
long lastAccessed, long maxIdle, long expiry,
Map<String,Object> attributes)
throws Exception
{
DBCollection collection = _mongoClient.getDB(DB_NAME).getCollection(COLLECTION_NAME);
// Form query for upsert
BasicDBObject key = new BasicDBObject(MongoSessionDataStore.__ID, id);
// Form updates
BasicDBObject update = new BasicDBObject();
boolean upsert = false;
BasicDBObject sets = new BasicDBObject();
Object version = new Long(1);
// New session
upsert = true;
sets.put(MongoSessionDataStore.__CREATED,created);
sets.put(MongoSessionDataStore.__VALID,true);
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__VERSION,version);
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__LASTSAVED, System.currentTimeMillis());
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath +"."+MongoSessionDataStore.__LASTNODE, lastNode);
sets.put(MongoSessionDataStore.__MAX_IDLE, maxIdle);
sets.put(MongoSessionDataStore.__EXPIRY, expiry);
sets.put(MongoSessionDataStore.__ACCESSED, accessed);
sets.put(MongoSessionDataStore.__LAST_ACCESSED, lastAccessed);
if (attributes != null)
{
for (String name : attributes.keySet())
{
Object value = attributes.get(name);
sets.put(MongoSessionDataStore.__CONTEXT + "." + vhost.replace('.', '_') + ":" + contextPath+ "." + MongoUtils.encodeName(name),
MongoUtils.encodeName(value));
}
}
update.put("$set",sets);
collection.update(key,update,upsert,false,WriteConcern.SAFE);
}
}

View File

@ -1,84 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import static org.junit.Assert.fail;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* NonClusteredSessionScavengingTest
*/
public class NonClusteredSessionScavengingTest extends AbstractNonClusteredSessionScavengingTest
{
@BeforeClass
public static void beforeClass() throws Exception
{
MongoTestHelper.dropCollection();
MongoTestHelper.createCollection();
}
@AfterClass
public static void afterClass() throws Exception
{
MongoTestHelper.dropCollection();
}
/**
* @see org.eclipse.jetty.server.session.AbstractNonClusteredSessionScavengingTest#assertSession(java.lang.String, boolean)
*/
@Override
public void assertSession(String id, boolean exists)
{
assertNotNull(_dataStore);
try
{
boolean inmap = _dataStore.exists(id);
if (exists)
assertTrue(inmap);
else
assertFalse(inmap);
}
catch (Exception e)
{
fail(e.getMessage());
}
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return MongoTestHelper.newSessionDataStoreFactory();
}
}

View File

@ -1,188 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.Enumeration;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/* ------------------------------------------------------------ */
/** Test Servlet Sessions.
*
*
*/
public class SessionDump extends HttpServlet
{
int redirectCount=0;
/* ------------------------------------------------------------ */
String pageType;
/* ------------------------------------------------------------ */
@Override
public void init(ServletConfig config)
throws ServletException
{
super.init(config);
}
/* ------------------------------------------------------------ */
protected void handleForm(HttpServletRequest request,
HttpServletResponse response)
{
HttpSession session = request.getSession(false);
String action = request.getParameter("Action");
String name = request.getParameter("Name");
String value = request.getParameter("Value");
if (action!=null)
{
if(action.equals("New Session"))
{
session = request.getSession(true);
session.setAttribute("test","value");
}
else if (session!=null)
{
if (action.equals("Invalidate"))
session.invalidate();
else if (action.equals("Set") && name!=null && name.length()>0)
session.setAttribute(name,value);
else if (action.equals("Remove"))
session.removeAttribute(name);
}
}
}
/* ------------------------------------------------------------ */
@Override
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
handleForm(request,response);
String nextUrl = getURI(request)+"?R="+redirectCount++;
String encodedUrl=response.encodeRedirectURL(nextUrl);
response.sendRedirect(encodedUrl);
}
/* ------------------------------------------------------------ */
@Override
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
handleForm(request,response);
response.setContentType("text/html");
HttpSession session = request.getSession(getURI(request).indexOf("new")>0);
try
{
if (session!=null)
session.isNew();
}
catch(IllegalStateException e)
{
session=null;
}
PrintWriter out = response.getWriter();
out.println("<h1>Session Dump Servlet:</h1>");
out.println("<form action=\""+response.encodeURL(getURI(request))+"\" method=\"post\">");
if (session==null)
{
out.println("<H3>No Session</H3>");
out.println("<input type=\"submit\" name=\"Action\" value=\"New Session\"/>");
}
else
{
try
{
out.println("<b>ID:</b> "+session.getId()+"<br/>");
out.println("<b>New:</b> "+session.isNew()+"<br/>");
out.println("<b>Created:</b> "+new Date(session.getCreationTime())+"<br/>");
out.println("<b>Last:</b> "+new Date(session.getLastAccessedTime())+"<br/>");
out.println("<b>Max Inactive:</b> "+session.getMaxInactiveInterval()+"<br/>");
out.println("<b>Context:</b> "+session.getServletContext()+"<br/>");
Enumeration keys=session.getAttributeNames();
while(keys.hasMoreElements())
{
String name=(String)keys.nextElement();
String value=""+session.getAttribute(name);
out.println("<b>"+name+":</b> "+value+"<br/>");
}
out.println("<b>Name:</b><input type=\"text\" name=\"Name\" /><br/>");
out.println("<b>Value:</b><input type=\"text\" name=\"Value\" /><br/>");
out.println("<input type=\"submit\" name=\"Action\" value=\"Set\"/>");
out.println("<input type=\"submit\" name=\"Action\" value=\"Remove\"/>");
out.println("<input type=\"submit\" name=\"Action\" value=\"Refresh\"/>");
out.println("<input type=\"submit\" name=\"Action\" value=\"Invalidate\"/><br/>");
out.println("</form><br/>");
if (request.isRequestedSessionIdFromCookie())
out.println("<P>Turn off cookies in your browser to try url encoding<BR>");
if (request.isRequestedSessionIdFromURL())
out.println("<P>Turn on cookies in your browser to try cookie encoding<BR>");
out.println("<a href=\""+response.encodeURL(request.getRequestURI()+"?q=0")+"\">Encoded Link</a><BR>");
}
catch (IllegalStateException e)
{
e.printStackTrace();
}
}
}
/* ------------------------------------------------------------ */
@Override
public String getServletInfo() {
return "Session Dump Servlet";
}
/* ------------------------------------------------------------ */
private String getURI(HttpServletRequest request)
{
String uri=(String)request.getAttribute(RequestDispatcher.FORWARD_REQUEST_URI);
if (uri==null)
uri=request.getRequestURI();
return uri;
}
}

View File

@ -1,385 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2018 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.server.session.AbstractSessionExpiryTest;
import org.eclipse.jetty.server.session.DefaultSessionCacheFactory;
import org.eclipse.jetty.server.session.SessionCache;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.server.session.TestServer;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.eclipse.jetty.util.StringUtil;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import com.mongodb.BasicDBObject;
import com.mongodb.DBCollection;
import com.mongodb.DBObject;
public class SessionExpiryTest extends AbstractSessionExpiryTest
{
@BeforeClass
public static void beforeClass() throws Exception
{
MongoTestHelper.dropCollection();
MongoTestHelper.createCollection();
}
@AfterClass
public static void afterClass() throws Exception
{
MongoTestHelper.dropCollection();
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
return MongoTestHelper.newSessionDataStoreFactory();
}
@Test
@Override
public void testSessionNotExpired() throws Exception
{
super.testSessionNotExpired();
}
@Test
@Override
public void testSessionExpiry() throws Exception
{
super.testSessionExpiry();
}
@Test
@Override
public void testRequestForSessionWithChangedTimeout() throws Exception
{
super.testRequestForSessionWithChangedTimeout();
}
@Test
public void testBigSessionExpiry() throws Exception
{
String contextPath = "";
String servletMapping = "/server";
int inactivePeriod = Integer.MAX_VALUE * 60; //integer overflow
int scavengePeriod = 10;
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
MongoSessionDataStoreFactory storeFactory = MongoTestHelper.newSessionDataStoreFactory();
storeFactory.setGracePeriodSec(scavengePeriod);
TestServer server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
ChangeTimeoutServlet servlet = new ChangeTimeoutServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler context = server1.addContext(contextPath);
context.addServlet(holder, servletMapping);
TestHttpSessionListener listener = new TestHttpSessionListener();
context.getSessionHandler().addEventListener(listener);
server1.start();
int port1 = server1.getPort();
try
{
HttpClient client = new HttpClient();
client.start();
String url = "http://localhost:" + port1 + contextPath + servletMapping;
//make a request to set up a session on the server
ContentResponse response1 = client.GET(url + "?action=init");
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
String sessionCookie = response1.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null);
// Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
String sessionId = TestServer.extractSessionId(sessionCookie);
DBCollection sessions = MongoTestHelper.getCollection();
verifySessionCreated(listener,sessionId);
//verify that the session timeout is set in mongo
verifySessionTimeout(sessions, sessionId, -1); //SessionManager sets -1 if maxInactive < 0
//get the session expiry time from mongo
long expiry = getSessionExpiry(sessions, sessionId);
assertEquals(0, expiry);
}
finally
{
server1.stop();
}
}
@Test
public void changeSessionTimeout() throws Exception
{
String contextPath = "";
String servletMapping = "/server";
int inactivePeriod = 10;
int scavengePeriod = 1;
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
MongoSessionDataStoreFactory storeFactory = MongoTestHelper.newSessionDataStoreFactory();
storeFactory.setGracePeriodSec(scavengePeriod);
TestServer server1 = new TestServer(0, inactivePeriod, scavengePeriod, cacheFactory, storeFactory);
ChangeTimeoutServlet servlet = new ChangeTimeoutServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler context = server1.addContext(contextPath);
context.addServlet(holder, servletMapping);
TestHttpSessionListener listener = new TestHttpSessionListener();
context.getSessionHandler().addEventListener(listener);
server1.start();
int port1 = server1.getPort();
try
{
HttpClient client = new HttpClient();
client.start();
String url = "http://localhost:" + port1 + contextPath + servletMapping;
//make a request to set up a session on the server
ContentResponse response1 = client.GET(url + "?action=init");
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
String sessionCookie = response1.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null);
// Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
String sessionId = TestServer.extractSessionId(sessionCookie);
DBCollection sessions = MongoTestHelper.getCollection();
verifySessionCreated(listener,sessionId);
//verify that the session timeout is set in mongo
verifySessionTimeout(sessions, sessionId, inactivePeriod);
//get the session expiry time from mongo
long expiry = getSessionExpiry(sessions, sessionId);
//make another request to change the session timeout to a smaller value
inactivePeriod = 5;
Request request = client.newRequest(url + "?action=change&val="+inactivePeriod);
request.getHeaders().add("Cookie", sessionCookie);
ContentResponse response2 = request.send();
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
//check the timeout in mongo
verifySessionTimeout(sessions, sessionId, inactivePeriod);
//check the session expiry time has decreased from previous value
assertTrue(getSessionExpiry(sessions, sessionId)<expiry);
expiry = getSessionExpiry(sessions, sessionId);
//increase the session timeout
inactivePeriod = 20;
request = client.newRequest(url + "?action=change&val="+inactivePeriod);
request.getHeaders().add("Cookie", sessionCookie);
response2 = request.send();
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
//verify that the session timeout is set in mongo
verifySessionTimeout(sessions, sessionId, inactivePeriod);
long latestExpiry = getSessionExpiry(sessions, sessionId);
assertTrue (latestExpiry > expiry);
assertTrue(getSessionAccessed(sessions, sessionId)+ (1000L*inactivePeriod) <= getSessionExpiry(sessions, sessionId));
assertTrue (latestExpiry >= 15);//old inactive expired in 5, new inactive expired in 20
}
finally
{
server1.stop();
}
}
@Test
public void testChangeNewSessionTimeout () throws Exception
{
String contextPath = "";
String servletMapping = "/server";
int inactivePeriod = 10;
int scavengePeriod = 1;
DefaultSessionCacheFactory cacheFactory = new DefaultSessionCacheFactory();
cacheFactory.setEvictionPolicy(SessionCache.NEVER_EVICT);
MongoSessionDataStoreFactory storeFactory = MongoTestHelper.newSessionDataStoreFactory();
storeFactory.setGracePeriodSec(scavengePeriod);
TestServer server1 = new TestServer(0, inactivePeriod, scavengePeriod,cacheFactory, storeFactory);
ImmediateChangeTimeoutServlet servlet = new ImmediateChangeTimeoutServlet();
ServletHolder holder = new ServletHolder(servlet);
ServletContextHandler context = server1.addContext(contextPath);
context.addServlet(holder, servletMapping);
TestHttpSessionListener listener = new TestHttpSessionListener();
context.getSessionHandler().addEventListener(listener);
server1.start();
int port1 = server1.getPort();
try
{
HttpClient client = new HttpClient();
client.start();
String url = "http://localhost:" + port1 + contextPath + servletMapping;
inactivePeriod = 5; //change from the sessionmanager configured default
//make a request to set up a session on the server and change its inactive setting straight away
ContentResponse response1 = client.GET(url + "?action=init&val="+inactivePeriod);
assertEquals(HttpServletResponse.SC_OK,response1.getStatus());
String sessionCookie = response1.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null);
// Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
String sessionId = TestServer.extractSessionId(sessionCookie);
DBCollection sessions = MongoTestHelper.getCollection();
verifySessionCreated(listener,sessionId);
//verify that the session timeout is the new value and not the default
verifySessionTimeout(sessions, sessionId, inactivePeriod);
}
finally
{
server1.stop();
}
}
public void verifySessionTimeout (DBCollection sessions, String id, int sec) throws Exception
{
long val;
if (sec > 0)
val = sec*1000L;
else
val = sec;
assertNotNull(sessions);
assertNotNull(id);
DBObject o = sessions.findOne(new BasicDBObject(MongoSessionDataStore.__ID,id));
assertNotNull(o);
Long maxIdle = (Long)o.get(MongoSessionDataStore.__MAX_IDLE);
assertNotNull(maxIdle);
assertEquals(val, maxIdle.longValue());
}
public long getSessionExpiry (DBCollection sessions, String id) throws Exception
{
assertNotNull(sessions);
assertNotNull(id);
DBObject o = sessions.findOne(new BasicDBObject(MongoSessionDataStore.__ID,id));
assertNotNull(o);
Long expiry = (Long)o.get(MongoSessionDataStore.__EXPIRY);
return (expiry == null? null : expiry.longValue());
}
public long getSessionMaxInactiveInterval (DBCollection sessions, String id) throws Exception
{
assertNotNull(sessions);
assertNotNull(id);
DBObject o = sessions.findOne(new BasicDBObject(MongoSessionDataStore.__ID,id));
assertNotNull(o);
Long inactiveInterval = (Long)o.get(MongoSessionDataStore.__MAX_IDLE);
return (inactiveInterval == null? null : inactiveInterval.longValue());
}
public long getSessionAccessed (DBCollection sessions, String id) throws Exception
{
assertNotNull(sessions);
assertNotNull(id);
DBObject o = sessions.findOne(new BasicDBObject(MongoSessionDataStore.__ID,id));
assertNotNull(o);
Long accessed = (Long)o.get(MongoSessionDataStore.__ACCESSED);
return (accessed == null? null : accessed.longValue());
}
public void debugPrint (DBCollection sessions, String id) throws Exception
{
assertNotNull(sessions);
assertNotNull(id);
DBObject o = sessions.findOne(new BasicDBObject(MongoSessionDataStore.__ID,id));
assertNotNull(o);
System.err.println(o);
}
public static class ImmediateChangeTimeoutServlet extends HttpServlet
{
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse httpServletResponse) throws ServletException, IOException
{
String action = request.getParameter("action");
if ("init".equals(action))
{
HttpSession session = request.getSession(true);
assertNotNull(session);
String tmp = request.getParameter("val");
int val = (StringUtil.isBlank(tmp)?0:Integer.valueOf(tmp.trim()));
session.setMaxInactiveInterval(val);
}
else if ("change".equals(action))
{
String tmp = request.getParameter("val");
int val = (StringUtil.isBlank(tmp)?0:Integer.valueOf(tmp.trim()));
HttpSession session = request.getSession(false);
assertNotNull(session);
session.setMaxInactiveInterval(val);
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More