Alpha impl for infinispan session manager.

Conflicts:
	tests/test-sessions/pom.xml

Conflicts:
	tests/test-sessions/pom.xml
	tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/SessionExpiryTest.java
This commit is contained in:
Jan Bartel 2015-04-02 12:20:12 +11:00
parent abb74087a5
commit 7375ba2cc3
31 changed files with 2845 additions and 149 deletions

83
jetty-infinispan/pom.xml Normal file
View File

@ -0,0 +1,83 @@
<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">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.1.6-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-infinispan</artifactId>
<name>Jetty :: Infinispan Session Managers</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.infinispan</bundle-symbolic-name>
<infinispan.version>7.1.1.Final</infinispan.version>
</properties>
<build>
<defaultGoal>install</defaultGoal>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
<configuration>
<descriptorRefs>
<descriptorRef>config</descriptorRef>
</descriptorRefs>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<configuration>
<instructions>
<Import-Package>javax.servlet.*;version="[2.6.0,3.2)",org.eclipse.jetty.server.session.jmx;version="9.1";resolution:=optional,,org.eclipse.jetty.*;version="9.1",*</Import-Package>
</instructions>
</configuration>
<extensions>true</extensions>
<executions>
<execution>
<goals>
<goal>manifest</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<executions>
<execution>
<id>artifact-jar</id>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
<configuration>
<archive>
<manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile>
</archive>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.infinispan</groupId>
<artifactId>infinispan-core</artifactId>
<version>${infinispan.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,316 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.session.infinispan;
import java.util.Random;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.session.AbstractSession;
import org.eclipse.jetty.server.session.AbstractSessionIdManager;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.infinispan.Cache;
/**
* InfinispanSessionIdManager
*
* Maintain a set of in-use session ids. This session id manager does NOT locally store
* a list of in-use sesssion ids, but rather stores them in the cluster cache. Thus,
* all operations to this session manager involve interaction with a possibly remote
* cache.
*
* For each session id that is in-use, an entry of the following form is put into
* the cluster cache:
* <pre>
* ("__o.e.j.s.infinispanIdMgr__"+[id], [id])
* </pre>
* where [id] is the id of the session.
*
* Having one entry per in-use session id means that there is no contention on
* cache entries (as would be the case if a single entry was kept containing a
* list of in-use session ids).
*
* TODO synchronization
*/
public class InfinispanSessionIdManager extends AbstractSessionIdManager
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
protected final static String ID_KEY = "__o.e.j.s.infinispanIdMgr__";
protected Cache<String,Object> _cache;
private Server _server;
/**
* @param server
*/
public InfinispanSessionIdManager(Server server)
{
super();
_server = server;
}
/**
* @param server
* @param random
*/
public InfinispanSessionIdManager(Server server, Random random)
{
super(random);
_server = server;
}
/**
* Start the id manager.
* @see org.eclipse.jetty.server.session.AbstractSessionIdManager#doStart()
*/
@Override
protected void doStart() throws Exception
{
super.doStart();
}
/**
* Stop the id manager
* @see org.eclipse.jetty.server.session.AbstractSessionIdManager#doStop()
*/
@Override
protected void doStop() throws Exception
{
super.doStop();
}
/**
* Check to see if the given session id is being
* used by a session in any context.
*
* This method will consult the cluster.
*
* @see org.eclipse.jetty.server.SessionIdManager#idInUse(java.lang.String)
*/
@Override
public boolean idInUse(String id)
{
if (id == null)
return false;
String clusterId = getClusterId(id);
//ask the cluster
try
{
return exists(clusterId);
}
catch (Exception e)
{
LOG.warn("Problem checking inUse for id="+clusterId, e);
return false;
}
}
/**
* Remember a new in-use session id.
*
* This will save the in-use session id to the cluster.
*
* @see org.eclipse.jetty.server.SessionIdManager#addSession(javax.servlet.http.HttpSession)
*/
@Override
public void addSession(HttpSession session)
{
if (session == null)
return;
//insert into the cache
insert (((AbstractSession)session).getClusterId());
}
/**
* Remove a session id from the list of in-use ids.
*
* This will remvove the corresponding session id from the cluster.
*
* @see org.eclipse.jetty.server.SessionIdManager#removeSession(javax.servlet.http.HttpSession)
*/
@Override
public void removeSession(HttpSession session)
{
if (session == null)
return;
//delete from the cache
delete (((AbstractSession)session).getClusterId());
}
/**
* Remove a session id. This compels all other contexts who have a session
* with the same id to also remove it.
*
* @see org.eclipse.jetty.server.SessionIdManager#invalidateAll(java.lang.String)
*/
@Override
public void invalidateAll(String id)
{
//delete the session id from list of in-use sessions
delete (id);
//tell all contexts that may have a session object with this id to
//get rid of them
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
for (int i=0; contexts!=null && i<contexts.length; i++)
{
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
if (sessionHandler != null)
{
SessionManager manager = sessionHandler.getSessionManager();
if (manager != null && manager instanceof InfinispanSessionManager)
{
((InfinispanSessionManager)manager).invalidateSession(id);
}
}
}
}
/**
* Change a session id.
*
* Typically this occurs when a previously existing session has passed through authentication.
*
* @see org.eclipse.jetty.server.session.AbstractSessionIdManager#renewSessionId(java.lang.String, java.lang.String, javax.servlet.http.HttpServletRequest)
*/
@Override
public void renewSessionId(String oldClusterId, String oldNodeId, HttpServletRequest request)
{
//generate a new id
String newClusterId = newSessionId(request.hashCode());
delete(oldClusterId);
insert(newClusterId);
//tell all contexts to update the id
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
for (int i=0; contexts!=null && i<contexts.length; i++)
{
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
if (sessionHandler != null)
{
SessionManager manager = sessionHandler.getSessionManager();
if (manager != null && manager instanceof InfinispanSessionManager)
{
((InfinispanSessionManager)manager).renewSessionId(oldClusterId, oldNodeId, newClusterId, getNodeId(newClusterId, request));
}
}
}
}
public Cache<String,Object> getCache()
{
return _cache;
}
public void setCache(Cache<String,Object> cache)
{
this._cache = cache;
}
/**
* Ask the cluster if a particular id exists.
*
* @param id
* @return
*/
protected boolean exists (String id)
{
if (_cache == null)
throw new IllegalStateException ("No cache");
Object key =_cache.get(makeKey(id));
if (key == null)
return false;
return true;
}
/**
* Put a session id into the cluster.
*
* @param id
*/
protected void insert (String id)
{
if (_cache == null)
throw new IllegalStateException ("No cache");
_cache.putIfAbsent(makeKey(id), id);
}
/**
* Remove a session id from the cluster.
*
* @param id
*/
protected void delete (String id)
{
if (_cache == null)
throw new IllegalStateException ("No cache");
_cache.remove(makeKey(id));
}
/**
* Generate a unique cache key from the session id.
*
* @param id
* @return
*/
protected String makeKey (String id)
{
return ID_KEY+id;
}
}

View File

@ -155,6 +155,12 @@ public abstract class AbstractSession implements AbstractSessionManager.SessionI
{
return _cookieSet;
}
/* ------------------------------------------------------------- */
public void setCookieSetTime(long time)
{
_cookieSet = time;
}
/* ------------------------------------------------------------- */
@Override

View File

@ -98,10 +98,7 @@ public class JDBCSessionManager extends AbstractSessionManager
protected boolean _dirty=false;
/**
* Time in msec since the epoch that a session cookie was set for this session
*/
protected long _cookieSet;
/**
@ -223,16 +220,7 @@ public class JDBCSessionManager extends AbstractSessionManager
return _canonicalContext;
}
public void setCookieSet (long ms)
{
_cookieSet = ms;
}
public synchronized long getCookieSet ()
{
return _cookieSet;
}
public synchronized void setLastNode (String node)
{
_lastNode=node;
@ -261,11 +249,6 @@ public class JDBCSessionManager extends AbstractSessionManager
_dirty=true;
}
@Override
protected void cookieSet()
{
_cookieSet = getAccessed();
}
/**
* Entry to session.
@ -400,7 +383,7 @@ public class JDBCSessionManager extends AbstractSessionManager
{
return "Session rowId="+_rowId+",id="+getId()+",lastNode="+_lastNode+
",created="+getCreationTime()+",accessed="+getAccessed()+
",lastAccessed="+getLastAccessedTime()+",cookieSet="+_cookieSet+
",lastAccessed="+getLastAccessedTime()+",cookieSet="+getCookieSetTime()+
",maxInterval="+getMaxInactiveInterval()+",lastSaved="+_lastSaved+",expiry="+_expiryTime;
}
}
@ -925,7 +908,7 @@ public class JDBCSessionManager extends AbstractSessionManager
result.getLong(_sessionTableSchema.getCreateTimeColumn()),
result.getLong(_sessionTableSchema.getAccessTimeColumn()),
maxInterval);
session.setCookieSet(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
session.setCookieSetTime(result.getLong(_sessionTableSchema.getCookieTimeColumn()));
session.setLastAccessedTime(result.getLong(_sessionTableSchema.getLastAccessTimeColumn()));
session.setLastNode(result.getString(_sessionTableSchema.getLastNodeColumn()));
session.setLastSaved(result.getLong(_sessionTableSchema.getLastSavedTimeColumn()));
@ -999,7 +982,7 @@ public class JDBCSessionManager extends AbstractSessionManager
statement.setLong(6, session.getAccessed());//accessTime
statement.setLong(7, session.getLastAccessedTime()); //lastAccessTime
statement.setLong(8, session.getCreationTime()); //time created
statement.setLong(9, session.getCookieSet());//time cookie was set
statement.setLong(9, session.getCookieSetTime());//time cookie was set
statement.setLong(10, now); //last saved time
statement.setLong(11, session.getExpiryTime());
statement.setLong(12, session.getMaxInactiveInterval());

View File

@ -224,6 +224,8 @@
<exclude>jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/DefaultPolicyLoader.java</exclude>
<exclude>jetty-policy/src/main/java/org/eclipse/jetty/policy/loader/PolicyFileScanner.java</exclude>
<exclude>jetty-ant/**</exclude>
<exclude>jetty-infinispan/**</exclude>
<exclude>tests/test-sessions/test-infinispan-sessions/**</exclude>
</excludes>
</configuration>
<executions>
@ -484,6 +486,7 @@
<module>jetty-jaspi</module>
<module>jetty-rewrite</module>
<module>jetty-nosql</module>
<module>jetty-infinispan</module>
<module>tests</module>
<module>examples</module>
<module>jetty-quickstart</module>

View File

@ -33,7 +33,7 @@
<module>test-sessions-common</module>
<module>test-hash-sessions</module>
<module>test-jdbc-sessions</module>
<!-- Requires mongodb server running -->
<module>test-mongodb-sessions</module>
<module>test-infinispan-sessions</module>
</modules>
</project>

View File

@ -38,7 +38,7 @@ public class HashTestServer extends AbstractTestServer
}
public SessionIdManager newSessionIdManager(String config)
public SessionIdManager newSessionIdManager(Object config)
{
return new HashSessionIdManager();
}

View File

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
// ========================================================================
// Copyright (c) Webtide LLC
//
// 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.apache.org/licenses/LICENSE-2.0.txt
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
-->
<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.1.6-SNAPSHOT</version>
</parent>
<artifactId>test-infinispan-sessions</artifactId>
<name>Jetty Tests :: Sessions :: Infinispan</name>
<url>http://www.eclipse.org/jetty</url>
<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>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>generate-test-resources</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-policy</artifactId>
<version>${jetty-test-policy-version}</version>
<type>jar</type>
<overWrite>true</overWrite>
<includes>**/*.keystore,**/*.pem</includes>
<outputDirectory>${jetty.test.policy.loc}</outputDirectory>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</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</groupId>
<artifactId>jetty-infinispan</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-jmx</artifactId>
<version>${project.version}</version>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<!--
<profiles>
<profile>
<id>mongodb</id>
<activation>
<property>
<name>mongodb.enabled</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
-->
</project>

View File

@ -0,0 +1,60 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class ClientCrossContextSessionTest extends AbstractClientCrossContextSessionTest
{
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();
}
@Override
public AbstractTestServer createServer(int port)
{
InfinispanTestSessionServer server = new InfinispanTestSessionServer(port, __testSupport.getCache());
return server;
}
@Test
public void testCrossContextDispatch() throws Exception
{
super.testCrossContextDispatch();
}
}

View File

@ -0,0 +1,71 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* ImmortalSessionTest
*
*
*/
public class ImmortalSessionTest extends AbstractImmortalSessionTest
{
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.AbstractImmortalSessionTest#createServer(int, int, int)
*/
@Override
public AbstractTestServer createServer(int port, int maxInactiveMs, int scavengeMs)
{
return new InfinispanTestSessionServer(port, maxInactiveMs, scavengeMs, __testSupport.getCache());
}
@Override
public void testImmortalSession() throws Exception
{
super.testImmortalSession();
}
}

View File

@ -0,0 +1,79 @@
package org.eclipse.jetty.server.session;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.session.infinispan.InfinispanSessionIdManager;
import org.eclipse.jetty.session.infinispan.InfinispanSessionManager;
import org.infinispan.Cache;
import org.infinispan.commons.util.CloseableIteratorSet;
public class InfinispanTestSessionServer extends AbstractTestServer
{
static int __workers=0;
public InfinispanTestSessionServer(int port, Cache config)
{
this(port, 30, 10, config);
}
public InfinispanTestSessionServer(int port, int maxInactivePeriod, int scavengePeriod, Cache config)
{
super(port, maxInactivePeriod, scavengePeriod, config);
}
@Override
public SessionIdManager newSessionIdManager(Object config)
{
InfinispanSessionIdManager idManager = new InfinispanSessionIdManager(getServer());
idManager.setWorkerName("w"+(__workers++));
idManager.setCache((Cache)config);
return idManager;
}
@Override
public SessionManager newSessionManager()
{
InfinispanSessionManager sessionManager = new InfinispanSessionManager();
sessionManager.setSessionIdManager((InfinispanSessionIdManager)_sessionIdManager);
sessionManager.setCache(((InfinispanSessionIdManager)_sessionIdManager).getCache());
sessionManager.setStaleIntervalSec(1);
sessionManager.setScavengeInterval(_scavengePeriod);
return sessionManager;
}
@Override
public SessionHandler newSessionHandler(SessionManager sessionManager)
{
return new SessionHandler(sessionManager);
}
public void dumpCache ()
{
Cache cache = ((InfinispanSessionIdManager)_sessionIdManager).getCache();
if (cache != null)
{
System.err.println(cache.getName()+" contains "+cache.size()+" entries");
CloseableIteratorSet<String> keys = cache.keySet();
for (String key:keys)
System.err.println(key + " "+cache.get(key));
}
}
public void clearCache ()
{
Cache cache = ((InfinispanSessionIdManager)_sessionIdManager).getCache();
if (cache != null)
cache.clear();
}
}

View File

@ -0,0 +1,114 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import java.io.File;
import org.eclipse.jetty.util.IO;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
/**
* InfinispanTestSupport
*
*
*/
public class InfinispanTestSupport
{
public static final String DEFAULT_CACHE_NAME = "session_test_cache";
public Cache _cache;
public ConfigurationBuilder _builder;
private File _tmpdir;
private boolean _useFileStore;
private String _name;
public static EmbeddedCacheManager _manager;
static
{
try
{
_manager = new DefaultCacheManager(new GlobalConfigurationBuilder().globalJmxStatistics().allowDuplicateDomains(true).build());
}
catch (Exception e)
{
e.printStackTrace();
}
}
public InfinispanTestSupport ()
{
this (null);
}
public InfinispanTestSupport(String cacheName)
{
if (cacheName == null)
cacheName = DEFAULT_CACHE_NAME+System.currentTimeMillis();
_name = cacheName;
_builder = new ConfigurationBuilder();
}
public void setUseFileStore (boolean useFileStore)
{
_useFileStore = useFileStore;
}
public Cache getCache ()
{
return _cache;
}
public void setup () throws Exception
{
if (_useFileStore)
{
_tmpdir = File.createTempFile("infini", "span");
_tmpdir.delete();
_tmpdir.mkdir();
System.err.println("Temp file: "+_tmpdir);
Configuration config = _builder.persistence().addSingleFileStore().location(_tmpdir.getAbsolutePath()).storeAsBinary().build();
_manager.defineConfiguration(_name, config);
}
else
{
_manager.defineConfiguration(_name, _builder.build());
}
_cache = _manager.getCache(_name);
}
public void teardown () throws Exception
{
_manager.removeCache(_name);
if (_useFileStore)
{
if (_tmpdir != null)
{
IO.delete(_tmpdir);
}
}
}
}

View File

@ -0,0 +1,116 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import java.io.File;
import org.eclipse.jetty.server.SessionManager;
import org.eclipse.jetty.session.infinispan.InfinispanSessionIdManager;
import org.eclipse.jetty.session.infinispan.InfinispanSessionManager;
import org.eclipse.jetty.util.IO;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* InvalidationSessionTest
*
*
*/
public class InvalidationSessionTest extends AbstractInvalidationSessionTest
{
public static InfinispanTestSupport __testSupport;
public static long __staleSec = 3L;
@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.AbstractInvalidationSessionTest#createServer(int)
*/
@Override
public AbstractTestServer createServer(int port)
{
return new InfinispanTestSessionServer(port, __testSupport.getCache());
// return new InfinispanTestSessionServer(port, __cache)
// {
//
// @Override
// public SessionManager newSessionManager()
// {
// InfinispanSessionManager sessionManager = new InfinispanSessionManager();
// sessionManager.setSessionIdManager((InfinispanSessionIdManager)_sessionIdManager);
// sessionManager.setStaleIntervalSec(__staleSec);
// sessionManager.setCache(((InfinispanSessionIdManager)_sessionIdManager).getCache());
// return sessionManager;
// }
// };
}
@Override
public void testInvalidation() throws Exception
{
super.testInvalidation();
}
/**
* @see org.eclipse.jetty.server.session.AbstractInvalidationSessionTest#pause()
*/
@Override
public void pause()
{
//This test moves a session from node 1 to node 2, then invalidates the session back on node1. This
//should never happen with a decent load balancer.
//The infinispan session manager on node 2 will hold the session in local memory for a specific (configurable)
//amount of time. We've set the stale session time to 3 sec, so we need to pause for at least this long before making
//another request to node2
//that the node will re-load the session from the database and discover that it has gone.
try
{
Thread.sleep(2 * __staleSec * 1000);
}
catch (InterruptedException e)
{
}
}
}

View File

@ -0,0 +1,65 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import java.io.File;
import org.eclipse.jetty.util.IO;
import org.infinispan.Cache;
import org.infinispan.configuration.cache.Configuration;
import org.infinispan.configuration.cache.ConfigurationBuilder;
import org.infinispan.manager.DefaultCacheManager;
import org.infinispan.manager.EmbeddedCacheManager;
import org.junit.AfterClass;
import org.junit.BeforeClass;
public class LastAccessTimeTest extends AbstractLastAccessTimeTest
{
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
{
__testSupport.teardown();
}
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new InfinispanTestSessionServer(port, max, scavenge, __testSupport.getCache());
}
@Override
public void testLastAccessTime() throws Exception
{
super.testLastAccessTime();
}
}

View File

@ -0,0 +1,59 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* LocalSessionScavengingTest
*
*
*/
public class LocalSessionScavengingTest extends AbstractLocalSessionScavengingTest
{
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
{
__testSupport.teardown();
}
/**
* @see org.eclipse.jetty.server.session.AbstractLocalSessionScavengingTest#createServer(int, int, int)
*/
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new InfinispanTestSessionServer(port, max, scavenge, __testSupport.getCache());
}
}

View File

@ -0,0 +1,66 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* NewSessionTest
*
*
*/
public class NewSessionTest extends AbstractNewSessionTest
{
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.AbstractNewSessionTest#createServer(int, int, int)
*/
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new InfinispanTestSessionServer(port, max, scavenge, __testSupport.getCache());
}
@Override
public void testNewSession() throws Exception
{
super.testNewSession();
}
}

View File

@ -0,0 +1,64 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* ReentrantRequestSessionTest
*
*
*/
public class ReentrantRequestSessionTest extends AbstractReentrantRequestSessionTest
{
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.AbstractReentrantRequestSessionTest#createServer(int)
*/
@Override
public AbstractTestServer createServer(int port)
{
return new InfinispanTestSessionServer(port, __testSupport.getCache());
}
@Override
public void testReentrantRequestSession() throws Exception
{
super.testReentrantRequestSession();
}
}

View File

@ -0,0 +1,58 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
public class RemoveSessionTest extends AbstractRemoveSessionTest
{
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();
}
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
InfinispanTestSessionServer s = new InfinispanTestSessionServer(port, max, scavenge, __testSupport.getCache());
return s;
}
@Test
public void testRemoveSession() throws Exception
{
super.testRemoveSession();
}
}

View File

@ -0,0 +1,70 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.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();
}
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
InfinispanTestSessionServer server = new InfinispanTestSessionServer(port, max, scavenge, __testSupport.getCache());
return server;
}
@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

@ -0,0 +1,66 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* SessionInvalidateAndCreateTest
*
*
*/
public class SessionInvalidateAndCreateTest extends AbstractSessionInvalidateAndCreateTest
{
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.AbstractSessionInvalidateAndCreateTest#createServer(int, int, int)
*/
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new InfinispanTestSessionServer(port, max, scavenge, __testSupport.getCache());
}
@Override
public void testSessionScavenge() throws Exception
{
super.testSessionScavenge();
}
}

View File

@ -0,0 +1,64 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
/**
* SessionMigrationTest
*
*
*/
public class SessionMigrationTest extends AbstractSessionMigrationTest
{
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.AbstractSessionMigrationTest#createServer(int)
*/
@Override
public AbstractTestServer createServer(int port)
{
return new InfinispanTestSessionServer(port, __testSupport.getCache());
}
@Override
public void testSessionMigration() throws Exception
{
super.testSessionMigration();
}
}

View File

@ -0,0 +1,67 @@
//
// ========================================================================
// Copyright (c) 1995-2015 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.server.session;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
/**
* SessionRenewTest
*
*
*/
public class SessionRenewTest extends AbstractSessionRenewTest
{
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.AbstractSessionRenewTest#createServer(int, int, int)
*/
@Override
public AbstractTestServer createServer(int port, int max, int scavenge)
{
return new InfinispanTestSessionServer(port, max, scavenge, __testSupport.getCache());
}
@Test
public void testSessionRenewal() throws Exception
{
super.testSessionRenewal();
}
}

View File

@ -76,14 +76,14 @@ public class JdbcTestServer extends AbstractTestServer
* @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionIdManager(String)
*/
@Override
public SessionIdManager newSessionIdManager(String config)
public SessionIdManager newSessionIdManager(Object config)
{
synchronized(JdbcTestServer.class)
{
JDBCSessionIdManager idManager = new JDBCSessionIdManager(_server);
idManager.setScavengeInterval(_scavengePeriod);
idManager.setWorkerName("w"+(__workers++));
idManager.setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:config));
idManager.setDriverInfo(DRIVER_CLASS, (config==null?DEFAULT_CONNECTION_URL:(String)config));
JDBCSessionIdManager.SessionIdTableSchema idTableSchema = new JDBCSessionIdManager.SessionIdTableSchema();
idTableSchema.setTableName("mysessionids");
idTableSchema.setIdColumn("myid");

View File

@ -18,23 +18,9 @@
package org.eclipse.jetty.server.session;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
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.eclipse.jetty.servlet.ServletHolder;
import org.junit.After;
import org.junit.Test;
@ -47,22 +33,6 @@ import org.junit.Test;
public class SessionExpiryTest extends AbstractSessionExpiryTest
{
public class TestHttpSessionListener implements HttpSessionListener
{
public List<String> createdSessions = new ArrayList<String>();
public List<String> destroyedSessions = new ArrayList<String>();
public void sessionDestroyed(HttpSessionEvent se)
{
destroyedSessions.add(se.getSession().getId());
}
public void sessionCreated(HttpSessionEvent se)
{
createdSessions.add(se.getSession().getId());
}
};
/**
* @see org.eclipse.jetty.server.session.AbstractSessionExpiryTest#createServer(int, int, int)
*/
@ -75,70 +45,9 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest
@Test
public void testSessionExpiry() throws Exception
{
String contextPath = "";
String servletMapping = "/server";
int inactivePeriod = 2;
int scavengePeriod = 1;
AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
TestServlet servlet = new TestServlet();
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 = extractSessionId(sessionCookie);
assertTrue(listener.createdSessions.contains(sessionId));
//now stop the server
server1.stop();
//and wait until the expiry time has passed
pause(inactivePeriod);
//restart the server
server1.start();
port1 = server1.getPort();
url = "http://localhost:" + port1 + contextPath + servletMapping;
//make another request, the session should have expired
Request request = client.newRequest(url + "?action=test");
request.getHeaders().add("Cookie", sessionCookie);
ContentResponse response2 = request.send();
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
//and wait until the expiry time has passed
pause(inactivePeriod);
assertTrue(listener.destroyedSessions.contains(sessionId));
}
finally
{
server1.stop();
}
super.testSessionExpiry();
}
@ -149,24 +58,7 @@ public class SessionExpiryTest extends AbstractSessionExpiryTest
super.testSessionNotExpired();
}
public String extractSessionId (String sessionCookie)
{
if (sessionCookie == null)
return null;
sessionCookie = sessionCookie.trim();
int i = sessionCookie.indexOf(';');
if (i >= 0)
sessionCookie = sessionCookie.substring(0,i);
if (sessionCookie.startsWith("JSESSIONID"))
sessionCookie = sessionCookie.substring("JSESSIONID=".length());
i = sessionCookie.indexOf('.');
if (i >=0)
sessionCookie = sessionCookie.substring(0,i);
return sessionCookie;
}
@After

View File

@ -50,7 +50,7 @@ public class MongoTestServer extends AbstractTestServer
_saveAllAttributes = saveAllAttributes;
}
public SessionIdManager newSessionIdManager(String config)
public SessionIdManager newSessionIdManager(Object config)
{
try
{

View File

@ -82,8 +82,7 @@ public abstract class AbstractRemoveSessionTest
assertTrue(testListener.isDestroyed());
// The session is not there anymore, but we present an old cookie
// The server creates a new session, we must ensure we released all locks
// The session is not there anymore, even if we present an old cookie
request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=check");
request.header("Cookie", sessionCookie);
response = request.send();

View File

@ -39,7 +39,7 @@ import org.junit.Ignore;
import org.junit.Test;
/**
* AbstractNewSessionTest
* AbstractSessionCookieTest
*/
public abstract class AbstractSessionCookieTest
{

View File

@ -22,16 +22,21 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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 javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
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.eclipse.jetty.servlet.ServletHolder;
import org.junit.Test;
@ -50,6 +55,23 @@ public abstract class AbstractSessionExpiryTest
e.printStackTrace();
}
}
public class TestHttpSessionListener implements HttpSessionListener
{
public List<String> createdSessions = new ArrayList<String>();
public List<String> destroyedSessions = new ArrayList<String>();
public void sessionDestroyed(HttpSessionEvent se)
{
destroyedSessions.add(se.getSession().getId());
}
public void sessionCreated(HttpSessionEvent se)
{
createdSessions.add(se.getSession().getId());
}
};
@Test
public void testSessionNotExpired() throws Exception
@ -101,18 +123,26 @@ public abstract class AbstractSessionExpiryTest
server1.stop();
}
}
@Test
public void testSessionExpiry() throws Exception
{
String contextPath = "";
String servletMapping = "/server";
int inactivePeriod = 2;
int scavengePeriod = 10;
int scavengePeriod = 1;
AbstractTestServer server1 = createServer(0, inactivePeriod, scavengePeriod);
TestServlet servlet = new TestServlet();
ServletHolder holder = new ServletHolder(servlet);
server1.addContext(contextPath).addServlet(holder, servletMapping);
ServletContextHandler context = server1.addContext(contextPath);
context.addServlet(holder, servletMapping);
TestHttpSessionListener listener = new TestHttpSessionListener();
context.getSessionHandler().addEventListener(listener);
server1.start();
int port1 = server1.getPort();
@ -129,7 +159,11 @@ public abstract class AbstractSessionExpiryTest
assertTrue(sessionCookie != null);
// Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
String sessionId = AbstractTestServer.extractSessionId(sessionCookie);
verifySessionCreated(listener,sessionId);
//now stop the server
server1.stop();
@ -138,6 +172,7 @@ public abstract class AbstractSessionExpiryTest
//restart the server
server1.start();
port1 = server1.getPort();
url = "http://localhost:" + port1 + contextPath + servletMapping;
@ -146,12 +181,27 @@ public abstract class AbstractSessionExpiryTest
request.getHeaders().add("Cookie", sessionCookie);
ContentResponse response2 = request.send();
assertEquals(HttpServletResponse.SC_OK,response2.getStatus());
//and wait until the expiry time has passed
pause(inactivePeriod);
verifySessionDestroyed (listener, sessionId);
}
finally
{
server1.stop();
}
}
}
public void verifySessionCreated (TestHttpSessionListener listener, String sessionId)
{
assertTrue(listener.createdSessions.contains(sessionId));
}
public void verifySessionDestroyed (TestHttpSessionListener listener, String sessionId)
{
assertTrue (listener.destroyedSessions.contains(sessionId));
}
public static class TestServlet extends HttpServlet
{

View File

@ -37,7 +37,7 @@ import org.junit.Test;
/**
* AbstractLastAccessTimeTest
* AbstractSessionValueSavingTest
*/
public abstract class AbstractSessionValueSavingTest
{

View File

@ -34,17 +34,38 @@ import org.eclipse.jetty.webapp.WebAppContext;
*/
public abstract class AbstractTestServer
{
public static int DEFAULT_MAX_INACTIVE = 30;
public static int DEFAULT_SCAVENGE = 10;
protected final Server _server;
protected final int _maxInactivePeriod;
protected final int _scavengePeriod;
protected final ContextHandlerCollection _contexts;
protected SessionIdManager _sessionIdManager;
public static String extractSessionId (String sessionCookie)
{
if (sessionCookie == null)
return null;
sessionCookie = sessionCookie.trim();
int i = sessionCookie.indexOf(';');
if (i >= 0)
sessionCookie = sessionCookie.substring(0,i);
if (sessionCookie.startsWith("JSESSIONID"))
sessionCookie = sessionCookie.substring("JSESSIONID=".length());
i = sessionCookie.indexOf('.');
if (i >=0)
sessionCookie = sessionCookie.substring(0,i);
return sessionCookie;
}
public AbstractTestServer(int port)
{
this(port, 30, 10);
this(port, DEFAULT_MAX_INACTIVE, DEFAULT_SCAVENGE);
}
public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod)
@ -52,7 +73,7 @@ public abstract class AbstractTestServer
this (port, maxInactivePeriod, scavengePeriod, null);
}
public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod, String sessionIdMgrConfig)
public AbstractTestServer(int port, int maxInactivePeriod, int scavengePeriod, Object sessionIdMgrConfig)
{
_server = new Server(port);
_maxInactivePeriod = maxInactivePeriod;
@ -64,7 +85,7 @@ public abstract class AbstractTestServer
public abstract SessionIdManager newSessionIdManager(String config);
public abstract SessionIdManager newSessionIdManager(Object config);
public abstract SessionManager newSessionManager();
public abstract SessionHandler newSessionHandler(SessionManager sessionManager);