Merge branch 'master' into jetty-9.4.x-Feature

This commit is contained in:
Greg Wilkins 2016-04-21 16:34:12 +10:00
commit 4e286266c0
430 changed files with 4961 additions and 7118 deletions

View File

@ -1,6 +1,3 @@
[name]
alpn-boot
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,6 +1,3 @@
[name]
alpn-boot
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,6 +1,3 @@
[name]
alpn-boot
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,6 +1,3 @@
[name]
alpn-boot
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.0.v20141016|lib/alpn/alpn-boot-8.1.0.v20141016.jar

View File

@ -1,6 +1,3 @@
[name]
alpn-boot
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.2.v20141202|lib/alpn/alpn-boot-8.1.2.v20141202.jar

View File

@ -1,6 +1,3 @@
[name]
alpn-boot
[files]
maven://org.mortbay.jetty.alpn/alpn-boot/8.1.3.v20150130|lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.3.v20150130/alpn-boot-8.1.3.v20150130.jar|lib/alpn/alpn-boot-8.1.3.v20150130.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.4.v20150727/alpn-boot-8.1.4.v20150727.jar|lib/alpn/alpn-boot-8.1.4.v20150727.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.5.v20150921/alpn-boot-8.1.5.v20150921.jar|lib/alpn/alpn-boot-8.1.5.v20150921.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.6.v20151105/alpn-boot-8.1.6.v20151105.jar|lib/alpn/alpn-boot-8.1.6.v20151105.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -1,6 +1,3 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.7.v20160121/alpn-boot-8.1.7.v20160121.jar|lib/alpn/alpn-boot-8.1.7.v20160121.jar

View File

@ -0,0 +1,8 @@
[name]
protonego-boot
[files]
http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/8.1.8.v20160420/alpn-boot-8.1.8.v20160420.jar|lib/alpn/alpn-boot-8.1.8.v20160420.jar
[exec]
-Xbootclasspath/p:lib/alpn/alpn-boot-8.1.8.v20160420.jar

View File

@ -15,9 +15,6 @@ specific version of Java.
# All versions of alpn-boot can be found at
# http://central.maven.org/maven2/org/mortbay/jetty/alpn/alpn-boot/
[name]
alpn
[depend]
ssl
alpn-impl/alpn-${java.version}

View File

@ -466,8 +466,6 @@ public class AnnotationConfiguration extends AbstractConfiguration
if (initializers != null && initializers.size()>0)
{
Map<String, Set<String>> map = ( Map<String, Set<String>>) context.getAttribute(AnnotationConfiguration.CLASS_INHERITANCE_MAP);
if (map == null)
LOG.warn ("ServletContainerInitializers: detected. Class hierarchy: empty");
for (ContainerInitializer i : initializers)
i.resolveClasses(context,map);
}

View File

@ -218,6 +218,7 @@ public class Servlet3Continuation implements Continuation, AsyncListener
{
if (isSuspended())
{
_initial=false;
if (ContinuationFilter.__debug)
throw new ContinuationThrowable();
throw __exception;
@ -244,14 +245,12 @@ public class Servlet3Continuation implements Continuation, AsyncListener
@Override
public void onStartAsync(AsyncEvent event) throws IOException
{
_initial=false;
}
/* ------------------------------------------------------------ */
@Override
public void onTimeout(AsyncEvent event) throws IOException
{
_initial=false;
_expired=true;
for (ContinuationListener listener:_listeners)
listener.onTimeout(this);

View File

@ -0,0 +1,13 @@
<?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">
<!-- ============================================================================================== -->
<!-- GCloud configuration when running in the cloud -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<!-- All configuration information is provided by the cloud environment -->
</New>
</Configure>

View File

@ -0,0 +1,14 @@
<?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">
<!-- ============================================================================================== -->
<!-- GCloud configuration for interacting with a local dev gcloud server for testing -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"><Default><Env name="DATASTORE_DATASET"/></Default></Property></Set>
<!-- ensure DATASTORE_HOST System property/environment variable to the url of the dev server -->
</New>
</Configure>

View File

@ -0,0 +1,19 @@
<?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">
<!-- ============================================================================================== -->
<!-- GCloud configuration. -->
<!-- Note: passwords can use jetty obfuscation. See -->
<!-- https://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html -->
<!-- See your start.ini or gcloud-session-store.ini file for more configuration information. -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"><Default><Env name="DATASTORE_DATASET"/></Default></Property></Set>
<Set name="p12File"><Property name="jetty.gcloudSession.p12File"/></Set>
<Set name="serviceAccount"><Property name="jetty.gcloudSession.serviceAccount"/></Set>
<Set name="password"><Property name="jetty.gcloudSession.password"/></Set>
</New>
</Configure>

View File

@ -3,11 +3,17 @@
<Configure id="Server" class="org.eclipse.jetty.server.Server">
<!-- ===================================================================== -->
<!-- Configure a GCloudSessionIdManager -->
<!-- ===================================================================== -->
<Get name="sessionIdManager">
<Set name="workerName"><Property name="jetty.sessionIdManager.workerName"><Default>node<Env name="GAE_MODULE_INSTANCE" default="0"/></Default></Property></Set>
</Get>
<!-- ===================================================================== -->
<!-- Configure a factory for GCloudSessionStores -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.server.session.GCloudSessionStoreFactory">
<Set name="gcloudConfiguration"><Ref id="gconf"/></Set>
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,9 @@
[description]
Enables session storage when running inside the cloud.
[name]
gcloud-embedded
[xml]
etc/jetty-gcloud-embedded.xml

View File

@ -0,0 +1,9 @@
[description]
Enables session storage on a local GCloudDataStore dev server.
[name]
gcloud-local
[xml]
etc/jetty-gcloud-local.xml

View File

@ -0,0 +1,15 @@
[description]
Enables session storage on a remote GCloudDataStore service.
[name]
gcloud-remote
[xml]
etc/jetty-gcloud-remote.xml
[ini-template]
#jetty.gcloudSession.projectId=
#jetty.gcloudSession.p12File=
#jetty.gcloudSession.serviceAccount=
#jetty.gcloudSession.password=

View File

@ -1,12 +1,16 @@
[description]
Enables GCloudDatastore session management.
[name]
gcloud-session-store
[depend]
annotations
webapp
sessions
gcloud-${type}
[files]
maven://com.google.gcloud/gcloud-java-datastore/0.0.7|lib/gcloud/gcloud-java-datastore-0.0.7.jar
maven://com.google.gcloud/gcloud-java-core/0.0.7|lib/gcloud/gcloud-java-core-0.0.7.jar
maven://com.google.auth/google-auth-library-credentials/0.1.0|lib/gcloud/google-auth-library-credentials-0.1.0.jar
@ -49,28 +53,16 @@ GCloudDatastore is an open source project hosted on Github and released under th
https://github.com/GoogleCloudPlatform/gcloud-java
http://www.apache.org/licenses/LICENSE-2.0.html
[xml]
etc/jetty-gcloud-sessions.xml
[ini]
type=remote
[ini-template]
#type=local
#type=embedded
## GCloudDatastore Session config
## If running inside Google cloud all configuration is provided by
## environment variables and you do not need to set anything in this file.
##
## If running externally to Google:
## To contact the remote gcloud datastore:
## 1. set the DATASTORE_DATASET System property/environment variable to the name of your project
## or alternatively set the jetty.gcloudSession.projectId property below.
## 2. set the jetty.gcloudSession.p12File, jetty.gcloudSession.serviceAccount and
## jetty.gcloudSession.password (supports obfuscation) below.
##
## To contact a local dev gcloud datastore server:
## 1. set the DATASTORE_DATASET System property/environment variable to the name of your project.
## 2. set the DATASTORE_HOST System property/environment variable to the url of the dev server
## as described at https://cloud.google.com/datastore/docs/tools/devserver#setting_environment_variables
## The gcloud projectId
## Set this property to connect to remote gcloud datastore.
@ -78,13 +70,13 @@ etc/jetty-gcloud-sessions.xml
#jetty.gcloudSession.projectId=
## The p12 file associated with the project.
## Set this property to connect to remote gcloud datastore
## Set this property only when connecting to remote gcloud datastore
#jetty.gcloudSession.p12File=
## The serviceAccount for the Datastore.
## Set this property to connect to to remote gcloud datastore
## Set this property only when connecting to remote gcloud datastore
#jetty.gcloudSession.serviceAccount=
## The password (can be obfuscated).
## Set this property to connect to remote gcloud datastore
## Set this property only when connecting to remote gcloud datastore
#jetty.gcloudSession.password=

View File

@ -1,42 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<!-- ============================================================================================== -->
<!-- GCloud configuration. -->
<!-- Note: passwords can use jetty obfuscation. See -->
<!-- https://www.eclipse.org/jetty/documentation/current/configuring-security-secure-passwords.html -->
<!-- See your start.ini or gcloud-sessions.ini file for more configuration information. -->
<!-- ============================================================================================== -->
<New id="gconf" class="org.eclipse.jetty.gcloud.session.GCloudConfiguration">
<!-- Either set jetty.gcloudSession.projectId or use system property/env var DATASTORE_DATASET-->
<Set name="projectId"><Property name="jetty.gcloudSession.projectId"/></Set>
<!-- To contact remote gclouddatastore set the following properties in start.ini -->
<Set name="p12File"><Property name="jetty.gcloudSession.p12File"/></Set>
<Set name="serviceAccount"><Property name="jetty.gcloudSession.serviceAccount"/></Set>
<Set name="password"><Property name="jetty.gcloudSession.password"/></Set>
</New>
<Get name="sessionHandler">
<Set name="sessionManager">
<New class="org.eclipse.jetty.gcloud.session.GCloudSessionManager">
<Set name="maxInactiveInterval">seconds</Set>
<Get name="sessionDataStore">
<Set name="gcloudConfiguration">
<Ref id="gconf"/>
</Set>
<Set name="maxResults">integer</Set>
</Get>
<Get name="sessionStore">
<Set name="idlePassivationTimeoutSec">seconds</Set>
<Set name="expiryTimeoutSec">seconds</Set>
</Get>
</New>
</Set>
</Get>
</Configure>

View File

@ -1,87 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.gcloud.session;
import org.eclipse.jetty.server.session.AbstractSessionStore;
import org.eclipse.jetty.server.session.MemorySessionStore;
import org.eclipse.jetty.server.session.SessionManager;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* GCloudSessionManager
*
* Convenience class to link up a MemorySessionStore with the GCloudSessionDataStore.
*
*/
public class GCloudSessionManager extends SessionManager
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
private GCloudSessionDataStore _sessionDataStore = null;
/**
*
*/
public GCloudSessionManager()
{
_sessionDataStore = new GCloudSessionDataStore();
setSessionStore(new MemorySessionStore(this));
}
public GCloudSessionDataStore getSessionDataStore()
{
return _sessionDataStore;
}
/**
* Start the session manager.
*
* @see org.eclipse.jetty.server.session.SessionManager#doStart()
*/
@Override
public void doStart() throws Exception
{
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
super.doStart();
}
/**
* Stop the session manager.
*
* @see org.eclipse.jetty.server.session.SessionManager#doStop()
*/
@Override
public void doStop() throws Exception
{
super.doStop();
}
}

View File

@ -42,7 +42,7 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
import org.eclipse.jetty.server.session.AbstractSessionStore;
import org.eclipse.jetty.server.session.SessionContext;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
@ -51,11 +51,11 @@ import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* GCloudSessionDataStore
* GCloudSessionStore
*
*
*/
public class GCloudSessionDataStore extends AbstractSessionDataStore
public class GCloudSessionStore extends AbstractSessionStore
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
@ -85,7 +85,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStart()
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStart()
*/
@Override
protected void doStart() throws Exception
@ -138,7 +138,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
*/
@Override
public SessionData load(String id) throws Exception
@ -159,7 +159,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
*/
@Override
public boolean delete(String id) throws Exception
@ -170,7 +170,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
*/
@Override
public Set<String> doGetExpired(Set<String> candidates)
@ -264,7 +264,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception
@ -290,7 +290,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
@ -431,7 +431,7 @@ public class GCloudSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
*/
@Override
public boolean isPassivating()

View File

@ -25,6 +25,7 @@ import org.eclipse.jetty.security.HashLoginService;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.AllowSymLinkAliasChecker;
import org.eclipse.jetty.server.session.DefaultSessionIdManager;
import org.eclipse.jetty.server.session.DefaultSessionCache;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.webapp.WebAppContext;
@ -58,10 +59,12 @@ public class GCloudSessionTester
webapp.setContextPath("/");
webapp.setWar("../../jetty-distribution/target/distribution/demo-base/webapps/test.war");
webapp.addAliasCheck(new AllowSymLinkAliasChecker());
GCloudSessionManager mgr = new GCloudSessionManager();
mgr.getSessionDataStore().setGCloudConfiguration(config);
mgr.setSessionIdManager(idmgr);
webapp.setSessionHandler(new SessionHandler(mgr));
GCloudSessionStore ds = new GCloudSessionStore();
ds.setGCloudConfiguration(config);
DefaultSessionCache ss = new DefaultSessionCache(webapp.getSessionHandler());
webapp.getSessionHandler().setSessionStore(ss);
ss.setSessionStore(ds);
webapp.getSessionHandler().setSessionIdManager(idmgr);
// A WebAppContext is a ContextHandler as well so it needs to be set to
// the server so it is aware of where to send the appropriate requests.

View File

@ -18,9 +18,12 @@
package org.eclipse.jetty.http;
import static java.lang.Integer.MIN_VALUE;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
/* ------------------------------------------------------------ */
/**
@ -41,15 +44,44 @@ public class QuotedQualityCSV implements Iterable<String>
private final List<String> _values = new ArrayList<>();
private final List<Double> _quality = new ArrayList<>();
private boolean _sorted = false;
private final Function<String, Integer> secondaryOrderingFunction;
/* ------------------------------------------------------------ */
public QuotedQualityCSV(String... values)
/**
* Sorts values with equal quality according to the length of the value String.
*/
public QuotedQualityCSV()
{
for (String v:values)
addValue(v);
this((s) -> s.length());
}
/**
* Sorts values with equal quality according to given order.
*/
public QuotedQualityCSV(String[] serverPreferredValueOrder)
{
this((s) -> {
for (int i=0;i<serverPreferredValueOrder.length;++i)
if (serverPreferredValueOrder[i].equals(s))
return serverPreferredValueOrder.length-i;
if ("*".equals(s))
return serverPreferredValueOrder.length;
return MIN_VALUE;
});
}
/**
* Orders values with equal quality with the given function.
*/
public QuotedQualityCSV(Function<String, Integer> secondaryOrderingFunction)
{
this.secondaryOrderingFunction = secondaryOrderingFunction;
}
/* ------------------------------------------------------------ */
public void addValue(String value)
{
@ -224,7 +256,7 @@ public class QuotedQualityCSV implements Iterable<String>
_sorted=true;
Double last = ZERO;
int len = Integer.MIN_VALUE;
int lastOrderIndex = Integer.MIN_VALUE;
for (int i = _values.size(); i-- > 0;)
{
@ -232,20 +264,20 @@ public class QuotedQualityCSV implements Iterable<String>
Double q = _quality.get(i);
int compare=last.compareTo(q);
if (compare > 0 || (compare==0 && v.length()<len))
if (compare>0 || (compare==0 && secondaryOrderingFunction.apply(v)<lastOrderIndex))
{
_values.set(i, _values.get(i + 1));
_values.set(i + 1, v);
_quality.set(i, _quality.get(i + 1));
_quality.set(i + 1, q);
last = ZERO;
len=0;
lastOrderIndex=0;
i = _values.size();
continue;
}
last=q;
len=v.length();
lastOrderIndex=secondaryOrderingFunction.apply(v);
}
}

View File

@ -18,6 +18,9 @@
package org.eclipse.jetty.http;
import static org.hamcrest.Matchers.contains;
import static org.junit.Assert.assertThat;
import org.hamcrest.Matchers;
import org.junit.Assert;
import org.junit.Test;
@ -143,4 +146,74 @@ public class QuotedQualityCSVTest
"value1.0",
"value0.5;p=v"));
}
/* ------------------------------------------------------------ */
private static final String[] preferBrotli = {"br","gzip"};
private static final String[] preferGzip = {"gzip","br"};
private static final String[] noFormats = {};
@Test
public void testFirefoxContentEncodingWithBrotliPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
values.addValue("gzip, deflate, br");
assertThat(values, contains("br", "gzip", "deflate"));
}
@Test
public void testFirefoxContentEncodingWithGzipPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(preferGzip);
values.addValue("gzip, deflate, br");
assertThat(values, contains("gzip", "br", "deflate"));
}
@Test
public void testFirefoxContentEncodingWithNoPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(noFormats);
values.addValue("gzip, deflate, br");
assertThat(values, contains("gzip", "deflate", "br"));
}
@Test
public void testChromeContentEncodingWithBrotliPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
values.addValue("gzip, deflate, sdch, br");
assertThat(values, contains("br", "gzip", "deflate", "sdch"));
}
@Test
public void testComplexEncodingWithGzipPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(preferGzip);
values.addValue("gzip;q=0.9, identity;q=0.1, *;q=0.01, deflate;q=0.9, sdch;q=0.7, br;q=0.9");
assertThat(values, contains("gzip", "br", "deflate", "sdch", "identity", "*"));
}
@Test
public void testComplexEncodingWithBrotliPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
values.addValue("gzip;q=0.9, identity;q=0.1, *;q=0, deflate;q=0.9, sdch;q=0.7, br;q=0.99");
assertThat(values, contains("br", "gzip", "deflate", "sdch", "identity"));
}
@Test
public void testStarEncodingWithGzipPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(preferGzip);
values.addValue("br, *");
assertThat(values, contains("*", "br"));
}
@Test
public void testStarEncodingWithBrotliPreference()
{
QuotedQualityCSV values = new QuotedQualityCSV(preferBrotli);
values.addValue("gzip, *");
assertThat(values, contains("*", "gzip"));
}
}

View File

@ -47,9 +47,11 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.ssl.SslContextFactory;
import org.eclipse.jetty.util.thread.ExecutionStrategy;
import org.eclipse.jetty.util.thread.QueuedThreadPool;
import org.eclipse.jetty.util.thread.ScheduledExecutorScheduler;
import org.eclipse.jetty.util.thread.Scheduler;
import org.eclipse.jetty.util.thread.strategy.ProduceConsume;
/**
* <p>{@link HTTP2Client} provides an asynchronous, non-blocking implementation
@ -127,6 +129,7 @@ public class HTTP2Client extends ContainerLifeCycle
private int initialSessionRecvWindow = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
private int initialStreamRecvWindow = FlowControlStrategy.DEFAULT_WINDOW_SIZE;
private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F);
private ExecutionStrategy.Factory executionStrategyFactory = new ProduceConsume.Factory();
@Override
protected void doStart() throws Exception
@ -225,6 +228,16 @@ public class HTTP2Client extends ContainerLifeCycle
this.flowControlStrategyFactory = flowControlStrategyFactory;
}
public ExecutionStrategy.Factory getExecutionStrategyFactory()
{
return executionStrategyFactory;
}
public void setExecutionStrategyFactory(ExecutionStrategy.Factory executionStrategyFactory)
{
this.executionStrategyFactory = executionStrategyFactory;
}
@ManagedAttribute("The number of selectors")
public int getSelectors()
{

View File

@ -39,6 +39,7 @@ import org.eclipse.jetty.io.EndPoint;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.Promise;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.ExecutionStrategy;
import org.eclipse.jetty.util.thread.Scheduler;
public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
@ -67,7 +68,8 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
FlowControlStrategy flowControl = client.getFlowControlStrategyFactory().newFlowControlStrategy();
HTTP2ClientSession session = new HTTP2ClientSession(scheduler, endPoint, generator, listener, flowControl);
Parser parser = new Parser(byteBufferPool, session, 4096, 8192);
HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint, parser, session, client.getInputBufferSize(), promise, listener);
HTTP2ClientConnection connection = new HTTP2ClientConnection(client, byteBufferPool, executor, endPoint,
parser, session, client.getInputBufferSize(), client.getExecutionStrategyFactory(), promise, listener);
connection.addListener(connectionListener);
return connection;
}
@ -78,9 +80,9 @@ public class HTTP2ClientConnectionFactory implements ClientConnectionFactory
private final Promise<Session> promise;
private final Session.Listener listener;
public HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, Parser parser, ISession session, int bufferSize, Promise<Session> promise, Session.Listener listener)
private HTTP2ClientConnection(HTTP2Client client, ByteBufferPool byteBufferPool, Executor executor, EndPoint endpoint, Parser parser, ISession session, int bufferSize, ExecutionStrategy.Factory executionFactory, Promise<Session> promise, Session.Listener listener)
{
super(byteBufferPool, executor, endpoint, parser, session, bufferSize);
super(byteBufferPool, executor, endpoint, parser, session, bufferSize, executionFactory);
this.client = client;
this.promise = promise;
this.listener = listener;

View File

@ -46,14 +46,14 @@ public class HTTP2Connection extends AbstractConnection
private final HTTP2Producer producer = new HTTP2Producer();
private final ExecutionStrategy executionStrategy;
public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, ISession session, int bufferSize)
public HTTP2Connection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, Parser parser, ISession session, int bufferSize, ExecutionStrategy.Factory executionFactory)
{
super(endPoint, executor);
this.byteBufferPool = byteBufferPool;
this.parser = parser;
this.session = session;
this.bufferSize = bufferSize;
this.executionStrategy = ExecutionStrategy.Factory.instanceFor(producer, executor);
this.executionStrategy = executionFactory.newExecutionStrategy(producer, executor);
}
public ISession getSession()

View File

@ -35,6 +35,7 @@ import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.annotation.Name;
import org.eclipse.jetty.util.component.LifeCycle;
import org.eclipse.jetty.util.thread.ExecutionStrategy;
@ManagedObject
public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConnectionFactory
@ -46,6 +47,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
private int maxConcurrentStreams = -1;
private int maxHeaderBlockFragment = 0;
private FlowControlStrategy.Factory flowControlStrategyFactory = () -> new BufferingFlowControlStrategy(0.5F);
private ExecutionStrategy.Factory executionStrategyFactory = ExecutionStrategy.Factory.getDefault();
public AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration)
{
@ -112,6 +114,16 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
this.flowControlStrategyFactory = flowControlStrategyFactory;
}
public ExecutionStrategy.Factory getExecutionStrategyFactory()
{
return executionStrategyFactory;
}
public void setExecutionStrategyFactory(ExecutionStrategy.Factory executionStrategyFactory)
{
this.executionStrategyFactory = executionStrategyFactory;
}
public HttpConfiguration getHttpConfiguration()
{
return httpConfiguration;
@ -135,7 +147,7 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne
ServerParser parser = newServerParser(connector, session);
HTTP2Connection connection = new HTTP2ServerConnection(connector.getByteBufferPool(), connector.getExecutor(),
endPoint, httpConfiguration, parser, session, getInputBufferSize(), listener);
endPoint, httpConfiguration, parser, session, getInputBufferSize(), getExecutionStrategyFactory(), listener);
connection.addListener(connectionListener);
return configure(connection, connector, endPoint);
}

View File

@ -51,6 +51,7 @@ import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
import org.eclipse.jetty.util.ConcurrentArrayQueue;
import org.eclipse.jetty.util.TypeUtil;
import org.eclipse.jetty.util.thread.ExecutionStrategy;
public class HTTP2ServerConnection extends HTTP2Connection implements Connection.UpgradeTo
{
@ -59,9 +60,9 @@ public class HTTP2ServerConnection extends HTTP2Connection implements Connection
private final HttpConfiguration httpConfig;
private final List<Frame> upgradeFrames = new ArrayList<>();
public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ServerParser parser, ISession session, int inputBufferSize, ServerSessionListener listener)
public HTTP2ServerConnection(ByteBufferPool byteBufferPool, Executor executor, EndPoint endPoint, HttpConfiguration httpConfig, ServerParser parser, ISession session, int inputBufferSize, ExecutionStrategy.Factory executionFactory, ServerSessionListener listener)
{
super(byteBufferPool, executor, endPoint, parser, session, inputBufferSize);
super(byteBufferPool, executor, endPoint, parser, session, inputBufferSize, executionFactory);
this.listener = listener;
this.httpConfig = httpConfig;
}

View File

@ -0,0 +1,28 @@
<?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">
<!-- ===================================================================== -->
<!-- Get a reference to the default local cache. -->
<!-- ===================================================================== -->
<New id="local" class="org.infinispan.manager.DefaultCacheManager">
<Get id="cache" name="cache"></Get>
</New>
<!-- ===================================================================== -->
<!-- Configure a factory for InfinispanSessionStore using the -->
<!-- Infinispan DefaultCache -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.server.session.InfinispanSessionStoreFactory">
<Set name="cache"><Ref id="cache"/></Set>
<Set name="infinispanIdleTimeoutSec"><Property name="jetty.session.infinispanIdleTimeout.seconds" default="0" /></Set>
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,30 @@
<?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">
<!-- ===================================================================== -->
<!-- Get a reference to the remote cache. -->
<!-- ===================================================================== -->
<New id="hotrodMgr" class="org.infinispan.client.hotrod.RemoteCacheManager">
<Call id="remoteCache" name="getCache">
<Arg><Property name="jetty.session.remoteInfinispanCache.name" default="sessions"/></Arg>
</Call>
</New>
<!-- ===================================================================== -->
<!-- Configure a factory for InfinispanSessionStore using the -->
<!-- Infinispan DefaultCache -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.server.session.InfinispanSessionStoreFactory">
<Set name="cache"><Ref id="remoteCache"/></Set>
<Set name="infinispanIdleTimeoutSec"><Property name="jetty.session.infinispanIdleTimeout.seconds" default="0" /></Set>
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,10 @@
[description]
Enable use of DefaultCache for session data storage
[name]
infinispan-session-default
[xml]
etc/jetty-default-infinispan-session-store.xml

View File

@ -0,0 +1,12 @@
[description]
Enable use of HotRod remote cache for session data storage
[name]
infinispan-session-remote
[files]
https://raw.githubusercontent.com/eclipse/jetty.project/master/jetty-infinispan/src/main/infinispan-resources/hotrod-client.properties?id=${jetty.tag.version}|resources/hotrod-client.properties
[xml]
etc/jetty-remote-infinispan-session-store.xml

View File

@ -1,10 +1,12 @@
#
# Jetty Infinispan module
#
[description]
Enables session data store in a remote Infinispan cache
[name]
infinispan-session-store
[depend]
annotations
webapp
session
infinispan-session-${cache-type}
[files]
maven://org.infinispan/infinispan-core/7.1.1.Final|lib/infinispan/infinispan-core-7.1.1.Final.jar
@ -17,17 +19,18 @@ maven://org.jboss.logging/jboss-logging/3.1.2.GA|lib/infinispan/jboss-logging-3.
lib/jetty-infinispan-${jetty.version}.jar
lib/infinispan/*.jar
[xml]
etc/jetty-infinispan.xml
[license]
Infinispan is an open source project hosted on Github and released under the Apache 2.0 license.
http://infinispan.org/
http://www.apache.org/licenses/LICENSE-2.0.html
[ini]
cache-type=default
[ini-template]
## Infinispan Session config
## Unique identifier for this node in the cluster
# jetty.infinispanSession.workerName=node1
#cache-type=remote
#jetty.session.remoteInfinispanCache.name=sessions
#jetty.session.infinispanIdleTimeout.seconds=0
#jetty.session.gracePeriod.seconds=3600

View File

@ -1,25 +0,0 @@
[description]
Enables an Infinispan Session Manager for session
persistance and/or clustering
[depend]
annotations
webapp
[files]
maven://org.infinispan/infinispan-core/7.1.1.Final|lib/infinispan/infinispan-core-7.1.1.Final.jar
maven://org.infinispan/infinispan-commons/7.1.1.Final|lib/infinispan/infinispan-commons-7.1.1.Final.jar
maven://org.jgroups/jgroups/3.6.1.Final|lib/infinispan/jgroups-3.6.1.Final.jar
maven://org.jboss.marshalling/jboss-marshalling-osgi/1.4.4.Final|lib/infinispan/jboss-marshalling-osgi-1.4.4.Final.jar
maven://org.jboss.logging/jboss-logging/3.1.2.GA|lib/infinispan/jboss-logging-3.1.2.GA.jar
[lib]
lib/jetty-infinispan-${jetty.version}.jar
lib/infinispan/*.jar
[license]
Infinispan is an open source project hosted on Github and released under the Apache 2.0 license.
http://infinispan.org/
http://www.apache.org/licenses/LICENSE-2.0.html

View File

@ -1,44 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<!-- ===================================================================== -->
<!-- Get a reference to the default local cache. -->
<!-- ===================================================================== -->
<New id="local" class="org.infinispan.manager.DefaultCacheManager">
<Get id="cache" name="cache"></Get>
</New>
<!-- ===================================================================== -->
<!-- Get a reference to a hotrod client for a remote cache. -->
<!-- Change the name of the cache to match your setup. -->
<!-- ===================================================================== -->
<!--
<New id="hotrodMgr" class="org.infinispan.client.hotrod.RemoteCacheManager">
<Call id="cache" name="getCache">
<Arg>sessions</Arg>
</Call>
</New>
-->
<Get name="sessionHandler">
<Set name="sessionManager">
<New class="org.eclipse.jetty.server.session.infinispan.InfinispanSessionManager">
<Set name="maxInactiveInterval">seconds</Set>
<Get name="sessionDataStore">
<Set name="cache">
<Ref id="cache"/>
</Set>
</Get>
<Get name="sessionStore">
<Set name="idlePassivationTimeoutSec">seconds</Set>
<Set name="expiryTimeoutSec">seconds</Set>
</Get>
</New>
</Set>
</Get>
</Configure>

View File

@ -0,0 +1 @@
infinispan.client.hotrod.marshaller=org.eclipse.jetty.session.infinispan.WebAppMarshaller

View File

@ -1,88 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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 org.eclipse.jetty.server.session.AbstractSessionStore;
import org.eclipse.jetty.server.session.MemorySessionStore;
import org.eclipse.jetty.server.session.SessionManager;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* InfinispanSessionManager
*
* Convenience class to create a MemorySessionStore and an InfinispanSessionDataStore.
*
*/
public class InfinispanSessionManager extends SessionManager
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
protected InfinispanSessionDataStore _sessionDataStore;
public InfinispanSessionManager()
{
setSessionStore(new MemorySessionStore(this));
_sessionDataStore = new InfinispanSessionDataStore();
}
/**
* Start the session manager.
*
* @see org.eclipse.jetty.server.session.SessionManager#doStart()
*/
@Override
public void doStart() throws Exception
{
if (_sessionIdManager == null)
throw new IllegalStateException("No session id manager defined");
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
_sessionDataStore.setSessionIdManager(_sessionIdManager);
super.doStart();
}
/**
* Stop the session manager.
*
* @see org.eclipse.jetty.server.session.SessionManager#doStop()
*/
@Override
public void doStop() throws Exception
{
super.doStop();
}
public InfinispanSessionDataStore getSessionDataStore()
{
return _sessionDataStore;
}
}

View File

@ -25,18 +25,18 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
import org.eclipse.jetty.server.session.AbstractSessionStore;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.infinispan.commons.api.BasicCache;
/**
* InfinispanSessionDataStore
* InfinispanSessionStore
*
*
*/
public class InfinispanSessionDataStore extends AbstractSessionDataStore
public class InfinispanSessionStore extends AbstractSessionStore
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
@ -47,7 +47,6 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
*/
private BasicCache<String, Object> _cache;
private SessionIdManager _idMgr = null;
private int _infinispanIdleTimeoutSec;
@ -74,14 +73,10 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
this._cache = cache;
}
public void setSessionIdManager (SessionIdManager idMgr)
{
_idMgr = idMgr;
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#load(String)
* @see org.eclipse.jetty.server.session.SessionStore#load(String)
*/
@Override
public SessionData load(String id) throws Exception
@ -119,7 +114,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(String)
* @see org.eclipse.jetty.server.session.SessionStore#delete(String)
*/
@Override
public boolean delete(String id) throws Exception
@ -130,7 +125,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
*/
@Override
public Set<String> doGetExpired(Set<String> candidates)
@ -201,7 +196,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(String, SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
@ -229,7 +224,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
*/
@Override
public boolean isPassivating()
@ -253,7 +248,7 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception

View File

@ -0,0 +1,90 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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 org.eclipse.jetty.server.session.AbstractSessionStoreFactory;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.server.session.SessionStore;
import org.infinispan.commons.api.BasicCache;
/**
* InfinispanSessionStoreFactory
*
*
*/
public class InfinispanSessionStoreFactory extends AbstractSessionStoreFactory
{
int _infinispanIdleTimeoutSec;
BasicCache<String, Object> _cache;
/**
* @return the infinispanIdleTimeoutSec
*/
public int getInfinispanIdleTimeoutSec()
{
return _infinispanIdleTimeoutSec;
}
/**
* @param infinispanIdleTimeoutSec the infinispanIdleTimeoutSec to set
*/
public void setInfinispanIdleTimeoutSec(int infinispanIdleTimeoutSec)
{
_infinispanIdleTimeoutSec = infinispanIdleTimeoutSec;
}
/**
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionStore(org.eclipse.jetty.server.session.SessionHandler)
*/
@Override
public SessionStore getSessionStore (SessionHandler handler) throws Exception
{
InfinispanSessionStore store = new InfinispanSessionStore();
store.setGracePeriodSec(getGracePeriodSec());
store.setInfinispanIdleTimeoutSec(getInfinispanIdleTimeoutSec());
store.setCache(getCache());
return store;
}
/**
* Get the clustered cache instance.
*
* @return the cache
*/
public BasicCache<String, Object> getCache()
{
return _cache;
}
/**
* Set the clustered cache instance.
*
* @param cache the cache
*/
public void setCache (BasicCache<String, Object> cache)
{
this._cache = cache;
}
}

View File

@ -66,10 +66,15 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable, Dump
private Selector _selector;
public ManagedSelector(SelectorManager selectorManager, int id)
{
this(selectorManager, id, ExecutionStrategy.Factory.getDefault());
}
public ManagedSelector(SelectorManager selectorManager, int id, ExecutionStrategy.Factory executionFactory)
{
_selectorManager = selectorManager;
_id = id;
_strategy = ExecutionStrategy.Factory.instanceFor(new SelectorProducer(), selectorManager.getExecutor());
_strategy = executionFactory.newExecutionStrategy(new SelectorProducer(), selectorManager.getExecutor());
setStopTimeout(5000);
}
@ -554,7 +559,7 @@ public class ManagedSelector extends AbstractLifeCycle implements Runnable, Dump
LOG.debug("rejected accept {}",channel);
closeNoExceptions(channel);
}
@Override
public void run()
{

View File

@ -0,0 +1,20 @@
<?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 MongoSessionStores -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.server.session.MongoSessionStoreFactory">
<Set name="dbName"><Property name="jetty.session.dbName" default="HttpSessions" /></Set>
<Set name="collectionName"><Property name="jetty.session.collectionName" default="jettySessions" /></Set>
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -1,8 +1,11 @@
[description]
Enables NoSql session management with a MongoDB driver.
[name]
mongo-session-store
[depend]
webapp
sessions
[files]
maven://org.mongodb/mongo-java-driver/2.6.1|lib/nosql/mongo-java-driver-2.6.1.jar
@ -17,3 +20,12 @@ The java driver for the MongoDB document-based database system is hosted on GitH
http://www.mongodb.org/
http://www.apache.org/licenses/LICENSE-2.0.html
[xml]
etc/jetty-mongo-session-store.xml
[ini]
#jetty.session.dbName=HttpSessions
#jetty.session.collectionName=jettySessions
#jetty.session.gracePeriod.seconds=3600

View File

@ -1,37 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<!-- ===================================================================== -->
<!-- Get a reference to the session collection -->
<!-- ===================================================================== -->
<New class="com.mongodb.Mongo">
<Call id="sessiondb" name="getDB">
<Arg>HttpSessions</Arg>
<Call id="sessioncollection" name="getCollection">
<Arg>sessions</Arg>
</Call>
</Call>
</New>
<Get name="sessionHandler">
<Set name="sessionManager">
<New class="org.eclipse.jetty.nosql.mongodb.MongoSessionManager">
<Set name="maxInactiveInterval">seconds</Set>
<Get name="sessionDataStore">
<Set name="dBCollection">
<Ref id="sessioncollection"/>
</Set>
</Get>
<Get name="sessionStore">
<Set name="idlePassivationTimeoutSec">seconds</Set>
<Set name="expiryTimeoutSec">seconds</Set>
</Get>
</New>
</Set>
</Get>
</Configure>

View File

@ -22,16 +22,16 @@ package org.eclipse.jetty.nosql;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
import org.eclipse.jetty.server.session.AbstractSessionStore;
import org.eclipse.jetty.server.session.SessionData;
/**
* NoSqlSessionDataStore
* NoSqlSessionStore
*
*
*/
public abstract class NoSqlSessionDataStore extends AbstractSessionDataStore
public abstract class NoSqlSessionStore extends AbstractSessionStore
{
public class NoSqlSessionData extends SessionData

View File

@ -1,138 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import com.mongodb.DBCollection;
import com.mongodb.MongoException;
import java.net.UnknownHostException;
import org.eclipse.jetty.server.SessionIdManager;
import org.eclipse.jetty.server.session.AbstractSessionStore;
import org.eclipse.jetty.server.session.MemorySessionStore;
import org.eclipse.jetty.server.session.SessionManager;
import org.eclipse.jetty.util.annotation.ManagedAttribute;
import org.eclipse.jetty.util.annotation.ManagedObject;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* MongoSessionManager
* <p>
* Clustered session manager using MongoDB as the shared DB instance.
* The document model is an outer object that contains the elements:
* <ul>
* <li>"id" : session_id </li>
* <li>"created" : create_time </li>
* <li>"accessed": last_access_time </li>
* <li>"maxIdle" : max_idle_time setting as session was created </li>
* <li>"expiry" : time at which session should expire </li>
* <li>"valid" : session_valid </li>
* <li>"context" : a nested object containing 1 nested object per context for which the session id is in use
* </ul>
* Each of the nested objects inside the "context" element contains:
* <ul>
* <li>unique_context_name : nested object containing name:value pairs of the session attributes for that context</li>
* </ul>
* <p>
* One of the name:value attribute pairs will always be the special attribute "__metadata__". The value
* is an object representing a version counter which is incremented every time the attributes change.
* </p>
* <p>
* For example:
* <pre>
* { "_id" : ObjectId("52845534a40b66410f228f23"),
* "accessed" : NumberLong("1384818548903"),
* "maxIdle" : 1,
* "context" : { "::/contextA" : { "A" : "A",
* "__metadata__" : { "version" : NumberLong(2) }
* },
* "::/contextB" : { "B" : "B",
* "__metadata__" : { "version" : NumberLong(1) }
* }
* },
* "created" : NumberLong("1384818548903"),
* "expiry" : NumberLong("1384818549903"),
* "id" : "w01ijx2vnalgv1sqrpjwuirprp7",
* "valid" : true
* }
* </pre>
* <p>
* In MongoDB, the nesting level is indicated by "." separators for the key name. Thus to
* interact with a session attribute, the key is composed of:
* <code>"context".unique_context_name.attribute_name</code>
* Eg <code>"context"."::/contextA"."A"</code>
*/
@ManagedObject("Mongo Session Manager")
public class MongoSessionManager extends SessionManager
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
/**
* Access to MongoDB
*/
private DBCollection _dbSessions;
private MongoSessionDataStore _sessionDataStore;
/* ------------------------------------------------------------ */
public MongoSessionManager() throws UnknownHostException, MongoException
{
setSessionStore(new MemorySessionStore(this));
_sessionDataStore = new MongoSessionDataStore();
}
/*------------------------------------------------------------ */
@Override
public void doStart() throws Exception
{
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
super.doStart();
}
public MongoSessionDataStore getSessionDataStore()
{
return _sessionDataStore;
}
/*------------------------------------------------------------ */
/**
* returns the total number of session objects in the session store
*
* the count() operation itself is optimized to perform on the server side
* and avoid loading to client side.
* @return the session store count
*/
@ManagedAttribute("total number of known sessions in the store")
public long getSessionStoreCount()
{
return _dbSessions.find().count();
}
}

View File

@ -36,14 +36,14 @@ import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import org.eclipse.jetty.nosql.NoSqlSessionDataStore;
import org.eclipse.jetty.nosql.NoSqlSessionStore;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.util.ClassLoadingObjectInputStream;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
/**
* MongoSessionDataStore
* MongoSessionStore
*
* The document model is an outer object that contains the elements:
* <ul>
@ -88,7 +88,7 @@ import org.eclipse.jetty.util.log.Logger;
* <code>"context".unique_context_name.attribute_name</code>
* Eg <code>"context"."::/contextA"."A"</code>
*/
public class MongoSessionDataStore extends NoSqlSessionDataStore
public class MongoSessionStore extends NoSqlSessionStore
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
@ -166,7 +166,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#load(String)
* @see org.eclipse.jetty.server.session.SessionStore#load(String)
*/
@Override
public SessionData load(String id) throws Exception
@ -258,7 +258,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(String)
* @see org.eclipse.jetty.server.session.SessionStore#delete(String)
*/
@Override
public boolean delete(String id) throws Exception
@ -318,7 +318,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception
@ -345,7 +345,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
*/
@Override
public Set<String> doGetExpired(Set<String> candidates)
@ -409,7 +409,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(String, SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
@ -648,7 +648,7 @@ public class MongoSessionDataStore extends NoSqlSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
*/
@Override
public boolean isPassivating()

View File

@ -0,0 +1,90 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb;
import java.net.UnknownHostException;
import org.eclipse.jetty.server.session.AbstractSessionStoreFactory;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.server.session.SessionStore;
import com.mongodb.Mongo;
import com.mongodb.MongoException;
/**
* MongoSessionStoreFactory
*
*
*/
public class MongoSessionStoreFactory extends AbstractSessionStoreFactory
{
String _dbName;
String _collectionName;
/**
* @return the dbName
*/
public String getDbName()
{
return _dbName;
}
/**
* @param dbName the dbName to set
*/
public void setDbName(String dbName)
{
_dbName = dbName;
}
/**
* @return the collectionName
*/
public String getCollectionName()
{
return _collectionName;
}
/**
* @param collectionName the collectionName to set
*/
public void setCollectionName(String collectionName)
{
_collectionName = collectionName;
}
/**
* @throws MongoException
* @throws UnknownHostException
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionStore(org.eclipse.jetty.server.session.SessionHandler)
*/
@Override
public SessionStore getSessionStore(SessionHandler handler) throws Exception
{
MongoSessionStore store = new MongoSessionStore();
store.setGracePeriodSec(getGracePeriodSec());
store.setDBCollection(new Mongo().getDB(getDbName()).getCollection(getCollectionName()));
return store;
}
}

View File

@ -1,64 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// All rights reserved. This program and the accompanying materials
// are made available under the terms of the Eclipse Public License v1.0
// and Apache License v2.0 which accompanies this distribution.
//
// The Eclipse Public License is available at
// http://www.eclipse.org/legal/epl-v10.html
//
// The Apache License v2.0 is available at
// http://www.opensource.org/licenses/apache2.0.php
//
// You may elect to redistribute this code under either of these licenses.
// ========================================================================
//
package org.eclipse.jetty.nosql.mongodb.jmx;
import org.eclipse.jetty.nosql.mongodb.MongoSessionManager;
import org.eclipse.jetty.server.handler.AbstractHandlerContainer;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.server.session.jmx.SessionManagerMBean;
import org.eclipse.jetty.util.annotation.ManagedObject;
@ManagedObject("Mongo Session Manager MBean")
public class MongoSessionManagerMBean extends SessionManagerMBean
{
public MongoSessionManagerMBean(Object managedObject)
{
super(managedObject);
}
/* ------------------------------------------------------------ */
public String getObjectContextBasis()
{
if (_managed != null && _managed instanceof MongoSessionManager)
{
MongoSessionManager manager = (MongoSessionManager)_managed;
String basis = null;
SessionHandler handler = manager.getSessionHandler();
if (handler != null)
{
ContextHandler context =
AbstractHandlerContainer.findContainerOf(handler.getServer(),
ContextHandler.class,
handler);
if (context != null)
basis = getContextName(context);
}
if (basis != null)
return basis;
}
return super.getObjectContextBasis();
}
}

View File

@ -1,23 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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.
// ========================================================================
//
/**
* Jetty NoSql : MongoDB Sessions JMX Integration
*/
package org.eclipse.jetty.nosql.mongodb.jmx;

View File

@ -26,6 +26,7 @@ import org.osgi.framework.FrameworkUtil;
import org.osgi.framework.ServiceReference;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventAdmin;
import org.osgi.util.tracker.ServiceTracker;
/**
* Utility class for emiting OSGi EventAdmin events
@ -41,14 +42,13 @@ public class EventSender
private static final EventSender __instance = new EventSender();
private Bundle _myBundle;
private EventAdmin _eventAdmin;
private ServiceTracker _serviceTracker;
private EventSender ()
{
_myBundle = FrameworkUtil.getBundle(EventSender.class);
ServiceReference ref = _myBundle.getBundleContext().getServiceReference(EventAdmin.class.getName());
if (ref != null)
_eventAdmin = (EventAdmin)_myBundle.getBundleContext().getService(ref);
_serviceTracker = new ServiceTracker(_myBundle.getBundleContext(),EventAdmin.class.getName(),null);
_serviceTracker.open();
}
public static EventSender getInstance()
@ -66,24 +66,24 @@ public class EventSender
public void send (String topic, Bundle wab, String contextPath, Exception ex)
{
if (_eventAdmin == null)
return;
Dictionary<String,Object> props = new Hashtable<String,Object>();
props.put("bundle.symbolicName", wab.getSymbolicName());
props.put("bundle.id", wab.getBundleId());
props.put("bundle", wab);
props.put("bundle.version", wab.getVersion());
props.put("context.path", contextPath);
props.put("timestamp", System.currentTimeMillis());
props.put("extender.bundle", _myBundle);
props.put("extender.bundle.symbolicName", _myBundle.getSymbolicName());
props.put("extender.bundle.id", _myBundle.getBundleId());
props.put("extender.bundle.version", _myBundle.getVersion());
if (FAILED_EVENT.equalsIgnoreCase(topic) && ex != null)
props.put("exception", ex);
_eventAdmin.sendEvent(new Event(topic, props));
EventAdmin service = (EventAdmin)_serviceTracker.getService();
if (service != null) {
Dictionary<String,Object> props = new Hashtable<String,Object>();
props.put("bundle.symbolicName", wab.getSymbolicName());
props.put("bundle.id", wab.getBundleId());
props.put("bundle", wab);
props.put("bundle.version", wab.getVersion());
props.put("context.path", contextPath);
props.put("timestamp", System.currentTimeMillis());
props.put("extender.bundle", _myBundle);
props.put("extender.bundle.symbolicName", _myBundle.getSymbolicName());
props.put("extender.bundle.id", _myBundle.getBundleId());
props.put("extender.bundle.version", _myBundle.getVersion());
if (FAILED_EVENT.equalsIgnoreCase(topic) && ex != null)
props.put("exception", ex);
service.sendEvent(new Event(topic, props));
}
}
}

View File

@ -43,7 +43,6 @@ public class OSGiClassLoader extends URLClassLoader
private Bundle _bundle;
private ClassLoader _osgiBundleClassLoader;
private boolean _lookInOsgiFirst = true;
private ClassLoader _parent;
/* ------------------------------------------------------------ */
@ -69,14 +68,6 @@ public class OSGiClassLoader extends URLClassLoader
boolean tried_parent= false;
if (_parent!=null && !_lookInOsgiFirst)
{
tried_parent= true;
if (_parent!=null)
url= _parent.getResource(name);
}
if (url == null)
{
url = _osgiBundleClassLoader.getResource(name);
@ -118,21 +109,6 @@ public class OSGiClassLoader extends URLClassLoader
ClassNotFoundException ex= null;
boolean tried_parent= false;
if (c == null && _parent!=null && !_lookInOsgiFirst)
{
tried_parent= true;
try
{
c= _parent.loadClass(name);
if (LOG.isDebugEnabled())
LOG.debug("loaded " + c);
}
catch (ClassNotFoundException e)
{
ex= e;
}
}
if (c == null)
{
try
@ -166,14 +142,7 @@ public class OSGiClassLoader extends URLClassLoader
{
Enumeration<URL> osgiUrls = _osgiBundleClassLoader.getResources(name);
Enumeration<URL> urls = super.getResources(name);
if (_lookInOsgiFirst)
{
return Collections.enumeration(toList(osgiUrls, urls));
}
else
{
return Collections.enumeration(toList(urls, osgiUrls));
}
return Collections.enumeration(toList(osgiUrls, urls));
}
@ -181,21 +150,7 @@ public class OSGiClassLoader extends URLClassLoader
@Override
protected Class<?> findClass(String name) throws ClassNotFoundException
{
try
{
return _lookInOsgiFirst ? _osgiBundleClassLoader.loadClass(name) : super.findClass(name);
}
catch (ClassNotFoundException cne)
{
try
{
return _lookInOsgiFirst ? super.findClass(name) : _osgiBundleClassLoader.loadClass(name);
}
catch (ClassNotFoundException cne2)
{
throw cne;
}
}
return _osgiBundleClassLoader.loadClass(name);
}

View File

@ -316,15 +316,15 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration impl
}
//session-config
if (context.getSessionHandler().getSessionManager() != null)
if (context.getSessionHandler() != null)
{
out.openTag("session-config");
int maxInactiveSec = context.getSessionHandler().getSessionManager().getMaxInactiveInterval();
int maxInactiveSec = context.getSessionHandler().getMaxInactiveInterval();
out.tag("session-timeout", (maxInactiveSec==0?"0":Integer.toString(maxInactiveSec/60)));
//cookie-config
SessionCookieConfig cookieConfig = context.getSessionHandler().getSessionManager().getSessionCookieConfig();
SessionCookieConfig cookieConfig = context.getSessionHandler().getSessionCookieConfig();
if (cookieConfig != null)
{
out.openTag("cookie-config");
@ -347,7 +347,7 @@ public class QuickStartGeneratorConfiguration extends AbstractConfiguration impl
}
// tracking-modes
Set<SessionTrackingMode> modes =context. getSessionHandler().getSessionManager().getEffectiveSessionTrackingModes();
Set<SessionTrackingMode> modes =context. getSessionHandler().getEffectiveSessionTrackingModes();
if (modes != null)
{
for (SessionTrackingMode mode:modes)

View File

@ -118,7 +118,7 @@ public abstract class LoginAuthenticator implements Authenticator
s.renewId(request);
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
if (s.isIdChanged() && response != null && (response instanceof Response))
((Response)response).addCookie(s.getSessionManager().getSessionCookie(s, request.getContextPath(), request.isSecure()));
((Response)response).addCookie(s.getSessionHandler().getSessionCookie(s, request.getContextPath(), request.isSecure()));
LOG.debug("renew {}->{}",oldId,s.getId());
}
else

View File

@ -0,0 +1,19 @@
<?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 in-memory Session objects -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.server.session.DefaultSessionCacheFactory">
<Set name="idlePassivationTimeoutSec"><Property name="jetty.session.idlePassivationTimeout.seconds" default="0" /></Set>
<Set name="passivateOnComplete"><Property name="jetty.session.passivateOnComplete" default="false" /></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,18 @@
<?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 FileSessionStores -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.server.session.FileSessionStoreFactory">
<Set name="deleteUnrestorableFiles"><Property name="jetty.session.deleteUnrestorableFiles" default="false" /></Set>
<Set name="storeDir"><Property name="jetty.session.storeDir"/></Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -0,0 +1,11 @@
<?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">
<New id="databaseAdaptor" class="org.eclipse.jetty.server.session.DatabaseAdaptor">
<Set name="DatasourceName"><Property name="jetty.session.datasourceName" default="/jdbc/sessions" /></Set>
</New>
</Configure>

View File

@ -0,0 +1,13 @@
<?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">
<New id="databaseAdaptor" class="org.eclipse.jetty.server.session.DatabaseAdaptor">
<Call name="setDriverInfo">
<Arg><Property name="jetty.session.driverClass"/></Arg>
<Arg><Property name="jetty.session.driverUrl"/></Arg>
</Call>
</New>
</Configure>

View File

@ -0,0 +1,65 @@
<?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 JDBCSessionStores -->
<!-- ===================================================================== -->
<Call name="addBean">
<Arg>
<New class="org.eclipse.jetty.server.session.JDBCSessionStoreFactory">
<Set name="gracePeriod"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
<Set name="databaseAdaptor">
<Ref id="databaseAdaptor"/>
</Set>
<Set name="sessionTableSchema">
<New
class="org.eclipse.jetty.server.session.JDBCSessionStore.SessionTableSchema">
<Set name="accessTimeColumn">
<Property name="jetty.sessionTableSchema.accessTimeColumn" default="accessTime" />
</Set>
<Set name="contextPathColumn">
<Property name="jetty.sessionTableSchema.contextPathColumn" default="contextPath" />
</Set>
<Set name="cookieTimeColumn">
<Property name="jetty.sessionTableSchema.cookieTimeColumn" default="cookieTime" />
</Set>
<Set name="createTimeColumn">
<Property name="jetty.sessionTableSchema.createTimeColumn" default="createTime" />
</Set>
<Set name="expiryTimeColumn">
<Property name="jetty.sessionTableSchema.expiryTimeColumn" default="expiryTime" />
</Set>
<Set name="lastAccessTimeColumn">
<Property name="jetty.sessionTableSchema.lastAccessTimeColumn" default="lastAccessTime" />
</Set>
<Set name="lastSavedTimeColumn">
<Property name="jetty.sessionTableSchema.lastSavedTimeColumn" default="lastSavedTime" />
</Set>
<Set name="idColumn">
<Property name="jetty.sessionTableSchema.idColumn" default="sessionId" />
</Set>
<Set name="lastNodeColumn">
<Property name="jetty.sessionTableSchema.lastNodeColumn" default="lastNode" />
</Set>
<Set name="virtualHostColumn">
<Property name="jetty.sessionTableSchema.virtualHostColumn" default="virtualHost" />
</Set>
<Set name="maxIntervalColumn">
<Property name="jetty.sessionTableSchema.maxIntervalColumn" default="maxInterval" />
</Set>
<Set name="mapColumn">
<Property name="jetty.sessionTableSchema.mapColumn" default="map" />
</Set>
<Set name="tableName">
<Property name="jetty.sessionTableSchema.table" default="JettySessions" />
</Set>
</New>
</Set>
</New>
</Arg>
</Call>
</Configure>

View File

@ -12,14 +12,14 @@
<Arg>
<Ref refid="Server"/>
</Arg>
<Set name="workerName"><Property name="jetty.sessionIdManager.workerName" default="node1"/></Set>
<Set name="workerName"><Property name="jetty.sessionIdManager.workerName"><Default>node<Env name="JETTY_WORKER_INSTANCE" default="0"/></Default></Property></Set>
<!-- ===================================================================== -->
<!-- Configure a session inspector to help with scavenging -->
<!-- Configure a session housekeeper to help with scavenging -->
<!-- ===================================================================== -->
<Set name="sessionInspector">
<New id="idMgr" class="org.eclipse.jetty.server.session.PeriodicSessionInspector">
<Set name="intervalSec"><Property name="jetty.sessionInspectionInterval.seconds" default="60"/></Set>
<Set name="sessionHouseKeeper">
<New class="org.eclipse.jetty.server.session.HouseKeeper">
<Set name="intervalSec"><Property name="jetty.sessionScavengeInterval.seconds" default="600"/></Set>
</New>
</Set>
</New>

View File

@ -0,0 +1,16 @@
[description]
Always in memory session objects.
[name]
default-session-cache
[xml]
etc/jetty-default-session-cache.xml
[ini-template]
#jetty.session.idlePassivationTimeout.seconds=0
#jetty.session.passivateOnComplete=false

View File

@ -0,0 +1,21 @@
[description]
Enables session storage in files.
[name]
file-session-store
[xml]
etc/jetty-file-session-store.xml
[depend]
sessions
[ini-template]
#jetty.session.storeDir=
#jetty.session.deleteUnrestorableFiles=false

View File

@ -0,0 +1,57 @@
[description]
Enables JDBC session storage.
[name]
jdbc-session-store
[xml]
etc/jetty-jdbc-session-store.xml
[depend]
sessions
sessions/jdbc/${db-connection-type}
[ini]
db-connection-type=datasource
##
##JDBC Session properties
##
#jetty.session.gracePeriod.seconds=3600
## Connection type:driver
#db-connection-type=driver
#jetty.session.driverClass=
#jetty.session.driverUrl=
## Connection type:Datasource
#db-connection-type=datasource
#jetty.session.datasourceName=/jdbc/sessions
## Session table schema
#jetty.sessionTableSchema.accessTimeColumn=accessTime
#jetty.sessionTableSchema.contextPathColumn=contextPath
#jetty.sessionTableSchema.cookieTimeColumn=cookieTime
#jetty.sessionTableSchema.createTimeColumn=createTime
#jetty.sessionTableSchema.expiryTimeColumn=expiryTime
#jetty.sessionTableSchema.lastAccessTimeColumn=lastAccessTime
#jetty.sessionTableSchema.lastSavedTimeColumn=lastSavedTime
#jetty.sessionTableSchema.idColumn="sessionId
#jetty.sessionTableSchema.lastNodeColumn=lastNode
#jetty.sessionTableSchema.virtualHostColumn=virtualHost
#jetty.sessionTableSchema.maxIntervalColumn=maxInterval
#jetty.sessionTableSchema.mapColumn=map
#jetty.sessionTableSchema.table=JettySessions

View File

@ -1,13 +1,20 @@
[description]
Enables basic sessions.
Enables session id management and scavenging.
[name]
sessions
[xml]
etc/jetty-sessions.xml
[ini-template]
## The name to uniquely identify this server instance
#jetty.sssionIdManager.workerName=node1
#jetty.sessionIdManager.workerName=node1
## How frequently sessions are inspected
#jetty.sessionInspectionInterval.seconds=60
## Period between runs of the session scavenger (in seconds)
#jetty.sessionScavengeInterval.seconds=60

View File

@ -0,0 +1,9 @@
[description]
JDBC Datasource connections for session storage
[name]
datasource
[xml]
etc/jetty-jdbc-session-store-datasource.xml

View File

@ -0,0 +1,9 @@
[description]
JDBC Driver connections for session storage
[name]
driver
[xml]
etc/jetty-jdbc-session-store-driver.xml

View File

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="sessionHandler">
<Set name="sessionManager">
<New class="org.eclipse.jetty.server.session.FileSessionManager">
<Set name="maxInactiveInterval">seconds</Set>
<Get name="sessionDataStore">
<Set name="storeDir">filename</Set>
<Set name="deleteUnrestorableFiles">boolean</Set>
</Get>
<Get name="sessionStore">
<Set name="idlePassivationTimeoutSec">seconds</Set>
<Set name="expiryTimeoutSec">seconds</Set>
</Get>
</New>
</Set>
</Get>
</Configure>

View File

@ -1,50 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure_9_3.dtd">
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Get name="sessionHandler">
<Set name="sessionManager">
<New class="org.eclipse.jetty.server.session.JDBCSessionManager">
<Set name="maxInactiveInterval">seconds</Set>
<Get name="sessionDataStore">
<Set name="gracePeriod">seconds</Set>
<Set name="loadAttempts">integer</Set>
<Set name="deleteUnloadableSessions">boolean</Set>
<Set name="databaseAdaptor">
<New class="org.eclipse.jetty.server.session.DatabaseAdaptor">
<!-- or alternative -->
<Call name="setDriverInfo">
<Arg>driver class</Arg>
<Arg>URL</Arg>
</Call>
</New>
</Set>
<Set name="sessionTableSchema">
<New class="org.eclipse.jetty.server.session.JDBCSessionDataStore.SessionTableSchema">
<Set name="tableName">JettySessions</Set>
<Set name="idColumn">sessionId</Set>
<Set name="accessTimeColumn">accessTime</Set>
<Set name="contextPathColumn">contextPath</Set>
<Set nmae="cookieTimeColumn">cookieTime</Set>
<Set name="createTimeColumn">createTime</Set>
<Set name="expiryTimeColumn">expiryTime</Set>
<Set name="lastAccessTimeColumn">lastAccessTime</Set>
<Set name="lastNodeColumn">lastNode</Set>
<Set name="lastSavedTimeColumn">lastSavedTime</Set>
<Set name="mapColumn">map</Set>
<Set name="maxIntervalColumn">maxInterval</Set>
<Set name="virtualHostColumn">virtualHost</Set>
</New>
</Get>
<Get name="sessionStore">
<Set name="idlePassivationTimeoutSec">seconds</Set>
<Set name="expiryTimeoutSec">seconds</Set>
</Get>
</New>
</Set>
</Get>
</Configure>

View File

@ -78,7 +78,7 @@ import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ContextHandler.Context;
import org.eclipse.jetty.server.session.Session;
import org.eclipse.jetty.server.session.SessionManager;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.Attributes;
import org.eclipse.jetty.util.AttributesMap;
import org.eclipse.jetty.util.IO;
@ -194,7 +194,7 @@ public class Request implements HttpServletRequest
private Map<Object, HttpSession> _savedNewSessions;
private UserIdentity.Scope _scope;
private HttpSession _session;
private SessionManager _sessionManager;
private SessionHandler _sessionHandler;
private long _timeStamp;
private MultiPartInputStreamParser _multiPartInputStream; //if the request is a multi-part mime
private AsyncContextState _async;
@ -1478,7 +1478,7 @@ public class Request implements HttpServletRequest
if (getRemoteUser() != null)
s.setAttribute(Session.SESSION_CREATED_SECURE, Boolean.TRUE);
if (s.isIdChanged())
_channel.getResponse().addCookie(_sessionManager.getSessionCookie(s, getContextPath(), isSecure()));
_channel.getResponse().addCookie(_sessionHandler.getSessionCookie(s, getContextPath(), isSecure()));
}
return session.getId();
@ -1503,7 +1503,7 @@ public class Request implements HttpServletRequest
{
if (_session != null)
{
if (_sessionManager != null && !_sessionManager.isValid(_session))
if (_sessionHandler != null && !_sessionHandler.isValid(_session))
_session = null;
else
return _session;
@ -1515,11 +1515,11 @@ public class Request implements HttpServletRequest
if (getResponse().isCommitted())
throw new IllegalStateException("Response is committed");
if (_sessionManager == null)
if (_sessionHandler == null)
throw new IllegalStateException("No SessionManager");
_session = _sessionManager.newHttpSession(this);
HttpCookie cookie = _sessionManager.getSessionCookie(_session,getContextPath(),isSecure());
_session = _sessionHandler.newHttpSession(this);
HttpCookie cookie = _sessionHandler.getSessionCookie(_session,getContextPath(),isSecure());
if (cookie != null)
_channel.getResponse().addCookie(cookie);
@ -1530,9 +1530,9 @@ public class Request implements HttpServletRequest
/**
* @return Returns the sessionManager.
*/
public SessionManager getSessionManager()
public SessionHandler getSessionHandler()
{
return _sessionManager;
return _sessionHandler;
}
/* ------------------------------------------------------------ */
@ -1682,7 +1682,7 @@ public class Request implements HttpServletRequest
return false;
HttpSession session = getSession(false);
return (session != null && _sessionManager.getSessionIdManager().getId(_requestedSessionId).equals(_sessionManager.getId(session)));
return (session != null && _sessionHandler.getSessionIdManager().getId(_requestedSessionId).equals(_sessionHandler.getId(session)));
}
/* ------------------------------------------------------------ */
@ -1831,7 +1831,7 @@ public class Request implements HttpServletRequest
_requestedSessionIdFromCookie = false;
_secure=false;
_session = null;
_sessionManager = null;
_sessionHandler = null;
_scope = null;
_servletPath = null;
_timeStamp = 0;
@ -2185,9 +2185,9 @@ public class Request implements HttpServletRequest
* @param sessionManager
* The sessionManager to set.
*/
public void setSessionManager(SessionManager sessionManager)
public void setSessionHandler(SessionHandler sessionHandler)
{
_sessionManager = sessionManager;
_sessionHandler = sessionHandler;
}
/* ------------------------------------------------------------ */

View File

@ -18,9 +18,10 @@
package org.eclipse.jetty.server;
import static java.util.Arrays.stream;
import static java.util.Collections.emptyList;
import static org.eclipse.jetty.http.CompressedContentFormat.BR;
import static org.eclipse.jetty.http.CompressedContentFormat.GZIP;
import static org.eclipse.jetty.http.HttpFields.qualityList;
import static org.eclipse.jetty.http.HttpHeaderValue.IDENTITY;
import java.io.FileNotFoundException;
@ -32,6 +33,7 @@ import java.util.Collection;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.AsyncContext;
import javax.servlet.RequestDispatcher;
@ -48,6 +50,7 @@ import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.http.QuotedCSV;
import org.eclipse.jetty.http.QuotedQualityCSV;
import org.eclipse.jetty.io.WriterOutputStream;
import org.eclipse.jetty.util.BufferUtil;
import org.eclipse.jetty.util.Callback;
@ -73,6 +76,9 @@ public abstract class ResourceService
private boolean _dirAllowed=true;
private boolean _redirectWelcome=false;
private CompressedContentFormat[] _precompressedFormats=new CompressedContentFormat[0];
private String[] _preferredEncodingOrder =new String[0];
private final Map<String, List<String>> _preferredEncodingOrderCache = new ConcurrentHashMap<>();
private int _encodingCacheSize=100;
private boolean _pathInfoOnly=false;
private boolean _etags=false;
private HttpField _cacheControl;
@ -126,6 +132,17 @@ public abstract class ResourceService
public void setPrecompressedFormats(CompressedContentFormat[] precompressedFormats)
{
_precompressedFormats = precompressedFormats;
_preferredEncodingOrder = stream(_precompressedFormats).map(f->f._encoding).toArray(String[]::new);
}
public void setEncodingCacheSize(int encodingCacheSize)
{
_encodingCacheSize = encodingCacheSize;
}
public int getEncodingCacheSize()
{
return _encodingCacheSize;
}
public boolean isPathInfoOnly()
@ -249,7 +266,7 @@ public abstract class ResourceService
// Tell caches that response may vary by accept-encoding
response.addHeader(HttpHeader.VARY.asString(),HttpHeader.ACCEPT_ENCODING.asString());
List<String> preferredEncodings = HttpFields.qualityList(request.getHeaders(HttpHeader.ACCEPT_ENCODING.asString()));
List<String> preferredEncodings = getPreferredEncodingOrder(request);
CompressedContentFormat precompressedContentEncoding = getBestPrecompressedContent(preferredEncodings, precompressedContents.keySet());
if (precompressedContentEncoding!=null)
{
@ -285,6 +302,40 @@ public abstract class ResourceService
}
}
private List<String> getPreferredEncodingOrder(HttpServletRequest request)
{
Enumeration<String> headers = request.getHeaders(HttpHeader.ACCEPT_ENCODING.asString());
if (!headers.hasMoreElements())
return emptyList();
String key = headers.nextElement();
if (headers.hasMoreElements())
{
StringBuilder sb = new StringBuilder(key.length()*2);
do
{
sb.append(',').append(headers.nextElement());
} while (headers.hasMoreElements());
key = sb.toString();
}
List<String> values=_preferredEncodingOrderCache.get(key);
if (values==null)
{
QuotedQualityCSV encodingQualityCSV = new QuotedQualityCSV(_preferredEncodingOrder);
encodingQualityCSV.addValue(key);
values=encodingQualityCSV.getValues();
// keep cache size in check even if we get strange/malicious input
if (_preferredEncodingOrderCache.size()>_encodingCacheSize)
_preferredEncodingOrderCache.clear();
_preferredEncodingOrderCache.put(key,values);
}
return values;
}
private CompressedContentFormat getBestPrecompressedContent(List<String> preferredEncodings, Collection<CompressedContentFormat> availableFormats)
{
if (availableFormats.isEmpty())

View File

@ -53,7 +53,7 @@ import org.eclipse.jetty.http.PreEncodedHttpField;
import org.eclipse.jetty.io.RuntimeIOException;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.ErrorHandler;
import org.eclipse.jetty.server.session.SessionManager;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.QuotedStringTokenizer;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.URIUtil;
@ -391,7 +391,8 @@ public class Response implements HttpServletResponse
public String encodeURL(String url)
{
final Request request = _channel.getRequest();
SessionManager sessionManager = request.getSessionManager();
SessionHandler sessionManager = request.getSessionHandler();
if (sessionManager == null)
return url;

View File

@ -22,7 +22,7 @@ import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.server.session.SessionManager;
import org.eclipse.jetty.server.session.SessionHandler;
import org.eclipse.jetty.util.component.LifeCycle;
/**
@ -109,8 +109,8 @@ public interface SessionIdManager extends LifeCycle
/* ------------------------------------------------------------ */
/**
* Get the set of all session managers for this node
* @return the set of session managers
* Get the set of all session handlers for this node
* @return the set of session handlers
*/
public Set<SessionManager> getSessionManagers();
public Set<SessionHandler> getSessionHandlers();
}

View File

@ -0,0 +1,639 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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.util.Collections;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker.Lock;
/**
* AbstractSessionCache
*
* Basic behaviour for maintaining an in-memory store of Session objects and
* making sure that any backing SessionDataStore is kept in sync.
*/
public abstract class AbstractSessionCache extends AbstractLifeCycle implements SessionCache
{
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
protected SessionStore _sessionStore;
protected final SessionHandler _handler;
protected SessionContext _context;
protected int _idlePassivationTimeoutSec;
private boolean _passivateOnComplete;
/**
* Create a new Session object from pre-existing session data
* @param data the session data
* @return a new Session object
*/
public abstract Session newSession (SessionData data);
/**
* Create a new Session for a request.
*
* @param request the request
* @param data the session data
* @return the new session
*/
public abstract Session newSession (HttpServletRequest request, SessionData data);
/**
* Get the session matching the key
* @param id session id
* @return the Session object matching the id
*/
public abstract Session doGet(String id);
/**
* Put the session into the map if it wasn't already there
*
* @param id the identity of the session
* @param session the session object
* @return null if the session wasn't already in the map, or the existing entry otherwise
*/
public abstract Session doPutIfAbsent (String id, Session session);
/**
* Replace the mapping from id to oldValue with newValue
* @param id the id
* @param oldValue the old value
* @param newValue the new value
* @return true if replacement was done
*/
public abstract boolean doReplace (String id, Session oldValue, Session newValue);
/**
* Remove the session with this identity from the store
* @param id the id
* @return true if removed false otherwise
*/
public abstract Session doDelete (String id);
/**
* PlaceHolder
*/
protected class PlaceHolderSession extends Session
{
/**
* @param data the session data
*/
public PlaceHolderSession(SessionData data)
{
super(data);
}
}
/**
*
*/
public AbstractSessionCache (SessionHandler manager)
{
_handler = manager;
}
/**
* @return the SessionManger
*/
public SessionHandler getSessionHandler()
{
return _handler;
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#initialize(org.eclipse.jetty.server.session.SessionContext)
*/
public void initialize (SessionContext context)
{
if (isStarted())
throw new IllegalStateException("Context set after session store started");
_context = context;
}
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
*/
@Override
protected void doStart() throws Exception
{
if (_sessionStore == null)
throw new IllegalStateException ("No session data store configured");
if (_handler == null)
throw new IllegalStateException ("No session manager");
if (_context == null)
throw new IllegalStateException ("No ContextId");
_sessionStore.initialize(_context);
_sessionStore.start();
super.doStart();
}
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
*/
@Override
protected void doStop() throws Exception
{
_sessionStore.stop();
super.doStop();
}
/**
* @return the SessionStore or null if there isn't one
*/
public SessionStore getSessionStore()
{
return _sessionStore;
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#setSessionStore(org.eclipse.jetty.server.session.SessionStore)
*/
public void setSessionStore(SessionStore sessionStore)
{
_sessionStore = sessionStore;
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#getIdlePassivationTimeoutSec()
*/
public int getIdlePassivationTimeoutSec()
{
return _idlePassivationTimeoutSec;
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#setIdlePassivationTimeoutSec(int)
*/
public void setIdlePassivationTimeoutSec(int idleTimeoutSec)
{
_idlePassivationTimeoutSec = idleTimeoutSec;
}
/**
* Get a session object.
*
* If the session object is not in this session store, try getting
* the data for it from a SessionDataStore associated with the
* session manager.
*
* @see org.eclipse.jetty.server.session.SessionCache#get(java.lang.String)
*/
@Override
public Session get(String id) throws Exception
{
Session session = null;
Exception ex = null;
while (true)
{
session = doGet(id);
if (_sessionStore == null)
break; //can't load any session data so just return null or the session object
if (session == null)
{
if (LOG.isDebugEnabled())
LOG.debug("Session not found locally, attempting to load");
//didn't get a session, try and create one and put in a placeholder for it
PlaceHolderSession phs = new PlaceHolderSession (new SessionData(id, null, null,0,0,0,0));
Lock phsLock = phs.lock();
Session s = doPutIfAbsent(id, phs);
if (s == null)
{
//My placeholder won, go ahead and load the full session data
try
{
session = loadSession(id);
if (session == null)
{
//session does not exist, remove the placeholder
doDelete(id);
phsLock.close();
break;
}
try (Lock lock = session.lock())
{
//swap it in instead of the placeholder
boolean success = doReplace(id, phs, session);
if (!success)
{
//something has gone wrong, it should have been our placeholder
doDelete(id);
session = null;
LOG.warn("Replacement of placeholder for session {} failed", id);
phsLock.close();
break;
}
else
{
//successfully swapped in the session
session.setTimeout (); //TODO start the session timer
phsLock.close();
break;
}
}
}
catch (Exception e)
{
ex = e; //remember a problem happened loading the session
doDelete(id); //remove the placeholder
phsLock.close();
session = null;
break;
}
}
else
{
//my placeholder didn't win, check the session returned
phsLock.close();
try (Lock lock = s.lock())
{
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
if (s.isPassivated() || s instanceof PlaceHolderSession)
{
session = null;
continue;
}
session = s;
break;
}
}
}
else
{
//check the session returned
try (Lock lock = session.lock())
{
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
if (session.isPassivated() || session instanceof PlaceHolderSession)
{
session = null;
continue;
}
//got the session
break;
}
}
}
if (ex != null)
throw ex;
return session;
}
/**
* Load the info for the session from the session data store
*
* @param id the id
* @return a Session object filled with data or null if the session doesn't exist
* @throws Exception
*/
private Session loadSession (String id)
throws Exception
{
SessionData data = null;
Session session = null;
if (_sessionStore == null)
return null; //can't load it
try
{
data =_sessionStore.load(id);
if (data == null) //session doesn't exist
return null;
session = newSession(data);
session.setSessionHandler(_handler);
return session;
}
catch (UnreadableSessionDataException e)
{
//can't load the session, delete it
_sessionStore.delete(id);
throw e;
}
}
/**
* Put the Session object back into the session store.
*
* This should be called by Session.complete when a request exists the session.
*
* If the session manager supports a session data store, write the
* session data through to the session data store.
*
* @see org.eclipse.jetty.server.session.SessionCache#put(java.lang.String, org.eclipse.jetty.server.session.Session)
*/
@Override
public void put(String id, Session session) throws Exception
{
if (id == null || session == null)
throw new IllegalArgumentException ("Put key="+id+" session="+(session==null?"null":session.getId()));
//if the session is new or data has changed write it to any backing store
try (Lock lock = session.lock())
{
session.setSessionHandler(_handler);
if (session.isPassivated())
throw new IllegalStateException ("Session "+id+" is passivated and cannot be saved");
if (!session.isValid())
return;
if (_sessionStore == null)
{
doPutIfAbsent(id, session); //ensure it is in our map
return;
}
if ((session.getRequests() <= 0))
{
//only save if all requests have finished
if (!_sessionStore.isPassivating())
{
//if our backing datastore isn't the passivating kind, just save the session
_sessionStore.store(id, session.getSessionData());
}
else
{
//backing store supports passivation
session.willPassivate();
_sessionStore.store(id, session.getSessionData());
session.setPassivated();
if (isPassivateOnComplete())
{
//throw out the passivated session object from the map
doDelete(id);
}
else
{
//reactivate the session
session.setActive();
session.didActivate();
}
}
}
doPutIfAbsent(id,session); //ensure it is in our map
}
}
/**
* Check to see if a session corresponding to the id exists.
*
* This method will first check with the object store. If it
* doesn't exist in the object store (might be passivated etc),
* it will check with the data store.
* @throws Exception
*
* @see org.eclipse.jetty.server.session.SessionCache#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception
{
//try the object store first
Session s = doGet(id);
if (s != null)
{
try (Lock lock = s.lock())
{
//wait for the lock and check the validity of the session
return s.isValid();
}
}
//not there, so find out if session data exists for it
return _sessionStore.exists (id);
}
/**
* Remove a session object from this store and from any backing store.
*
*
* @see org.eclipse.jetty.server.session.SessionCache#delete(java.lang.String)
*/
@Override
public Session delete(String id) throws Exception
{
//get the session, if its not in memory, this will load it
Session session = get(id);
//Always delete it from the backing data store
if (_sessionStore != null)
{
boolean dsdel = _sessionStore.delete(id);
if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in db {}",id, dsdel);
}
//delete it from the session object store
if (session != null)
session.stopTimeout();
return doDelete(id);
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#checkExpiration(Set)
*/
@Override
public Set<String> checkExpiration(Set<String> candidates)
{
if (!isStarted())
return Collections.emptySet();
if (LOG.isDebugEnabled())
LOG.debug("SessionStore checking expiration on {}", candidates);
return _sessionStore.getExpired(candidates);
}
/**
* If the SessionDataStore supports passivation,
* write the session to the backing data store.
*
* @param id identity of session to passivate
*/
@Override
public void passivateIdleSession(String id)
{
if (!isStarted())
return;
if (_sessionStore == null || !_sessionStore.isPassivating())
return; //no data store to passivate or it doesn't passivate
//get the session locally
Session s = doGet(id);
if (s == null)
{
LOG.warn("Session {} not in this session store", s);
return;
}
//lock the session during passivation
try (Lock lock = s.lock())
{
//check the session is still idle and that it doesn't have requests using it
if (s.isValid() && s.isIdleLongerThan(_idlePassivationTimeoutSec) && s.isActive() && (s.getRequests() <= 0))
{
//TODO - do we need to check that the session exists in the session data store
//before we passivate it? If it doesn't exist, we can assume another node
//invalidated it. If the session was new, it shouldn't have been idle passivated.
try
{
if (LOG.isDebugEnabled())
LOG.debug("Passivating idle session {}", id);
s.willPassivate();
_sessionStore.store(id, s.getSessionData());
s.setPassivated();
s.stopTimeout();
doDelete(id); //Take the session object of this session store
}
catch (Exception e)
{
LOG.warn("Passivation of idle session {} failed", id, e);
s.setPassivated(); //set it as passivated so it can't be used
doDelete(id); //detach it
}
}
}
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#renewSessionId(java.lang.String, java.lang.String)
*/
public Session renewSessionId (String oldId, String newId)
throws Exception
{
if (StringUtil.isBlank(oldId))
throw new IllegalArgumentException ("Old session id is null");
if (StringUtil.isBlank(newId))
throw new IllegalArgumentException ("New session id is null");
Session session = get(oldId);
if (session == null)
return null;
try (Lock lock = session.lock())
{
session.checkValidForWrite(); //can't change id on invalid session
session.getSessionData().setId(newId);
session.getSessionData().setLastSaved(0); //pretend that the session has never been saved before to get a full save
session.getSessionData().setDirty(true); //ensure we will try to write the session out
doPutIfAbsent(newId, session); //put the new id into our map
doDelete (oldId); //take old out of map
if (_sessionStore != null)
{
_sessionStore.delete(oldId); //delete the session data with the old id
_sessionStore.store(newId, session.getSessionData()); //save the session data with the new id
}
LOG.info("Session id {} swapped for new id {}", oldId, newId);
return session;
}
}
public void setPassivateOnComplete (boolean passivateOnComplete)
{
_passivateOnComplete = passivateOnComplete;
}
public boolean isPassivateOnComplete ()
{
return _passivateOnComplete;
}
/**
* @see org.eclipse.jetty.server.session.SessionCache#newSession(javax.servlet.http.HttpServletRequest, java.lang.String, long, long)
*/
@Override
public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs)
{
Session session = newSession(request, _sessionStore.newSessionData(id, time, time, time, maxInactiveMs));
session.setSessionHandler(_handler);
return session;
}
}

View File

@ -1,149 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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.util.Set;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
/**
* AbstractSessionDataStore
*
*
*/
public abstract class AbstractSessionDataStore extends AbstractLifeCycle implements SessionDataStore
{
protected SessionContext _context; //context associated with this session data store
protected int _gracePeriodSec = 60 * 60; //default of 1hr
protected long _lastExpiryCheckTime = 0; //last time in ms that getExpired was called
/**
* Store the session data persistently.
*
* @param id identity of session to store
* @param data info of the session
* @param lastSaveTime time of previous save or 0 if never saved
* @throws Exception if unable to store data
*/
public abstract void doStore(String id, SessionData data, long lastSaveTime) throws Exception;
/**
* Implemented by subclasses to resolve which sessions this node
* should attempt to expire.
*
* @param candidates the ids of sessions the SessionStore thinks has expired
* @return the reconciled set of session ids that this node should attempt to expire
*/
public abstract Set<String> doGetExpired (Set<String> candidates);
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#initialize(org.eclipse.jetty.server.session.SessionContext)
*/
public void initialize (SessionContext context)
{
if (isStarted())
throw new IllegalStateException("Context set after SessionDataStore started");
_context = context;
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
*/
@Override
public void store(String id, SessionData data) throws Exception
{
long lastSave = data.getLastSaved();
//set the last saved time to now
data.setLastSaved(System.currentTimeMillis());
try
{
//call the specific store method, passing in previous save time
doStore(id, data, lastSave);
data.setDirty(false); //only undo the dirty setting if we saved it
}
catch (Exception e)
{
//reset last save time if save failed
data.setLastSaved(lastSave);
throw e;
}
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(java.util.Set)
*/
@Override
public Set<String> getExpired(Set<String> candidates)
{
try
{
return doGetExpired (candidates);
}
finally
{
_lastExpiryCheckTime = System.currentTimeMillis();
}
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#newSessionData(java.lang.String, long, long, long, long)
*/
@Override
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
}
protected void checkStarted () throws IllegalStateException
{
if (isStarted())
throw new IllegalStateException("Already started");
}
@Override
protected void doStart() throws Exception
{
if (_context == null)
throw new IllegalStateException ("No SessionContext");
super.doStart();
}
public int getGracePeriodSec()
{
return _gracePeriodSec;
}
public void setGracePeriodSec(int sec)
{
_gracePeriodSec = sec;
}
}

View File

@ -19,621 +19,131 @@
package org.eclipse.jetty.server.session;
import java.util.Collections;
import java.util.Set;
import javax.servlet.http.HttpServletRequest;
import org.eclipse.jetty.util.StringUtil;
import org.eclipse.jetty.util.component.AbstractLifeCycle;
import org.eclipse.jetty.util.log.Log;
import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.thread.Locker.Lock;
/**
* AbstractSessionStore
*
* Basic behaviour for maintaining an in-memory store of Session objects and
* making sure that any backing SessionDataStore is kept in sync.
*
*/
public abstract class AbstractSessionStore extends AbstractLifeCycle implements SessionStore
{
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
protected SessionDataStore _sessionDataStore;
protected final SessionManager _manager;
protected SessionContext _context;
protected int _idlePassivationTimeoutSec;
private boolean _passivateOnComplete;
protected SessionContext _context; //context associated with this session data store
protected int _gracePeriodSec = 60 * 60; //default of 1hr
protected long _lastExpiryCheckTime = 0; //last time in ms that getExpired was called
/**
* Create a new Session object from pre-existing session data
* @param data the session data
* @return a new Session object
*/
public abstract Session newSession (SessionData data);
/**
* Create a new Session for a request.
* Store the session data persistently.
*
* @param request the request
* @param data the session data
* @return the new session
* @param id identity of session to store
* @param data info of the session
* @param lastSaveTime time of previous save or 0 if never saved
* @throws Exception if unable to store data
*/
public abstract Session newSession (HttpServletRequest request, SessionData data);
public abstract void doStore(String id, SessionData data, long lastSaveTime) throws Exception;
/**
* Get the session matching the key
* @param id session id
* @return the Session object matching the id
*/
public abstract Session doGet(String id);
/**
* Put the session into the map if it wasn't already there
* Implemented by subclasses to resolve which sessions this node
* should attempt to expire.
*
* @param id the identity of the session
* @param session the session object
* @return null if the session wasn't already in the map, or the existing entry otherwise
* @param candidates the ids of sessions the SessionStore thinks has expired
* @return the reconciled set of session ids that this node should attempt to expire
*/
public abstract Session doPutIfAbsent (String id, Session session);
/**
* Replace the mapping from id to oldValue with newValue
* @param id the id
* @param oldValue the old value
* @param newValue the new value
* @return true if replacement was done
*/
public abstract boolean doReplace (String id, Session oldValue, Session newValue);
public abstract Set<String> doGetExpired (Set<String> candidates);
/**
* Remove the session with this identity from the store
* @param id the id
* @return true if removed false otherwise
*/
public abstract Session doDelete (String id);
/**
* PlaceHolder
*/
protected class PlaceHolderSession extends Session
{
/**
* @param data the session data
*/
public PlaceHolderSession(SessionData data)
{
super(data);
}
}
/**
*
*/
public AbstractSessionStore (SessionManager manager)
{
_manager = manager;
}
/**
* @return the SessionManger
*/
public SessionManager getSessionManager()
{
return _manager;
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#initialize(org.eclipse.jetty.server.session.SessionContext)
*/
public void initialize (SessionContext context)
{
if (isStarted())
throw new IllegalStateException("Context set after session store started");
throw new IllegalStateException("Context set after SessionDataStore started");
_context = context;
}
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStart()
* @see org.eclipse.jetty.server.session.SessionStore#store(java.lang.String, org.eclipse.jetty.server.session.SessionData)
*/
@Override
public void store(String id, SessionData data) throws Exception
{
long lastSave = data.getLastSaved();
//set the last saved time to now
data.setLastSaved(System.currentTimeMillis());
try
{
//call the specific store method, passing in previous save time
doStore(id, data, lastSave);
data.setDirty(false); //only undo the dirty setting if we saved it
}
catch (Exception e)
{
//reset last save time if save failed
data.setLastSaved(lastSave);
throw e;
}
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(java.util.Set)
*/
@Override
public Set<String> getExpired(Set<String> candidates)
{
try
{
return doGetExpired (candidates);
}
finally
{
_lastExpiryCheckTime = System.currentTimeMillis();
}
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#newSessionData(java.lang.String, long, long, long, long)
*/
@Override
public SessionData newSessionData(String id, long created, long accessed, long lastAccessed, long maxInactiveMs)
{
return new SessionData(id, _context.getCanonicalContextPath(), _context.getVhost(), created, accessed, lastAccessed, maxInactiveMs);
}
protected void checkStarted () throws IllegalStateException
{
if (isStarted())
throw new IllegalStateException("Already started");
}
@Override
protected void doStart() throws Exception
{
if (_sessionDataStore == null)
throw new IllegalStateException ("No session data store configured");
if (_manager == null)
throw new IllegalStateException ("No session manager");
if (_context == null)
throw new IllegalStateException ("No ContextId");
_sessionDataStore.initialize(_context);
_sessionDataStore.start();
throw new IllegalStateException ("No SessionContext");
super.doStart();
}
/**
* @see org.eclipse.jetty.util.component.AbstractLifeCycle#doStop()
*/
@Override
protected void doStop() throws Exception
public int getGracePeriodSec()
{
_sessionDataStore.stop();
super.doStop();
return _gracePeriodSec;
}
/**
* @return the SessionDataStore or null if there isn't one
*/
public SessionDataStore getSessionDataStore()
public void setGracePeriodSec(int sec)
{
return _sessionDataStore;
_gracePeriodSec = sec;
}
/**
* @param sessionDataStore the session datastore
*/
public void setSessionDataStore(SessionDataStore sessionDataStore)
{
_sessionDataStore = sessionDataStore;
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#getIdlePassivationTimeoutSec()
*/
public int getIdlePassivationTimeoutSec()
{
return _idlePassivationTimeoutSec;
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#setIdlePassivationTimeoutSec(int)
*/
public void setIdlePassivationTimeoutSec(int idleTimeoutSec)
{
_idlePassivationTimeoutSec = idleTimeoutSec;
}
/**
* Get a session object.
*
* If the session object is not in this session store, try getting
* the data for it from a SessionDataStore associated with the
* session manager.
*
* @see org.eclipse.jetty.server.session.SessionStore#get(java.lang.String)
*/
@Override
public Session get(String id) throws Exception
{
Session session = null;
Exception ex = null;
while (true)
{
session = doGet(id);
if (_sessionDataStore == null)
break; //can't load any session data so just return null or the session object
if (session == null)
{
if (LOG.isDebugEnabled())
LOG.debug("Session not found locally, attempting to load");
//didn't get a session, try and create one and put in a placeholder for it
PlaceHolderSession phs = new PlaceHolderSession (new SessionData(id, null, null,0,0,0,0));
Lock phsLock = phs.lock();
Session s = doPutIfAbsent(id, phs);
if (s == null)
{
//My placeholder won, go ahead and load the full session data
try
{
session = loadSession(id);
if (session == null)
{
//session does not exist, remove the placeholder
doDelete(id);
phsLock.close();
break;
}
try (Lock lock = session.lock())
{
//swap it in instead of the placeholder
boolean success = doReplace(id, phs, session);
if (!success)
{
//something has gone wrong, it should have been our placeholder
doDelete(id);
session = null;
LOG.warn("Replacement of placeholder for session {} failed", id);
phsLock.close();
break;
}
else
{
//successfully swapped in the session
session.setTimeout (); //TODO start the session timer
phsLock.close();
break;
}
}
}
catch (Exception e)
{
ex = e; //remember a problem happened loading the session
doDelete(id); //remove the placeholder
phsLock.close();
session = null;
break;
}
}
else
{
//my placeholder didn't win, check the session returned
phsLock.close();
try (Lock lock = s.lock())
{
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
if (s.isPassivated() || s instanceof PlaceHolderSession)
{
session = null;
continue;
}
session = s;
break;
}
}
}
else
{
//check the session returned
try (Lock lock = session.lock())
{
//is it a placeholder? or is it passivated? In both cases, chuck it away and start again
if (session.isPassivated() || session instanceof PlaceHolderSession)
{
session = null;
continue;
}
//got the session
break;
}
}
}
if (ex != null)
throw ex;
return session;
}
/**
* Load the info for the session from the session data store
*
* @param id the id
* @return a Session object filled with data or null if the session doesn't exist
* @throws Exception
*/
private Session loadSession (String id)
throws Exception
{
SessionData data = null;
Session session = null;
if (_sessionDataStore == null)
return null; //can't load it
try
{
data =_sessionDataStore.load(id);
if (data == null) //session doesn't exist
return null;
session = newSession(data);
session.setSessionManager(_manager);
return session;
}
catch (UnreadableSessionDataException e)
{
//can't load the session, delete it
_sessionDataStore.delete(id);
throw e;
}
}
/**
* Put the Session object back into the session store.
*
* This should be called by Session.complete when a request exists the session.
*
* If the session manager supports a session data store, write the
* session data through to the session data store.
*
* @see org.eclipse.jetty.server.session.SessionStore#put(java.lang.String, org.eclipse.jetty.server.session.Session)
*/
@Override
public void put(String id, Session session) throws Exception
{
if (id == null || session == null)
throw new IllegalArgumentException ("Put key="+id+" session="+(session==null?"null":session.getId()));
//if the session is new or data has changed write it to any backing store
try (Lock lock = session.lock())
{
session.setSessionManager(_manager);
if (session.isPassivated())
throw new IllegalStateException ("Session "+id+" is passivated and cannot be saved");
if (!session.isValid())
return;
if (_sessionDataStore == null)
{
doPutIfAbsent(id, session); //ensure it is in our map
return;
}
if ((session.getRequests() <= 0))
{
//only save if all requests have finished
if (!_sessionDataStore.isPassivating())
{
//if our backing datastore isn't the passivating kind, just save the session
_sessionDataStore.store(id, session.getSessionData());
}
else
{
//backing store supports passivation
session.willPassivate();
_sessionDataStore.store(id, session.getSessionData());
session.setPassivated();
if (isPassivateOnComplete())
{
//throw out the passivated session object from the map
doDelete(id);
}
else
{
//reactivate the session
session.setActive();
session.didActivate();
}
}
}
doPutIfAbsent(id,session); //ensure it is in our map
}
}
/**
* Check to see if a session corresponding to the id exists.
*
* This method will first check with the object store. If it
* doesn't exist in the object store (might be passivated etc),
* it will check with the data store.
* @throws Exception
*
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception
{
//try the object store first
Session s = doGet(id);
if (s != null)
{
try (Lock lock = s.lock())
{
//wait for the lock and check the validity of the session
return s.isValid();
}
}
//not there, so find out if session data exists for it
return _sessionDataStore.exists (id);
}
/**
* Remove a session object from this store and from any backing store.
*
*
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
*/
@Override
public Session delete(String id) throws Exception
{
//get the session, if its not in memory, this will load it
Session session = get(id);
//Always delete it from the backing data store
if (_sessionDataStore != null)
{
boolean dsdel = _sessionDataStore.delete(id);
if (LOG.isDebugEnabled()) LOG.debug("Session {} deleted in db {}",id, dsdel);
}
//delete it from the session object store
if (session != null)
session.stopTimeout();
return doDelete(id);
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#checkExpiration(Set)
*/
@Override
public Set<String> checkExpiration(Set<String> candidates)
{
if (!isStarted())
return Collections.emptySet();
if (LOG.isDebugEnabled())
LOG.debug("SessionStore checking expiration on {}", candidates);
return _sessionDataStore.getExpired(candidates);
}
/**
* If the SessionDataStore supports passivation,
* write the session to the backing data store.
*
* @param id identity of session to passivate
*/
@Override
public void passivateIdleSession(String id)
{
if (!isStarted())
return;
if (_sessionDataStore == null || !_sessionDataStore.isPassivating())
return; //no data store to passivate or it doesn't passivate
//get the session locally
Session s = doGet(id);
if (s == null)
{
LOG.warn("Session {} not in this session store", s);
return;
}
//lock the session during passivation
try (Lock lock = s.lock())
{
//check the session is still idle and that it doesn't have requests using it
if (s.isValid() && s.isIdleLongerThan(_idlePassivationTimeoutSec) && s.isActive() && (s.getRequests() <= 0))
{
//TODO - do we need to check that the session exists in the session data store
//before we passivate it? If it doesn't exist, we can assume another node
//invalidated it. If the session was new, it shouldn't have been idle passivated.
try
{
if (LOG.isDebugEnabled())
LOG.debug("Passivating idle session {}", id);
s.willPassivate();
_sessionDataStore.store(id, s.getSessionData());
s.setPassivated();
s.stopTimeout();
doDelete(id); //Take the session object of this session store
}
catch (Exception e)
{
LOG.warn("Passivation of idle session {} failed", id, e);
s.setPassivated(); //set it as passivated so it can't be used
doDelete(id); //detach it
}
}
}
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#renewSessionId(java.lang.String, java.lang.String)
*/
public Session renewSessionId (String oldId, String newId)
throws Exception
{
if (StringUtil.isBlank(oldId))
throw new IllegalArgumentException ("Old session id is null");
if (StringUtil.isBlank(newId))
throw new IllegalArgumentException ("New session id is null");
Session session = get(oldId);
if (session == null)
return null;
try (Lock lock = session.lock())
{
session.checkValidForWrite(); //can't change id on invalid session
session.getSessionData().setId(newId);
session.getSessionData().setLastSaved(0); //pretend that the session has never been saved before to get a full save
session.getSessionData().setDirty(true); //ensure we will try to write the session out
doPutIfAbsent(newId, session); //put the new id into our map
doDelete (oldId); //take old out of map
if (_sessionDataStore != null)
{
_sessionDataStore.delete(oldId); //delete the session data with the old id
_sessionDataStore.store(newId, session.getSessionData()); //save the session data with the new id
}
LOG.info("Session id {} swapped for new id {}", oldId, newId);
return session;
}
}
public void setPassivateOnComplete (boolean passivateOnComplete)
{
_passivateOnComplete = passivateOnComplete;
}
public boolean isPassivateOnComplete ()
{
return _passivateOnComplete;
}
/**
* @see org.eclipse.jetty.server.session.SessionStore#newSession(javax.servlet.http.HttpServletRequest, java.lang.String, long, long)
*/
@Override
public Session newSession(HttpServletRequest request, String id, long time, long maxInactiveMs)
{
Session session = newSession(request, _sessionDataStore.newSessionData(id, time, time, time, maxInactiveMs));
session.setSessionManager(_manager);
return session;
}
}

View File

@ -20,20 +20,33 @@
package org.eclipse.jetty.server.session;
/**
* AlwaysStale
* AbstractSessionStoreFactory
*
*
*/
public class AlwaysStaleStrategy implements StalenessStrategy
public abstract class AbstractSessionStoreFactory implements SessionStoreFactory
{
/**
* @see org.eclipse.jetty.server.session.StalenessStrategy#isStale(org.eclipse.jetty.server.session.Session)
int _gracePeriodSec;
/**
* @return the gracePeriodSec
*/
@Override
public boolean isStale(Session session)
public int getGracePeriodSec()
{
return true;
return _gracePeriodSec;
}
/**
* @param gracePeriodSec the gracePeriodSec to set
*/
public void setGracePeriodSec(int gracePeriodSec)
{
_gracePeriodSec = gracePeriodSec;
}
}

View File

@ -32,7 +32,7 @@ import java.util.Set;
* can increase performance. The cache implementation can either be a local cache,
* a remote cache, or a clustered cache.
*/
public class CachingSessionDataStore extends AbstractSessionDataStore
public class CachingSessionDataStore extends AbstractSessionStore
{
public interface SessionDataCache
@ -45,17 +45,17 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
}
protected SessionDataStore _delegateDataStore;
protected SessionStore _delegateDataStore;
protected SessionDataCache _cache;
public void setSessionDataStore (SessionDataStore store)
public void setSessionDataStore (SessionStore store)
{
checkStarted();
_delegateDataStore = store;
}
public SessionDataStore getSessionDataStore()
public SessionStore getSessionDataStore()
{
return _delegateDataStore;
}
@ -74,7 +74,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
*/
@Override
public SessionData load(String id) throws Exception
@ -103,7 +103,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
*/
@Override
public boolean delete(String id) throws Exception
@ -116,7 +116,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
*/
@Override
public Set<String> doGetExpired(Set<String> candidates)
@ -127,14 +127,14 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
//write to the SessionDataStore first
if (_delegateDataStore instanceof AbstractSessionDataStore)
((AbstractSessionDataStore)_delegateDataStore).doStore(id, data, lastSaveTime);
if (_delegateDataStore instanceof AbstractSessionStore)
((AbstractSessionStore)_delegateDataStore).doStore(id, data, lastSaveTime);
//else??????
@ -159,7 +159,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
*/
@Override
public boolean isPassivating()
@ -168,7 +168,7 @@ public class CachingSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception

View File

@ -19,10 +19,7 @@
package org.eclipse.jetty.server.session;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import javax.servlet.http.HttpServletRequest;
@ -31,11 +28,11 @@ import org.eclipse.jetty.util.log.Logger;
import org.eclipse.jetty.util.statistic.CounterStatistic;
/**
* MemorySessionStore
* DefaultSessionCache
*
* A session store that keeps its sessions in memory in a hashmap
*/
public class MemorySessionStore extends AbstractSessionStore
public class DefaultSessionCache extends AbstractSessionCache
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
@ -73,7 +70,7 @@ public class MemorySessionStore extends AbstractSessionStore
public MemorySessionStore (SessionManager manager)
public DefaultSessionCache (SessionHandler manager)
{
super (manager);
}
@ -103,7 +100,7 @@ public class MemorySessionStore extends AbstractSessionStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doGet(java.lang.String)
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doGet(java.lang.String)
*/
@Override
public Session doGet(String id)
@ -118,7 +115,7 @@ public class MemorySessionStore extends AbstractSessionStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session)
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doPutIfAbsent(java.lang.String, org.eclipse.jetty.server.session.Session)
*/
@Override
public Session doPutIfAbsent(String id, Session session)
@ -132,7 +129,7 @@ public class MemorySessionStore extends AbstractSessionStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doDelete(java.lang.String)
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doDelete(java.lang.String)
*/
@Override
public Session doDelete(String id)
@ -158,14 +155,14 @@ public class MemorySessionStore extends AbstractSessionStore
for (Session session: _sessions.values())
{
//if we have a backing store and the session is dirty make sure it is written out
if (_sessionDataStore != null)
if (_sessionStore != null)
{
if (session.getSessionData().isDirty())
{
session.willPassivate();
try
{
_sessionDataStore.store(session.getId(), session.getSessionData());
_sessionStore.store(session.getId(), session.getSessionData());
}
catch (Exception e)
{
@ -193,7 +190,7 @@ public class MemorySessionStore extends AbstractSessionStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(javax.servlet.http.HttpServletRequest, org.eclipse.jetty.server.session.SessionData)
* @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(javax.servlet.http.HttpServletRequest, org.eclipse.jetty.server.session.SessionData)
*/
@Override
public Session newSession(HttpServletRequest request, SessionData data)
@ -206,7 +203,7 @@ public class MemorySessionStore extends AbstractSessionStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionStore#newSession(org.eclipse.jetty.server.session.SessionData)
* @see org.eclipse.jetty.server.session.AbstractSessionCache#newSession(org.eclipse.jetty.server.session.SessionData)
*/
@Override
public Session newSession(SessionData data)
@ -219,7 +216,7 @@ public class MemorySessionStore extends AbstractSessionStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doReplace(java.lang.String, org.eclipse.jetty.server.session.Session, org.eclipse.jetty.server.session.Session)
* @see org.eclipse.jetty.server.session.AbstractSessionCache#doReplace(java.lang.String, org.eclipse.jetty.server.session.Session, org.eclipse.jetty.server.session.Session)
*/
@Override
public boolean doReplace(String id, Session oldValue, Session newValue)

View File

@ -0,0 +1,80 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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;
/**
* MemorySessionStoreFactory
*
*
*/
public class DefaultSessionCacheFactory implements SessionCacheFactory
{
int _idlePassivationTimeoutSec;
boolean _passivateOnComplete;
/**
* @return the passivateOnComplete
*/
public boolean isPassivateOnComplete()
{
return _passivateOnComplete;
}
/**
* @param passivateOnComplete the passivateOnComplete to set
*/
public void setPassivateOnComplete(boolean passivateOnComplete)
{
_passivateOnComplete = passivateOnComplete;
}
/**
* @return the idlePassivationTimeoutSec
*/
public int getIdlePassivationTimeoutSec()
{
return _idlePassivationTimeoutSec;
}
/**
* @param idlePassivationTimeoutSec the idlePassivationTimeoutSec to set
*/
public void setIdlePassivationTimeoutSec(int idlePassivationTimeoutSec)
{
_idlePassivationTimeoutSec = idlePassivationTimeoutSec;
}
/**
* @see org.eclipse.jetty.server.session.SessionCacheFactory#getSessionStore(org.eclipse.jetty.server.session.SessionHandler)
*/
@Override
public SessionCache getSessionCache (SessionHandler handler)
{
DefaultSessionCache cache = new DefaultSessionCache(handler);
cache.setIdlePassivationTimeoutSec(_idlePassivationTimeoutSec);
cache.setPassivateOnComplete(_passivateOnComplete);
return cache;
}
}

View File

@ -58,7 +58,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
protected String _workerAttr;
protected long _reseed=100000L;
protected Server _server;
protected HouseKeeper _inspector;
protected HouseKeeper _houseKeeper;
/* ------------------------------------------------------------ */
@ -106,10 +106,10 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
/**
* @param inspector inspector of sessions
*/
public void setSessionInspector (HouseKeeper inspector)
public void setSessionHouseKeeper (HouseKeeper houseKeeper)
{
_inspector = inspector;
_inspector.setSessionIdManager(this);
_houseKeeper = houseKeeper;
_houseKeeper.setSessionIdManager(this);
}
@ -291,7 +291,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
try
{
for (SessionManager manager:getSessionManagers())
for (SessionHandler manager:getSessionHandlers())
{
if (manager.isIdInUse(id))
{
@ -327,14 +327,14 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
initRandom();
_workerAttr=(_workerName!=null && _workerName.startsWith("$"))?_workerName.substring(1):null;
if (_inspector == null)
if (_houseKeeper == null)
{
LOG.warn("No SessionScavenger set, using defaults");
_inspector = new HouseKeeper();
_inspector.setSessionIdManager(this);
_houseKeeper = new HouseKeeper();
_houseKeeper.setSessionIdManager(this);
}
_inspector.start();
_houseKeeper.start();
}
/* ------------------------------------------------------------ */
@ -344,7 +344,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
@Override
protected void doStop() throws Exception
{
_inspector.stop();
_houseKeeper.stop();
}
/* ------------------------------------------------------------ */
@ -424,7 +424,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
if (LOG.isDebugEnabled())
LOG.debug("Expiring {}",id);
for (SessionManager manager:getSessionManagers())
for (SessionHandler manager:getSessionHandlers())
{
manager.invalidate(id);
}
@ -435,7 +435,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
{
//tell all contexts that may have a session object with this id to
//get rid of them
for (SessionManager manager:getSessionManagers())
for (SessionHandler manager:getSessionHandlers())
{
manager.invalidate(id);
}
@ -457,7 +457,7 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
//TODO how to handle request for old id whilst id change is happening?
//tell all contexts to update the id
for (SessionManager manager:getSessionManagers())
for (SessionHandler manager:getSessionHandlers())
{
manager.renewSessionId(oldClusterId, oldNodeId, newClusterId, getExtendedId(newClusterId, request));
}
@ -470,9 +470,9 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
*
* @return all session managers
*/
public Set<SessionManager> getSessionManagers()
public Set<SessionHandler> getSessionHandlers()
{
Set<SessionManager> managers = new HashSet<>();
Set<SessionHandler> handlers = new HashSet<>();
Handler[] contexts = _server.getChildHandlersByClass(ContextHandler.class);
for (int i=0; contexts!=null && i<contexts.length; i++)
@ -480,12 +480,9 @@ public class DefaultSessionIdManager extends AbstractLifeCycle implements Sessio
SessionHandler sessionHandler = ((ContextHandler)contexts[i]).getChildHandlerByClass(SessionHandler.class);
if (sessionHandler != null)
{
SessionManager manager = (SessionManager)sessionHandler.getSessionManager();
if (manager != null)
managers.add(manager);
handlers.add(sessionHandler);
}
}
return managers;
return handlers;
}
}

View File

@ -46,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger;
*
* A file-based store of session data.
*/
public class FileSessionDataStore extends AbstractSessionDataStore
public class FileSessionDataStore extends AbstractSessionStore
{
private final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
private File _storeDir;
@ -92,7 +92,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
*/
@Override
public boolean delete(String id) throws Exception
@ -112,7 +112,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
*/
@Override
public Set<String> doGetExpired(final Set<String> candidates)
@ -166,7 +166,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
*/
@Override
public SessionData load(String id) throws Exception
@ -220,7 +220,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
@ -262,7 +262,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
*/
@Override
public boolean isPassivating()
@ -274,7 +274,7 @@ public class FileSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception

View File

@ -1,64 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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;
/**
* FileHashSessionManager
*
* Session manager that stores its sessions in files on disk
*
*/
public class FileSessionManager extends SessionManager
{
protected FileSessionDataStore _sessionDataStore;
/**
*
*/
public FileSessionManager ()
{
setSessionStore(new MemorySessionStore(this));
_sessionDataStore = new FileSessionDataStore();
}
@Override
public void doStart() throws Exception
{
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
super.doStart();
}
@Override
public void doStop() throws Exception
{
super.doStop();
}
/**
* Get the SessionDataStore to configure it
* @return the session datastore
*/
public FileSessionDataStore getSessionDataStore()
{
return _sessionDataStore;
}
}

View File

@ -0,0 +1,84 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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;
/**
* FileSessionStoreFactory
*
*
*/
public class FileSessionStoreFactory extends AbstractSessionStoreFactory
{
boolean _deleteUnrestorableFiles;
File _storeDir;
/**
* @return the deleteUnrestorableFiles
*/
public boolean isDeleteUnrestorableFiles()
{
return _deleteUnrestorableFiles;
}
/**
* @param deleteUnrestorableFiles the deleteUnrestorableFiles to set
*/
public void setDeleteUnrestorableFiles(boolean deleteUnrestorableFiles)
{
_deleteUnrestorableFiles = deleteUnrestorableFiles;
}
/**
* @return the storeDir
*/
public File getStoreDir()
{
return _storeDir;
}
/**
* @param storeDir the storeDir to set
*/
public void setStoreDir(File storeDir)
{
_storeDir = storeDir;
}
/**
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler)
*/
@Override
public SessionStore getSessionStore(SessionHandler handler)
{
FileSessionDataStore fsds = new FileSessionDataStore();
fsds.setDeleteUnrestorableFiles(isDeleteUnrestorableFiles());
fsds.setStoreDir(getStoreDir());
fsds.setGracePeriodSec(getGracePeriodSec());
return fsds;
}
}

View File

@ -1,55 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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;
/**
* HashSessionManager
*
* In memory-only session manager.
*
*/
public class HashSessionManager extends SessionManager
{
protected NullSessionDataStore _sessionDataStore = new NullSessionDataStore();
/**
*
*/
public HashSessionManager ()
{
setSessionStore(new MemorySessionStore(this));
}
@Override
public void doStart() throws Exception
{
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
super.doStart();
}
@Override
public void doStop() throws Exception
{
super.doStop();
}
}

View File

@ -155,7 +155,7 @@ public class HouseKeeper extends AbstractLifeCycle
_intervalMs += tenPercent;
if (LOG.isDebugEnabled())
LOG.debug("Inspecting every "+_intervalMs+" ms");
LOG.debug("Scavenging every "+_intervalMs+" ms");
synchronized (this)
{
@ -173,7 +173,7 @@ public class HouseKeeper extends AbstractLifeCycle
/**
* Get the period between inspection cycles.
* Get the period between scavenge cycles.
*
* @return the interval (in seconds)
*/
@ -194,10 +194,10 @@ public class HouseKeeper extends AbstractLifeCycle
return;
if (LOG.isDebugEnabled())
LOG.debug("Inspecting sessions");
LOG.debug("Scavenging sessions");
//find the session managers
for (SessionManager manager:_sessionIdManager.getSessionManagers())
for (SessionHandler manager:_sessionIdManager.getSessionHandlers())
{
if (manager != null)
{

View File

@ -46,7 +46,7 @@ import org.eclipse.jetty.util.log.Logger;
*
* Session data stored in database
*/
public class JDBCSessionDataStore extends AbstractSessionDataStore
public class JDBCSessionDataStore extends AbstractSessionStore
{
final static Logger LOG = Log.getLogger("org.eclipse.jetty.server.session");
@ -662,7 +662,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#load(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#load(java.lang.String)
*/
@Override
public SessionData load(String id) throws Exception
@ -758,7 +758,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#delete(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#delete(java.lang.String)
*/
@Override
public boolean delete(String id) throws Exception
@ -779,7 +779,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(String, SessionData, long)
* @see org.eclipse.jetty.server.session.AbstractSessionStore#doStore(String, SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
@ -884,7 +884,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#getExpired(Set)
* @see org.eclipse.jetty.server.session.SessionStore#getExpired(Set)
*/
@Override
public Set<String> doGetExpired(Set<String> candidates)
@ -1083,7 +1083,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
* @see org.eclipse.jetty.server.session.SessionStore#isPassivating()
*/
@Override
public boolean isPassivating()
@ -1096,7 +1096,7 @@ public class JDBCSessionDataStore extends AbstractSessionDataStore
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
* @see org.eclipse.jetty.server.session.SessionStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id)

View File

@ -1,64 +0,0 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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;
/**
* JDBCSessionManager
*
*/
public class JDBCSessionManager extends SessionManager
{
protected JDBCSessionDataStore _sessionDataStore;
public JDBCSessionManager()
{
setSessionStore(new MemorySessionStore(this));
_sessionDataStore = new JDBCSessionDataStore();
}
@Override
public void doStart() throws Exception
{
((AbstractSessionStore)_sessionStore).setSessionDataStore(_sessionDataStore);
super.doStart();
}
@Override
public void doStop() throws Exception
{
super.doStop();
}
/**
* Get the SessionDataStore to configure it
* @return the session data store
*/
public JDBCSessionDataStore getSessionDataStore ()
{
return _sessionDataStore;
}
}

View File

@ -0,0 +1,68 @@
//
// ========================================================================
// Copyright (c) 1995-2016 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;
/**
* JDBCSessionStoreFactory
*
*
*/
public class JDBCSessionStoreFactory extends AbstractSessionStoreFactory
{
DatabaseAdaptor _adaptor;
JDBCSessionDataStore.SessionTableSchema _schema;
boolean _deleteUnloadableSessions;
int _loadAttempts;
/**
* @see org.eclipse.jetty.server.session.SessionStoreFactory#getSessionDataStore(org.eclipse.jetty.server.session.SessionHandler)
*/
@Override
public SessionStore getSessionStore(SessionHandler handler)
{
JDBCSessionDataStore ds = new JDBCSessionDataStore();
ds.setDatabaseAdaptor(_adaptor);
ds.setSessionTableSchema(_schema);
ds.setDeleteUnloadableSessions(_deleteUnloadableSessions);
ds.setGracePeriodSec(_gracePeriodSec);
ds.setLoadAttempts(_loadAttempts);
return ds;
}
/**
* @param adaptor
*/
public void setDatabaseAdaptor (DatabaseAdaptor adaptor)
{
_adaptor = adaptor;
}
/**
* @param schema
*/
public void setSessionTableSchema (JDBCSessionDataStore.SessionTableSchema schema)
{
_schema = schema;
}
}

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