Merge remote-tracking branch 'origin/jetty-9.4.x'

This commit is contained in:
Joakim Erdfelt 2017-06-13 10:40:02 -07:00
commit 00beb607fc
37 changed files with 2046 additions and 38 deletions

View File

@ -232,6 +232,11 @@
<artifactId>jetty-infinispan</artifactId>
<version>9.4.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-hazelcast</artifactId>
<version>9.4.6-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-io</artifactId>

View File

@ -51,7 +51,7 @@
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>popluate distribution from home</id>
<id>populate distribution from home</id>
<phase>process-resources</phase>
<goals>
<goal>run</goal>

View File

@ -30,6 +30,7 @@ include::session-configuration-file-system.adoc[]
include::session-configuration-jdbc.adoc[]
include::session-configuration-mongodb.adoc[]
include::session-configuration-infinispan.adoc[]
include::session-configuration-hazelcast.adoc[]
include::session-configuration-gcloud.adoc[]
//include::setting-session-characteristics.adoc[]
//include::using-persistent-sessions.adoc[]

View File

@ -0,0 +1,184 @@
// ========================================================================
// Copyright (c) 1995-2017 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.
// ========================================================================
[[configuring-sessions-hazelcast]]
=== Clustered Session Management: Hazelcast
==== Enabling Hazelcast Sessions
When using the Jetty distribution, you will first need to enable the `session-store-hazelcast-remote` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line.
[source, screen, subs="{sub-order}"]
----
mb-olamy:tmp-base olamy$ java -jar ../start.jar --create-startd
MKDIR : ${jetty.base}/start.d
INFO : Base directory was modified
mb-olamy:tmp-base olamy$ java -jar ../start.jar --add-to-start=session-store-hazelcast-remote
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: session-store-hazelcast-remote
+ Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license.
+ https://hazelcast.org/
+ http://www.apache.org/licenses/LICENSE-2.0.html
Proceed (y/N)? y
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : sessions transitively enabled, ini template available with --add-to-start=sessions
INFO : session-store-hazelcast-remote initialized in ${jetty.base}/start.d/session-store-hazelcast-remote.ini
MKDIR : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : ${jetty.base}/lib/hazelcast
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar
INFO : Base directory was modified
----
Doing this enables the remote Hazelcast Session module and any dependent modules or files needed for it to run on the server.
The example above is using a fresh `${jetty.base}` with nothing else enabled.
Because Hazelcast is not a technology provided by the Eclipse Foundation, users are prompted to assent to the licenses of the external vendor (Apache in this case).
When the `--add-to-start` argument was added to the command line, it enabled the the `session-store-hazelcast-remote` module as well as the `sessions` and `server` modules, which are required for Hazelcast session management to operate.
It also downloaded the needed Hazelcast-specific jar files and created a directory named `${jetty.base}/lib/hazelcast/` to house them.
In addition to adding these modules to the classpath of the server it also added several ini configuration files to the `${jetty.base}/start.d` directory.
____
[NOTE]
If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
____
==== Configuring Hazelcast Remote Properties
Opening the `start.d/session-store-hazelcast-remote.ini` will show a list of all the configurable options for the Hazelcast module:
[source, screen, subs="{sub-order}"]
----
# ---------------------------------------
# Module: session-store-hazelcast-remote
# Enables session data store in a remote Hazelcast Map
# ---------------------------------------
--module=session-store-hazelcast-remote
#jetty.session.hazelcast.mapName=jetty_sessions
#jetty.session.hazelcast.onlyClient=true
#jetty.session.hazelcast.configurationLocation=
#jetty.session.gracePeriod.seconds=3600
#jetty.session.savePeriod.seconds=0
----
jetty.session.hazelcast.mapName::
Name of the Map in Hazelcast where sessions will be stored.
jetty.session.hazelcast.onlyClient::
Hazelcast instance will be configured in client mode
jetty.session.hazelcast.configurationLocation::
Path to an an Hazelcast xml configuration file
jetty.session.gracePeriod.seconds::
Amount of time, in seconds, to wait for other nodes to be checked to verify an expired session is in fact expired throughout the cluster before closing it.
jetty.session.savePeriod.seconds=0::
By default whenever the last concurrent request leaves a session, that session is always persisted via the `SessionDataStore`, even if the only thing that changed on the session is its updated last access time.
A non-zero value means that the `SessionDataStore` will skip persisting the session if only the access time changed, and it has been less than `savePeriod` seconds since the last time the session was written.
+
____
[NOTE]
Configuring `savePeriod` is useful if your persistence technology is very slow/costly for writes.
In a clustered environment, there is a risk of the last access time of the session being out-of-date in the shared store for up to `savePeriod` seconds.
This allows the possibility that a node may prematurely expire the session, even though it is in use by another node.
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - there is no point in setting a `savePeriod` that is larger than the `maxIdleTime`.
____
==== Configuring Embedded Hazelcast Clustering
During testing, it can be helpful to run an in-process instance of Hazelcast.
To enable this you will first need to enable the `session-store-hazelcast-embedded` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line.
[source, screen, subs="{sub-order}"]
----
mb-olamy:tmp-base olamy$ java -jar ../start.jar --create-startd
MKDIR : ${jetty.base}/start.d
INFO : Base directory was modified
mb-olamy:tmp-base olamy$ java -jar ../start.jar --add-to-start=session-store-hazelcast-embedded
ALERT: There are enabled module(s) with licenses.
The following 1 module(s):
+ contains software not provided by the Eclipse Foundation!
+ contains software not covered by the Eclipse Public License!
+ has not been audited for compliance with its license
Module: session-store-hazelcast-embedded
+ Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license.
+ https://hazelcast.org/
+ http://www.apache.org/licenses/LICENSE-2.0.html
Proceed (y/N)? y
INFO : server transitively enabled, ini template available with --add-to-start=server
INFO : sessions transitively enabled, ini template available with --add-to-start=sessions
INFO : session-store-hazelcast-embedded initialized in ${jetty.base}/start.d/session-store-hazelcast-embedded.ini
MKDIR : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2
DOWNLD: http://central.maven.org/maven2/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar
MKDIR : ${jetty.base}/lib/hazelcast
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast/3.8.2/hazelcast-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-3.8.2.jar
COPY : /Users/olamy/mvn-repo/com/hazelcast/hazelcast-client/3.8.2/hazelcast-client-3.8.2.jar to ${jetty.base}/lib/hazelcast/hazelcast-client-3.8.2.jar
----
Doing this enables the embedded Hazelcast Session module and any dependent modules or files needed for it to run on the server.
The example above is using a fresh `${jetty.base}` with nothing else enabled.
Because Hazelcast is not a technology provided by the Eclipse Foundation, users are prompted to assent to the licenses of the external vendor (Apache in this case).
When the `--add-to-start` argument was added to the command line, it enabled the the `session-store-hazelcast-embedded` module as well as the `sessions` and `server` modules, which are required for Hazelcast session management to operate.
It also downloaded the needed Hazelcast-specific jar files and created a directory named `${jetty.base}/lib/hazelcast/` to house them.
In addition to adding these modules to the classpath of the server it also added several ini configuration files to the `${jetty.base}/start.d` directory.
==== Configuring Hazelcast Embedded Properties
Opening the `start.d/start.d/session-store-hazelcast-embedded.ini` will show a list of all the configurable options for the Hazelcast module:
[source, screen, subs="{sub-order}"]
----
# ---------------------------------------
# Module: session-store-hazelcast-embedded
# Enables session data store in an embedded Hazelcast Map
# ---------------------------------------
--module=session-store-hazelcast-embedded
#jetty.session.hazelcast.mapName=jetty_sessions
#jetty.session.hazelcast.configurationLocation=
#jetty.session.gracePeriod.seconds=3600
#jetty.session.savePeriod.seconds=0
----
jetty.session.hazelcast.mapName::
Name of the Map in Hazelcast where sessions will be stored.
jetty.session.gracePeriod.seconds::
Amount of time, in seconds, to wait for other nodes to be checked to verify an expired session is in fact expired throughout the cluster before closing it.
jetty.session.hazelcast.configurationLocation::
Path to an an Hazelcast xml configuration file
jetty.session.savePeriod.seconds=0::
By default whenever the last concurrent request leaves a session, that session is always persisted via the `SessionDataStore`, even if the only thing that changed on the session is its updated last access time.
A non-zero value means that the `SessionDataStore` will skip persisting the session if only the access time changed, and it has been less than `savePeriod` seconds since the last time the session was written.
+
____
[NOTE]
Configuring `savePeriod` is useful if your persistence technology is very slow/costly for writes.
In a clustered environment, there is a risk of the last access time of the session being out-of-date in the shared store for up to `savePeriod` seconds.
This allows the possibility that a node may prematurely expire the session, even though it is in use by another node.
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - there is no point in setting a `savePeriod` that is larger than the `maxIdleTime`.
____

View File

@ -16,7 +16,7 @@
[[configuring-sessions-infinispan]]
=== Clustered Session Management: Infinispan
=== Clustered Session Management: Inifinspan
==== Enabling Infinispan Sessions
@ -65,9 +65,9 @@ ____
If you have updated versions of the jar files automatically downloaded by Jetty, you can place them in the associated `${jetty.base}/lib/` directory and use the `--skip-file-validation=<module name>` command line option to prevent errors when starting your server.
____
==== Configuring Infinispan Remote Properties
==== Configuring Inifinspan Remote Properties
Opening the `start.d/session-store-infinispan-remote.ini` will show a list of all the configurable options for the Infinispan module:
Opening the `start.d/session-store-infinispan-remote.ini` will show a list of all the configurable options for the JDBC module:
[source, screen, subs="{sub-order}"]
----
@ -101,7 +101,7 @@ This allows the possibility that a node may prematurely expire the session, even
Thorough consideration of the `maxIdleTime` of the session when setting the `savePeriod` is imperative - there is no point in setting a `savePeriod` that is larger than the `maxIdleTime`.
____
==== Configuring Embedded Infinispan Clustering
==== Configuring Embedded Inifinspan Clustering
During testing, it can be helpful to run an in-process instance of Infinispan.
To enable this you will first need to enable the `session-store-infinispan-embedded` link:#startup-modules[module] for your link:#startup-base-and-home[Jetty base] using the `--add-to-start` argument on the command line.
@ -140,7 +140,7 @@ In addition to adding these modules to the classpath of the server it also added
==== Configuring Inifinspan Embedded Properties
Opening the `start.d/session-store-infinispan-embedded.ini` will show a list of all the configurable options for the Infinispan module:
Opening the `start.d/session-store-infinispan-remote.ini` will show a list of all the configurable options for the JDBC module:
[source, screen, subs="{sub-order}"]
----

88
jetty-hazelcast/pom.xml Normal file
View File

@ -0,0 +1,88 @@
<?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">
<parent>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-project</artifactId>
<version>9.4.7-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>jetty-hazelcast</artifactId>
<name>Jetty :: Hazelcast Session Manager</name>
<properties>
<hazelcast.version>3.8.2</hazelcast.version>
<bundle-symbolic-name>${project.groupId}.hazelcast</bundle-symbolic-name>
</properties>
<dependencies>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>${hazelcast.version}</version>
<type>test-jar</type>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast-client</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>${hazelcast.version}</version>
</dependency>
<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>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-servlet</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<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>
</plugins>
</build>
</project>

View File

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- ===================================================================== -->
<!-- Configure a factory for HazelcastSessionDataStore using -->
<!-- an embedded Hazelcast Instance -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New id="sessionDataStoreFactory" class="org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory">
<Set name="mapName"><Property name="jetty.session.hazelcast.mapName" default="jetty-distributed-session-map" /></Set>
<Set name="hazelcastInstanceName"><Property name="jetty.session.hazelcast.hazelcastInstanceName" default="JETTY_DISTRIBUTED_SESSION_INSTANCE" /></Set>
<Set name="gracePeriodSec"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
<Set name="savePeriodSec"><Property name="jetty.session.savePeriod.seconds" default="0" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,21 @@
<?xml version="1.0"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- ===================================================================== -->
<!-- Configure a factory for HazelcastSessionDataStore using -->
<!-- an embedded Hazelcast Instance -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New id="sessionDataStoreFactory" class="org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory">
<Set name="mapName"><Property name="jetty.session.hazelcast.mapName" default="jetty-distributed-session-map" /></Set>
<Set name="hazelcastInstanceName"><Property name="jetty.session.hazelcast.hazelcastInstanceName" default="JETTY_DISTRIBUTED_SESSION_INSTANCE" /></Set>
<Set name="gracePeriodSec"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
<Set name="savePeriodSec"><Property name="jetty.session.savePeriod.seconds" default="0" /></Set>
<Set name="onlyClient"><Property name="jetty.session.hazelcast.onlyClient" default="true" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,34 @@
[description]
Enables session data store in an embedded Hazelcast Map
[tags]
session
[provides]
session-store
[depend]
sessions
[files]
maven://com.hazelcast/hazelcast/3.8.2|lib/hazelcast/hazelcast-3.8.2.jar
[xml]
etc/sessions/hazelcast/default.xml
[lib]
lib/jetty-hazelcast-${jetty.version}.jar
lib/hazelcast/*.jar
[license]
Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license.
https://hazelcast.org/
http://www.apache.org/licenses/LICENSE-2.0.html
[ini-template]
jetty.session.hazelcast.mapName=jetty-distributed-session-map
jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE
#jetty.session.hazelcast.configurationLocation=
jetty.session.gracePeriod.seconds=3600
jetty.session.savePeriod.seconds=0

View File

@ -0,0 +1,36 @@
[description]
Enables session data store in a remote Hazelcast Map
[tags]
session
[provides]
session-store
[depend]
sessions
[files]
maven://com.hazelcast/hazelcast/3.8.2|lib/hazelcast/hazelcast-3.8.2.jar
maven://com.hazelcast/hazelcast-client/3.8.2|lib/hazelcast/hazelcast-client-3.8.2.jar
[xml]
etc/sessions/hazelcast/remote.xml
[lib]
lib/jetty-hazelcast-${jetty.version}.jar
lib/hazelcast/*.jar
[license]
Hazelcast is an open source project hosted on Github and released under the Apache 2.0 license.
https://hazelcast.org/
http://www.apache.org/licenses/LICENSE-2.0.html
[ini-template]
jetty.session.hazelcast.mapName=jetty-distributed-session-map
jetty.session.hazelcast.hazelcastInstanceName=JETTY_DISTRIBUTED_SESSION_INSTANCE
jetty.session.hazelcast.onlyClient=true
#jetty.session.hazelcast.configurationLocation=
jetty.session.gracePeriod.seconds=3600
jetty.session.savePeriod.seconds=0

View File

@ -0,0 +1,205 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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 com.hazelcast.core.IMap;
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.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;
/**
* Session data stored in Hazelcast
*/
@ManagedObject
public class HazelcastSessionDataStore
extends AbstractSessionDataStore
implements SessionDataStore
{
private final static Logger LOG = Log.getLogger( "org.eclipse.jetty.server.session");
private IMap<String, SessionData> sessionDataMap;
public HazelcastSessionDataStore()
{
// no op
}
@Override
public SessionData load( String id )
throws Exception
{
final AtomicReference<SessionData> reference = new AtomicReference<SessionData>();
final AtomicReference<Exception> exception = new AtomicReference<Exception>();
//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);
}
} );
if (exception.get() != null)
{
throw exception.get();
}
return reference.get();
}
@Override
public boolean delete( String id )
throws Exception
{
return sessionDataMap == null ? false : sessionDataMap.remove( getCacheKey( id ) ) != null;
}
public IMap<String, SessionData> getSessionDataMap()
{
return sessionDataMap;
}
public void setSessionDataMap( IMap<String, SessionData> sessionDataMap )
{
this.sessionDataMap = sessionDataMap;
}
@Override
public void initialize( SessionContext context )
throws Exception
{
_context = context;
}
@Override
public void doStore( String id, SessionData data, long lastSaveTime )
throws Exception
{
this.sessionDataMap.set( getCacheKey( id ), data);
}
@Override
public boolean isPassivating()
{
return true;
}
@Override
public Set<String> doGetExpired( Set<String> candidates )
{
if (candidates == null || candidates.isEmpty())
{
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);
//if the session no longer exists
if (sd == null)
{
if (LOG.isDebugEnabled())
{
LOG.debug( "Session {} does not exist in Hazelcast", candidate );
}
return true;
}
else
{
if (_context.getWorkerName().equals(sd.getLastNode()))
{
//we are its manager, add it to the expired set if it is expired now
if ((sd.getExpiry() > 0 ) && sd.getExpiry() <= now)
{
if (LOG.isDebugEnabled())
{
LOG.debug( "Session {} managed by {} is expired", candidate, _context.getWorkerName() );
}
return true;
}
}
else
{
//if we are not the session's manager, only expire it iff:
// this is our first expiryCheck and the session expired a long time ago
//or
//the session expired at least one graceperiod ago
if (_lastExpiryCheckTime <=0)
{
if ((sd.getExpiry() > 0 ) && sd.getExpiry() < (now - (1000L * (3 * _gracePeriodSec))))
{
return true;
}
}
else
{
if ((sd.getExpiry() > 0 ) && sd.getExpiry() < (now - (1000L * _gracePeriodSec)))
{
return true;
}
}
}
}
}
catch (Exception e)
{
LOG.warn("Error checking if candidate {} is expired so expire it", candidate, e);
return true;
}
return false;
} ).collect( Collectors.toSet() );
}
@Override
public boolean exists( String id )
throws Exception
{
return this.sessionDataMap.containsKey( getCacheKey( id ) );
}
public String getCacheKey( String id )
{
return _context.getCanonicalContextPath() + "_" + _context.getVhost() + "_" + id;
}
}

View File

@ -0,0 +1,178 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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 com.hazelcast.client.HazelcastClient;
import com.hazelcast.client.config.ClientConfig;
import com.hazelcast.client.config.XmlClientConfigBuilder;
import com.hazelcast.config.Config;
import com.hazelcast.config.MapConfig;
import com.hazelcast.config.XmlConfigBuilder;
import com.hazelcast.core.Hazelcast;
import com.hazelcast.core.HazelcastInstance;
import org.eclipse.jetty.server.session.AbstractSessionDataStoreFactory;
import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.eclipse.jetty.server.session.SessionHandler;
import java.io.IOException;
/**
* Factory to construct {@link HazelcastSessionDataStore}
*/
public class HazelcastSessionDataStoreFactory
extends AbstractSessionDataStoreFactory
implements SessionDataStoreFactory
{
private String hazelcastInstanceName = "JETTY_DISTRIBUTED_SESSION_INSTANCE";
private boolean onlyClient;
private String configurationLocation;
private String mapName = "jetty-distributed-session-map";
private HazelcastInstance hazelcastInstance;
private MapConfig mapConfig;
@Override
public SessionDataStore getSessionDataStore( SessionHandler handler )
throws Exception
{
HazelcastSessionDataStore hazelcastSessionDataStore = new HazelcastSessionDataStore();
if ( hazelcastInstance == null )
{
try
{
if ( onlyClient )
{
if ( configurationLocation == null )
{
hazelcastInstance = HazelcastClient.newHazelcastClient( new ClientConfig() );
}
else
{
hazelcastInstance = HazelcastClient.newHazelcastClient(
new XmlClientConfigBuilder( configurationLocation ).build() );
}
}
else
{
Config config;
if ( configurationLocation == null )
{
config = new Config();
// configure a default Map if null
if ( mapConfig == null )
{
mapConfig = new MapConfig();
mapConfig.setName( mapName );
}
else
{
// otherwise we reuse the name
mapName = mapConfig.getName();
}
config.addMapConfig( mapConfig );
}
else
{
config = new XmlConfigBuilder( configurationLocation ).build();
}
config.setInstanceName( hazelcastInstanceName );
hazelcastInstance = Hazelcast.getOrCreateHazelcastInstance( config );
}
}
catch ( IOException e )
{
throw new RuntimeException( e.getMessage(), e );
}
}
// initialize the map
hazelcastSessionDataStore.setSessionDataMap(hazelcastInstance.getMap( mapName ) );
hazelcastSessionDataStore.setGracePeriodSec( getGracePeriodSec() );
hazelcastSessionDataStore.setSavePeriodSec( getSavePeriodSec() );
return hazelcastSessionDataStore;
}
public boolean isOnlyClient()
{
return onlyClient;
}
public void setOnlyClient( boolean onlyClient )
{
this.onlyClient = onlyClient;
}
public String getConfigurationLocation()
{
return configurationLocation;
}
public void setConfigurationLocation( String configurationLocation )
{
this.configurationLocation = configurationLocation;
}
public String getMapName()
{
return mapName;
}
public void setMapName( String mapName )
{
this.mapName = mapName;
}
public HazelcastInstance getHazelcastInstance()
{
return hazelcastInstance;
}
public void setHazelcastInstance( HazelcastInstance hazelcastInstance )
{
this.hazelcastInstance = hazelcastInstance;
}
public MapConfig getMapConfig()
{
return mapConfig;
}
public void setMapConfig( MapConfig mapConfig )
{
this.mapConfig = mapConfig;
}
public String getHazelcastInstanceName()
{
return hazelcastInstanceName;
}
public void setHazelcastInstanceName( String hazelcastInstanceName )
{
this.hazelcastInstanceName = hazelcastInstanceName;
}
}

View File

@ -0,0 +1,197 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.server.HttpConnectionFactory;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.ServerConnector;
import org.eclipse.jetty.server.session.DefaultSessionCache;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
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 java.io.IOException;
import java.io.PrintWriter;
import static org.junit.Assert.*;
public class TestHazelcastSessions
{
public static class TestServlet
extends HttpServlet
{
@Override
protected void doGet( HttpServletRequest req, HttpServletResponse resp )
throws ServletException, IOException
{
String arg = req.getParameter( "action" );
if ( arg == null )
{
return;
}
HttpSession s = null;
if ( "set".equals( arg ) )
{
s = req.getSession( true );
assertNotNull( s );
s.setAttribute( "val", req.getParameter( "value" ) );
}
else if ( "get".equals( arg ) )
{
s = req.getSession( false );
System.err.println( "GET: s=" + s + ",id=" + (s != null ? s.getId() : "" ) );
}
else if ( "del".equals( arg ) )
{
s = req.getSession();
assertNotNull( s );
s.invalidate();
s = null;
}
resp.setContentType( "text/html" );
PrintWriter w = resp.getWriter();
if ( s == null )
{
w.write( "No session" );
}
else
{
w.write( (String) s.getAttribute( "val" ) );
}
}
}
private HazelcastSessionDataStore hazelcastSessionDataStore;
private HazelcastSessionDataStoreFactory hazelcastSessionDataStoreFactory;
private Server server;
private ServerConnector serverConnector;
String contextPath = "/";
@Before
public void initialize()
throws Exception
{
server = new Server();
serverConnector = new ServerConnector( server, new HttpConnectionFactory() );
server.addConnector( serverConnector );
ServletContextHandler context = new ServletContextHandler( ServletContextHandler.SESSIONS );
context.setContextPath( contextPath );
context.setResourceBase( System.getProperty( "java.io.tmpdir" ) );
server.setHandler( context );
SessionContext sessionContext = new SessionContext( "foo", null );
hazelcastSessionDataStoreFactory = new HazelcastSessionDataStoreFactory();
hazelcastSessionDataStore = (HazelcastSessionDataStore) hazelcastSessionDataStoreFactory.getSessionDataStore(
context.getSessionHandler() );
hazelcastSessionDataStore.initialize( sessionContext );
DefaultSessionCache defaultSessionCache = new DefaultSessionCache( context.getSessionHandler() );
defaultSessionCache.setSessionDataStore( hazelcastSessionDataStore );
context.getSessionHandler().setSessionCache( defaultSessionCache );
// Add a test servlet
context.addServlet( new ServletHolder( new TestServlet() ), contextPath );
server.start();
}
@After
public void shutdown()
throws Exception
{
hazelcastSessionDataStoreFactory.getHazelcastInstance().shutdown();
server.stop();
}
@Test
public void testHazelcast()
throws Exception
{
int port = serverConnector.getLocalPort();
HttpClient client = new HttpClient();
client.start();
try
{
int value = 42;
ContentResponse response =
client.GET( "http://localhost:" + port + contextPath + "?action=set&value=" + value );
assertEquals( HttpServletResponse.SC_OK, response.getStatus() );
String sessionCookie = response.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 resp = response.getContentAsString();
assertEquals( resp.trim(), String.valueOf( value ) );
// Be sure the session value is still there
Request request = client.newRequest( "http://localhost:" + port + contextPath + "?action=get" );
request.header( "Cookie", sessionCookie );
response = request.send();
assertEquals( HttpServletResponse.SC_OK, response.getStatus() );
resp = response.getContentAsString();
assertEquals( String.valueOf( value ), resp.trim() );
//Delete the session
request = client.newRequest( "http://localhost:" + port + contextPath + "?action=del" );
request.header( "Cookie", sessionCookie );
response = request.send();
assertEquals( HttpServletResponse.SC_OK, response.getStatus() );
//Check that the session is gone
request = client.newRequest( "http://localhost:" + port + contextPath + "?action=get" );
request.header( "Cookie", sessionCookie );
response = request.send();
assertEquals( HttpServletResponse.SC_OK, response.getStatus() );
resp = response.getContentAsString();
assertEquals( "No session", resp.trim() );
}
finally
{
client.stop();
}
}
}

View File

@ -562,6 +562,11 @@
<artifactId>jetty-infinispan</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-hazelcast</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.gcloud</groupId>
<artifactId>jetty-gcloud-session-manager</artifactId>

View File

@ -53,7 +53,7 @@ public class HttpSenderOverHTTP2 extends HttpSender
{
HttpRequest request = exchange.getRequest();
String path = relativize(request.getPath());
HttpURI uri = new HttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null);
HttpURI uri = HttpURI.createHttpURI(request.getScheme(), request.getHost(), request.getPort(), path, null, request.getQuery(), null);
MetaData.Request metaData = new MetaData.Request(request.getMethod(), uri, HttpVersion.HTTP_2, request.getHeaders());
Supplier<HttpFields> trailers = request.getTrailers();
metaData.setTrailerSupplier(trailers);

View File

@ -19,10 +19,13 @@
package org.eclipse.jetty.websocket.jsr356;
import java.lang.reflect.Method;
import java.util.concurrent.Executor;
import javax.websocket.ContainerProvider;
import javax.websocket.WebSocketContainer;
import org.eclipse.jetty.io.ByteBufferPool;
import org.eclipse.jetty.io.MappedByteBufferPool;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
@ -46,7 +49,9 @@ public class JettyClientContainerProvider extends ContainerProvider
private static boolean useSingleton = false;
private static WebSocketContainer INSTANCE;
private static boolean useServerContainer = false;
private static Executor commonExecutor;
private static ByteBufferPool commonBufferPool;
private static Object lock = new Object();
/**
@ -180,14 +185,21 @@ public class JettyClientContainerProvider extends ContainerProvider
// Still no instance?
if (webSocketContainer == null)
{
// TODO: use cached Executor, ByteBufferPool, and HttpClient here
SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy());
QueuedThreadPool threadPool= new QueuedThreadPool();
String name = "Jsr356Client@" + hashCode();
threadPool.setName(name);
threadPool.setDaemon(true);
containerScope.setExecutor(threadPool);
containerScope.addBean(threadPool);
if (commonExecutor == null)
{
QueuedThreadPool threadPool = new QueuedThreadPool();
String name = "Jsr356Client@" + hashCode();
threadPool.setName(name);
threadPool.setDaemon(true);
commonExecutor = threadPool;
}
if (commonBufferPool == null)
{
commonBufferPool = new MappedByteBufferPool();
}
SimpleContainerScope containerScope = new SimpleContainerScope(WebSocketPolicy.newClientPolicy(), commonBufferPool, commonExecutor, null);
ClientContainer clientContainer = new ClientContainer(containerScope);
if (contextHandler != null && contextHandler instanceof ContainerLifeCycle)
@ -202,7 +214,7 @@ public class JettyClientContainerProvider extends ContainerProvider
// register JVM wide shutdown thread
ShutdownThread.register(clientContainer);
}
if (!clientContainer.isStarted())
{
try

View File

@ -34,31 +34,51 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke
private final ByteBufferPool bufferPool;
private final DecoratedObjectFactory objectFactory;
private final WebSocketPolicy containerPolicy;
private Executor executor;
private final Executor executor;
private SslContextFactory sslContextFactory;
public SimpleContainerScope(WebSocketPolicy containerPolicy)
public SimpleContainerScope(WebSocketPolicy policy)
{
this(containerPolicy, new MappedByteBufferPool(), new DecoratedObjectFactory());
this(policy, new MappedByteBufferPool(), new DecoratedObjectFactory());
this.sslContextFactory = new SslContextFactory();
}
public SimpleContainerScope(WebSocketPolicy containerPolicy, ByteBufferPool bufferPool)
public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool)
{
this(containerPolicy, bufferPool, new DecoratedObjectFactory());
this(policy, bufferPool, new DecoratedObjectFactory());
}
public SimpleContainerScope(WebSocketPolicy containerPolicy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory)
public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, DecoratedObjectFactory objectFactory)
{
this.containerPolicy = containerPolicy;
this(policy, bufferPool, null, objectFactory);
}
public SimpleContainerScope(WebSocketPolicy policy, ByteBufferPool bufferPool, Executor executor, DecoratedObjectFactory objectFactory)
{
this.containerPolicy = policy;
this.bufferPool = bufferPool;
this.objectFactory = objectFactory;
QueuedThreadPool threadPool = new QueuedThreadPool();
String name = "WebSocketContainer@" + hashCode();
threadPool.setName(name);
threadPool.setDaemon(true);
this.executor = threadPool;
addBean(executor);
if (objectFactory == null)
{
this.objectFactory = new DecoratedObjectFactory();
}
else
{
this.objectFactory = objectFactory;
}
if (executor == null)
{
QueuedThreadPool threadPool = new QueuedThreadPool();
String name = "WebSocketContainer@" + hashCode();
threadPool.setName(name);
threadPool.setDaemon(true);
this.executor = threadPool;
addBean(this.executor);
}
else
{
this.executor = executor;
}
}
@Override
@ -72,12 +92,7 @@ public class SimpleContainerScope extends ContainerLifeCycle implements WebSocke
{
return this.executor;
}
public void setExecutor(Executor executor)
{
this.executor = executor;
}
@Override
public DecoratedObjectFactory getObjectFactory()
{

View File

@ -252,7 +252,7 @@ public class DelayedStartClientOnServerTest
List<String> threadNames = getThreadNames(server, (ContainerLifeCycle)container);
assertNoHttpClientPoolThreads(threadNames);
assertThat("Threads", threadNames, hasItem(containsString("WebSocketContainer@")));
assertThat("Threads", threadNames, hasItem(containsString("Jsr356Client@")));
}
finally
{

View File

@ -81,6 +81,7 @@
<module>jetty-infinispan</module>
<module>jetty-gcloud</module>
<module>jetty-memcached</module>
<module>jetty-hazelcast</module>
<module>jetty-unixsocket</module>
<module>tests</module>
<module>examples</module>

View File

@ -21,5 +21,6 @@
<module>test-infinispan-sessions</module>
<module>test-gcloud-sessions</module>
<module>test-memcached-sessions</module>
<module>test-hazelcast-sessions</module>
</modules>
</project>

View File

@ -0,0 +1,94 @@
<?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.7-SNAPSHOT</version>
</parent>
<artifactId>test-hazelcast-sessions</artifactId>
<name>Jetty Tests :: Sessions :: Hazelcast</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.sessions.hazelcast</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>
<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-hazelcast</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>
</project>

View File

@ -0,0 +1,38 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractClusteredLastAccessTimeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
public class ClusteredLastAccessTimeTest
extends AbstractClusteredLastAccessTimeTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,44 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractClusteredOrphanedSessionTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
/**
* ClusteredOrphanedSessionTest
*/
public class ClusteredOrphanedSessionTest
extends AbstractClusteredOrphanedSessionTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,41 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractClusteredSessionMigrationTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
/**
* ClusteredSessionMigrationTest
*/
public class ClusteredSessionMigrationTest
extends AbstractClusteredSessionMigrationTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,41 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
/**
* ClusteredSessionScavengingTest
*/
public class ClusteredSessionScavengingTest
extends AbstractClusteredSessionScavengingTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,42 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractModifyMaxInactiveIntervalTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
/**
* ModifyMaxInactiveIntervalTest
*/
public class ModifyMaxInactiveIntervalTest
extends AbstractModifyMaxInactiveIntervalTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,69 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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 static org.junit.Assert.*;
/**
* 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 )
{
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()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,40 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractSessionExpiryTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.Test;
public class SessionExpiryTest
extends AbstractSessionExpiryTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,41 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractSessionInvalidateCreateScavengeTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
/**
* SessionInvalidateCreateScavengeTest
*/
public class SessionInvalidateCreateScavengeTest
extends AbstractSessionInvalidateCreateScavengeTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,68 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.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 = "jetty_foo_session";
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( "beer" );
// 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

@ -0,0 +1,43 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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 org.eclipse.jetty.hazelcast.session.HazelcastSessionDataStoreFactory;
import org.eclipse.jetty.server.session.AbstractModifyMaxInactiveIntervalTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
/**
* ModifyMaxInactiveIntervalTest
*/
public class ClientModifyMaxInactiveIntervalTest
extends AbstractModifyMaxInactiveIntervalTest
{
/**
* @see org.eclipse.jetty.server.session.AbstractTestBase#createSessionDataStoreFactory()
*/
@Override
public SessionDataStoreFactory createSessionDataStoreFactory()
{
HazelcastSessionDataStoreFactory factory = new HazelcastSessionDataStoreFactory();
return factory;
}
}

View File

@ -0,0 +1,96 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.*;
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 = "jetty_foo_session";
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( "beer" );
// 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

@ -0,0 +1,69 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractClusteredOrphanedSessionTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
public class ClientOrphanedSessionTest
extends AbstractClusteredOrphanedSessionTest
{
private static final String MAP_NAME = "jetty_foo_session";
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( "beer" );
// 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

@ -0,0 +1,70 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.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 = "jetty_foo_session";
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( "beer" );
// 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

@ -0,0 +1,68 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.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 = "jetty_foo_session";
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( "beer" );
// 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

@ -0,0 +1,71 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.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 = "jetty_foo_session";
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( "beer" );
// 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

@ -0,0 +1,69 @@
//
// ========================================================================
// Copyright (c) 1995-2017 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.AbstractClusteredSessionScavengingTest;
import org.eclipse.jetty.server.session.SessionDataStoreFactory;
import org.junit.After;
import org.junit.Before;
public class ClientSessionScavengingTest
extends AbstractClusteredSessionScavengingTest
{
private static final String MAP_NAME = "jetty_foo_session";
private HazelcastInstance hazelcastInstance;
@Before
public void startHazelcast()
throws Exception
{
Config config = new Config().addMapConfig( new MapConfig().setName( MAP_NAME ) ) //
.setInstanceName( "beer" );
// 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;
}
}