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

This commit is contained in:
Jan Bartel 2016-06-17 13:36:56 +10:00
commit 1e7b866d6f
30 changed files with 698 additions and 39 deletions

View File

@ -3,10 +3,10 @@ Memcache cache for SessionData
[depends]
session-store
slf4j-api
[files]
maven://com.googlecode.xmemcached/xmemcached/2.0.0|lib/xmemcached/xmemcached-2.0.0.jar
maven://org.slf4j/slf4j-api/1.6.6|lib/xmemcached/slf4j-api-1.6.6.jar
[lib]
lib/jetty-memcached-sessions-${jetty.version}.jar

View File

@ -5,6 +5,7 @@ Enables the core Jetty server on the classpath.
jvm
ext
resources
logging
[lib]
lib/servlet-api-3.1.jar

View File

@ -81,9 +81,9 @@ public class CachingSessionDataStore extends ContainerLifeCycle implements Sessi
/**
* @return the cache
* @return the fronting cache for session data
*/
public SessionDataMap getCache ()
public SessionDataMap getSessionDataMap ()
{
return _cache;
}

View File

@ -28,10 +28,10 @@ import java.util.List;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import org.eclipse.jetty.start.builders.StartDirBuilder;
import org.eclipse.jetty.start.builders.StartIniBuilder;
import org.eclipse.jetty.start.fileinits.BaseHomeFileInitializer;
import org.eclipse.jetty.start.fileinits.MavenLocalRepoFileInitializer;
import org.eclipse.jetty.start.fileinits.TestFileInitializer;
import org.eclipse.jetty.start.fileinits.UriFileInitializer;
@ -71,6 +71,9 @@ public class BaseBuilder
// Establish FileInitializers
if (args.isTestingModeEnabled())
{
// Copy from basehome
fileInitializers.add(new BaseHomeFileInitializer(baseHome));
// No downloads performed
fileInitializers.add(new TestFileInitializer());
}
@ -90,6 +93,9 @@ public class BaseBuilder
fileInitializers.add(new MavenLocalRepoFileInitializer(baseHome));
}
// Copy from basehome
fileInitializers.add(new BaseHomeFileInitializer(baseHome));
// Normal URL downloads
fileInitializers.add(new UriFileInitializer(baseHome));
}
@ -215,14 +221,12 @@ public class BaseBuilder
*/
private boolean processFileResource(FileArg arg, Path file) throws IOException
{
// now on copy/download paths (be safe above all else)
if (!file.startsWith(baseHome.getBasePath()))
throw new IOException("For security reasons, Jetty start is unable to process maven file resource not in ${jetty.base} - " + file);
if (startArgs.isDownload() && (arg.uri != null))
{
// now on copy/download paths (be safe above all else)
if (!file.startsWith(baseHome.getBasePath()))
{
throw new IOException("For security reasons, Jetty start is unable to process maven file resource not in ${jetty.base} - " + file);
}
// make the directories in ${jetty.base} that we need
boolean modified = FS.ensureDirectoryExists(file.getParent());
@ -238,7 +242,9 @@ public class BaseBuilder
}
}
return false;
System.err.println("Failed to initialize: "+arg.uri+"|"+arg.location);
return modified;
}
else
{

View File

@ -44,10 +44,11 @@ public class FileArg
final String LN = System.lineSeparator();
err.append("Unrecognized [file] argument: ").append(uriLocation);
err.append(LN).append("Valid Syntaxes: ");
err.append(LN).append(" <relative-path> - eg: resources/");
err.append(LN).append(" or <absolute-path> - eg: /var/run/jetty.pid");
err.append(LN).append(" or <uri>|<relative-path> - eg: http://machine/my.conf|resources/my.conf");
err.append(LN).append(" or <uri>|<absolute-path> - eg: http://machine/glob.dat|/opt/run/glob.dat");
err.append(LN).append(" <relative-path> - eg: resources/");
err.append(LN).append(" or <absolute-path> - eg: /var/run/jetty.pid");
err.append(LN).append(" or <uri>|<rel-path> - eg: http://machine/my.conf|resources/my.conf");
err.append(LN).append(" or <uri>|<abs-path> - eg: http://machine/glob.dat|/opt/run/glob.dat");
err.append(LN).append("Known uri schemes: http, maven, home");
throw new IllegalArgumentException(err.toString());
}
if (parts.length == 2)

View File

@ -402,16 +402,16 @@ public class Module
public String toString()
{
StringBuilder str = new StringBuilder();
str.append("Module[").append(getName());
str.append(getName()).append('{');
if (isEnabled())
{
str.append(",enabled");
str.append("enabled");
if (isTransitive())
str.append(",transitive");
}
if (isTransitive())
{
str.append(",transitive");
}
str.append(']');
else if (isTransitive())
str.append("transitive");
str.append('}');
return str.toString();
}

View File

@ -205,7 +205,15 @@ public class Modules implements Iterable<Module>
module.getDepends().forEach(add);
module.getOptional().forEach(add);
}
sort.sort(_modules);
try
{
sort.sort(_modules);
}
catch (IllegalStateException e)
{
System.err.println(sort.dump());
throw e;
}
}
public List<Module> getEnabled()
@ -251,7 +259,7 @@ public class Modules implements Iterable<Module>
}
}
else
throw new UsageException("Capability %s already enabled by %s for %s",name,p.getName(),module.getName());
throw new UsageException("%s provides %s, which is already provided by %s enabled in %s",module.getName(),name,p.getName(),p.getEnableSources());
}
});
}

View File

@ -0,0 +1,61 @@
//
// ========================================================================
// 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.start.fileinits;
import java.io.IOException;
import java.net.URI;
import java.nio.file.Files;
import java.nio.file.Path;
import org.eclipse.jetty.start.BaseHome;
import org.eclipse.jetty.start.FS;
import org.eclipse.jetty.start.FileInitializer;
/**
* Copy a file found in {@link BaseHome} from a URI of the form
* "basehome:some/path"
* {@link FileInitializer}
*/
public class BaseHomeFileInitializer implements FileInitializer
{
private final BaseHome _basehome;
public BaseHomeFileInitializer(BaseHome basehome)
{
_basehome=basehome;
}
@Override
public boolean init(URI uri, Path file, String fileRef) throws IOException
{
if (!"basehome".equalsIgnoreCase(uri.getScheme()) || uri.getSchemeSpecificPart().startsWith("/"))
return false;
Path source = _basehome.getPath(uri.getSchemeSpecificPart());
if (FS.exists(source) && !FS.exists(file))
{
FS.ensureDirectoryExists(file.getParent());
Files.copy(source,file);
return true;
}
return false;
}
}

View File

@ -1,2 +1,2 @@
EX|UsageException
EX|default already enabled by alternate
EX|default, which is already provided by alternate

View File

@ -0,0 +1,2 @@
DOWNLOAD|basehome:modules/demo/demo-config.xml|etc/demo-config.xml
EXISTS|etc/demo-config.xml

View File

@ -0,0 +1 @@
--add-to-startd=demo

View File

@ -0,0 +1,3 @@
[files]
basehome:modules/demo/demo-config.xml|etc/demo-config.xml

View File

@ -0,0 +1,8 @@
[description]
Enables Java util logging
[provide]
logging
[exec]
-Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.JavaUtilLog

View File

@ -0,0 +1,16 @@
[description]
Provides Apache Log4j 1.2 bridge to Log4j 2.
[depends]
log4j2-impl
[provides]
log4j-api
log4j-impl
[files]
maven://org.apache.logging.log4j/log4j-1.2-api/2.6.1|lib/log4j/log4j-1.2-api-2.6.1.jar
[lib]
lib/log4j/log4j-1.2-api-2.6.1.jar

View File

@ -0,0 +1,20 @@
[description]
Provides Apache Log4j 1.2
[depends]
resources
[provides]
log4j-api
log4j-impl
[files]
basehome:modules/log4j/log4j.properties|resources/log4j.properties
maven://log4j/log4j/1.2.17|lib/log4j/log4j-1.2.17.jar
[lib]
lib/log4j/log4j-1.2.17.jar
[license]
Log4j is released under the Apache 2.0 license.
http://www.apache.org/licenses/LICENSE-2.0.html

View File

@ -1,6 +1,4 @@
# This is not needed by Jetty - but it helps with many web apps.
log4j.rootLogger=INFO, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender

View File

@ -0,0 +1,14 @@
[description]
Provides Apache Log4j 2 API.
Requires a log4j 2 implementation module
Use slf4j-log4j module to link jetty logging
[files]
maven://org.apache.logging.log4j/log4j-api/2.6.1|lib/log4j/log4j-api-2.6.1.jar
[lib]
lib/log4j/log4j-api-2.6.1.jar
[license]
Log4j is released under the Apache 2.0 license.
http://www.apache.org/licenses/LICENSE-2.0.html

View File

@ -0,0 +1,16 @@
[description]
Provides Apache Log4j 2 Core.
[depends]
log4j2-api
[provides]
log4j2-impl
[files]
basehome:modules/log4j2/log4j2.properties|resources/log4j2.properties
maven://org.apache.logging.log4j/log4j-core/2.6.1|lib/log4j/log4j-core-2.6.1.jar
[lib]
lib/log4j/log4j-core-2.6.1.jar

View File

@ -0,0 +1,17 @@
[description]
Provides Apache Log4j 2 implementation that routes
logs into slf4j
[depends]
log4j2-api
slf4j-api
[provides]
log4j2-impl
[files]
maven://org.apache.logging.log4j/log4j-to-slf4j/2.6.1|lib/log4j/log4j-to-slf4j-2.6.1.jar
[lib]
lib/log4j/log4j-slf4j-to-2.6.1.jar

View File

@ -0,0 +1,11 @@
status = error
name = PropertiesConfig
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = STDOUT

View File

@ -13,16 +13,6 @@ lib/logging/**.jar
resources/
[ini-template]
## Logging Configuration
## Configure jetty logging for default internal behavior STDERR output
# -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.StdErrLog
## Configure jetty logging for slf4j
# -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog
## Configure jetty logging for java.util.logging
# -Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.JavaUtilLog
## Logging directory (relative to $jetty.base)
# jetty.logging.dir=logs

View File

@ -0,0 +1,36 @@
[description]
Provides SLF4J API. Requires a slf4j implementation (eg slf4j-simple)
otherwise a noop implementation is used.
[provides
logging
[files]
maven://org.slf4j/slf4j-api/1.7.21|lib/slf4j/slf4j-api-1.7.21.jar
[lib]
lib/slf4j/slf4j-api-1.7.21.jar
[license]
SLF4J is distributed under the MIT License.
Copyright (c) 2004-2013 QOS.ch
All rights reserved.
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,17 @@
[description]
Provides SLF4J simple logging
[depend]
slf4j-api
[provide]
slf4j-impl
[files]
maven://org.slf4j/slf4j-simple/1.7.21|lib/slf4j/slf4j-simple-1.7.21.jar
[lib]
lib/slf4j/slf4j-simple-1.7.21.jar
[exec]
-Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog

View File

@ -17,8 +17,10 @@
//
package org.eclipse.jetty.util;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
@ -28,6 +30,10 @@ import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import org.eclipse.jetty.util.component.ContainerLifeCycle;
import org.eclipse.jetty.util.component.Dumpable;
import org.eclipse.jetty.util.component.DumpableCollection;
/**
* Topological sort a list or array.
@ -45,7 +51,7 @@ import java.util.TreeSet;
*
* @param <T> The type to be sorted. It must be able to be added to a {@link HashSet}
*/
public class TopologicalSort<T>
public class TopologicalSort<T> implements Dumpable
{
private final Map<T,Set<T>> _dependencies = new HashMap<>();
@ -196,4 +202,17 @@ public class TopologicalSort<T>
{
return "TopologicalSort "+_dependencies;
}
@Override
public String dump()
{
return ContainerLifeCycle.dump(this);
}
@Override
public void dump(Appendable out, String indent) throws IOException
{
out.append(String.format("TopologicalSort@%x%n",hashCode()));
ContainerLifeCycle.dump(out, indent,_dependencies.entrySet());
}
}

View File

@ -183,7 +183,7 @@ public class Log
}
if (LOG!=null)
LOG.info(String.format("Logging initialized @%dms",Uptime.getUptime()));
LOG.info(String.format("Logging initialized @%dms to %s",Uptime.getUptime(),LOG.getClass().getName()));
}
}

View File

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

View File

@ -0,0 +1,89 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-parent</artifactId>
<version>9.4.0-SNAPSHOT</version>
</parent>
<artifactId>test-memcached-sessions</artifactId>
<name>Jetty Tests :: Sessions :: Memcached</name>
<url>http://www.eclipse.org/jetty</url>
<properties>
<bundle-symbolic-name>${project.groupId}.sessions.memcached</bundle-symbolic-name>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<!-- DO NOT DEPLOY (or Release) -->
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.tests</groupId>
<artifactId>test-sessions-common</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.memcached</groupId>
<artifactId>jetty-memcached-sessions</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.toolchain</groupId>
<artifactId>jetty-test-helper</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>memcached</id>
<activation>
<property>
<name>memcached.enabled</name>
<value>true</value>
</property>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skipTests>false</skipTests>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@ -0,0 +1,157 @@
//
// ========================================================================
// 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.memcached.sessions;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.memcached.sessions.MemcachedTestServer.MockDataStore;
import org.eclipse.jetty.server.session.AbstractTestServer;
import org.eclipse.jetty.server.session.CachingSessionDataStore;
import org.eclipse.jetty.server.session.SessionCache;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionDataMap;
import org.eclipse.jetty.server.session.SessionDataStore;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.junit.Test;
/**
* CachingSessionDataStoreTest
*
*
*/
public class CachingSessionDataStoreTest
{
public AbstractTestServer createServer (int port, int max, int scavenge,int evictionPolicy)
{
return new MemcachedTestServer(port, max, scavenge, evictionPolicy);
}
@Test
public void testSessionCRUD () throws Exception
{
String servletMapping = "/server";
int scavengePeriod = -1;
int maxInactivePeriod = -1;
//Make sure sessions are evicted on request exit so they will need to be reloaded via cache/persistent store
AbstractTestServer server = createServer(0, maxInactivePeriod, scavengePeriod, SessionCache.EVICT_ON_SESSION_EXIT);
ServletContextHandler context = server.addContext("/");
context.addServlet(TestServlet.class, servletMapping);
String contextPath = "";
try
{
server.start();
int port=server.getPort();
HttpClient client = new HttpClient();
client.start();
try
{
//
//Create a session
//
ContentResponse response = client.GET("http://localhost:" + port + contextPath + servletMapping + "?action=create");
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
String sessionCookie = response.getHeaders().get("Set-Cookie");
assertTrue(sessionCookie != null);
// Mangle the cookie, replacing Path with $Path, etc.
sessionCookie = sessionCookie.replaceFirst("(\\W)(P|p)ath=", "$1\\$Path=");
String id = AbstractTestServer.extractSessionId(sessionCookie);
//check that the memcache contains the session, and the session data store contains the session
CachingSessionDataStore ds = (CachingSessionDataStore)context.getSessionHandler().getSessionCache().getSessionDataStore();
assertNotNull(ds);
SessionDataStore persistentStore = ds.getSessionStore();
SessionDataMap dataMap = ds.getSessionDataMap();
//the backing persistent store contains the session
assertNotNull(persistentStore.load(id));
//the memcache cache contains the session
assertNotNull(dataMap.load(id));
//
//Update a session and check that is is NOT loaded via the persistent store
//
((MockDataStore)persistentStore).zeroLoadCount();
Request request = client.newRequest("http://localhost:" + port + contextPath + servletMapping + "?action=update");
request.header("Cookie", sessionCookie);
response = request.send();
assertEquals(HttpServletResponse.SC_OK,response.getStatus());
assertEquals(0, ((MockDataStore)persistentStore).getLoadCount());
//check it was updated in the persistent store
SessionData sd = persistentStore.load(id);
assertNotNull(sd);
assertEquals("bar", sd.getAttribute("foo"));
//check it was updated in the cache
sd = dataMap.load(id);
assertNotNull(sd);
assertEquals("bar", sd.getAttribute("foo"));
}
finally
{
client.stop();
}
}
finally
{
server.stop();
}
}
public static class TestServlet extends HttpServlet
{
String id;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
String action = request.getParameter("action");
if ("create".equals(action))
{
HttpSession session = request.getSession(true);
assertTrue(session.isNew());
id = session.getId();
return;
}
if ("update".equals(action))
{
HttpSession session = request.getSession(false);
assertNotNull(session);
session.setAttribute("foo", "bar");
return;
}
}
}
}

View File

@ -0,0 +1,167 @@
//
// ========================================================================
// 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.memcached.sessions;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.jetty.memcached.session.MemcachedSessionDataMap;
import org.eclipse.jetty.server.session.AbstractSessionDataStore;
import org.eclipse.jetty.server.session.AbstractTestServer;
import org.eclipse.jetty.server.session.CachingSessionDataStore;
import org.eclipse.jetty.server.session.DefaultSessionCache;
import org.eclipse.jetty.server.session.SessionData;
import org.eclipse.jetty.server.session.SessionHandler;
/**
* MemcachedTestServer
*
*
*/
public class MemcachedTestServer extends AbstractTestServer
{
public static class MockDataStore extends AbstractSessionDataStore
{
private Map<String,SessionData> _store = new HashMap<>();
private int _loadCount = 0;
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#isPassivating()
*/
@Override
public boolean isPassivating()
{
return true;
}
/**
* @see org.eclipse.jetty.server.session.SessionDataStore#exists(java.lang.String)
*/
@Override
public boolean exists(String id) throws Exception
{
return _store.get(id) != null;
}
/**
* @see org.eclipse.jetty.server.session.SessionDataMap#load(java.lang.String)
*/
@Override
public SessionData load(String id) throws Exception
{
_loadCount++;
return _store.get(id);
}
public void zeroLoadCount()
{
_loadCount = 0;
}
public int getLoadCount()
{
return _loadCount;
}
/**
* @see org.eclipse.jetty.server.session.SessionDataMap#delete(java.lang.String)
*/
@Override
public boolean delete(String id) throws Exception
{
return (_store.remove(id) != null);
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doStore(java.lang.String, org.eclipse.jetty.server.session.SessionData, long)
*/
@Override
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
{
_store.put(id, data);
}
/**
* @see org.eclipse.jetty.server.session.AbstractSessionDataStore#doGetExpired(java.util.Set)
*/
@Override
public Set<String> doGetExpired(Set<String> candidates)
{
Set<String> expiredIds = new HashSet<>();
long now = System.currentTimeMillis();
if (candidates != null)
{
for (String id:candidates)
{
SessionData sd = _store.get(id);
if (sd == null)
expiredIds.add(id);
else if (sd.isExpiredAt(now))
expiredIds.add(id);
}
}
for (String id:_store.keySet())
{
SessionData sd = _store.get(id);
if (sd.isExpiredAt(now))
expiredIds.add(id);
}
return expiredIds;
}
}
/**
* @param port
* @param maxInactivePeriod
* @param scavengePeriod
* @param sessionIdMgrConfig
*/
public MemcachedTestServer(int port, int maxInactivePeriod, int scavengePeriod, int evictionPolicy)
{
super(port, maxInactivePeriod, scavengePeriod, evictionPolicy);
}
/**
* @see org.eclipse.jetty.server.session.AbstractTestServer#newSessionHandler(org.eclipse.jetty.server.SessionManager)
*/
@Override
public SessionHandler newSessionHandler()
{
SessionHandler handler = new SessionHandler();
handler.setSessionIdManager(_sessionIdManager);
MockDataStore persistentStore = new MockDataStore();
MemcachedSessionDataMap sdm = new MemcachedSessionDataMap("localhost", "11211");
CachingSessionDataStore cachingStore = new CachingSessionDataStore(sdm, persistentStore);
DefaultSessionCache ss = new DefaultSessionCache(handler);
ss.setSessionDataStore(cachingStore);
handler.setSessionCache(ss);
return handler;
}
}