* Issue #6687 Update to infinispan 11.0.11 Signed-off-by: Jan Bartel <janb@webtide.com> Co-authored-by: Olivier Lamy <oliver.lamy@gmail.com>
This commit is contained in:
parent
f8df838755
commit
4aed1f3377
|
@ -722,22 +722,32 @@
|
|||
<artifactId>infinispan-embedded</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-embedded-query</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-remote</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>pom</type>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.wildfly.common</groupId>
|
||||
<artifactId>*</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-remote-query</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
|
|
@ -37,8 +37,13 @@
|
|||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.wildfly.common</groupId>
|
||||
<artifactId>wildfly-common</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan.protostream</groupId>
|
||||
|
@ -55,13 +60,11 @@
|
|||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-remote-query-client</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
<Set name="infinispanIdleTimeoutSec"><Property name="jetty.session.infinispan.idleTimeout.seconds" default="0" /></Set>
|
||||
<Set name="gracePeriodSec"><Property name="jetty.session.gracePeriod.seconds" default="3600" /></Set>
|
||||
<Set name="savePeriodSec"><Property name="jetty.session.savePeriod.seconds" default="0" /></Set>
|
||||
<Set name="serialization"><Property name="jetty.session.infinispan.serialization" default="false"/></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
|
||||
//
|
||||
// This program and the accompanying materials are made available under the
|
||||
// terms of the Eclipse Public License v. 2.0 which is available at
|
||||
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
|
||||
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
|
||||
//
|
||||
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
|
||||
// ========================================================================
|
||||
//
|
||||
|
||||
package org.eclipse.jetty.session.infinispan;
|
||||
|
||||
import java.io.UncheckedIOException;
|
||||
|
||||
import org.infinispan.protostream.FileDescriptorSource;
|
||||
import org.infinispan.protostream.SerializationContext;
|
||||
import org.infinispan.protostream.SerializationContextInitializer;
|
||||
|
||||
/**
|
||||
* Set up the marshaller for InfinispanSessionData serialization
|
||||
*
|
||||
*/
|
||||
public class InfinispanSerializationContextInitializer implements SerializationContextInitializer
|
||||
{
|
||||
@Override
|
||||
public String getProtoFileName()
|
||||
{
|
||||
return "session.proto";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getProtoFile() throws UncheckedIOException
|
||||
{
|
||||
return FileDescriptorSource.getResourceAsString(getClass(), "/" + getProtoFileName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerSchema(SerializationContext serCtx)
|
||||
{
|
||||
serCtx.registerProtoFiles(FileDescriptorSource.fromString(getProtoFileName(), getProtoFile()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerMarshallers(SerializationContext serCtx)
|
||||
{
|
||||
serCtx.registerMarshaller(new SessionDataMarshaller());
|
||||
}
|
||||
}
|
|
@ -38,7 +38,6 @@ import org.infinispan.commons.marshall.SerializeWith;
|
|||
* pool and thus these threads have no knowledge of the correct classloader to
|
||||
* use.
|
||||
*/
|
||||
@SerializeWith(SessionDataMarshaller.class)
|
||||
public class InfinispanSessionData extends SessionData
|
||||
{
|
||||
protected byte[] _serializedAttributes;
|
||||
|
|
|
@ -52,6 +52,8 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
private boolean _passivating;
|
||||
|
||||
private boolean _serialization;
|
||||
|
||||
/**
|
||||
* Get the clustered cache instance.
|
||||
*
|
||||
|
@ -94,9 +96,8 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
|
||||
try
|
||||
{
|
||||
_passivating = false;
|
||||
Class<?> remoteClass = InfinispanSessionDataStore.class.getClassLoader().loadClass("org.infinispan.client.hotrod.RemoteCache");
|
||||
if (remoteClass.isAssignableFrom(_cache.getClass()))
|
||||
if (remoteClass.isAssignableFrom(_cache.getClass()) || _serialization)
|
||||
_passivating = true;
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
|
@ -115,6 +116,9 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
LOG.debug("Loading session {} from infinispan", id);
|
||||
|
||||
InfinispanSessionData sd = (InfinispanSessionData)_cache.get(getCacheKey(id));
|
||||
|
||||
//Deserialize the attributes now that we are back in a thread that
|
||||
//has the correct classloader set on it
|
||||
if (isPassivating() && sd != null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
|
@ -235,6 +239,15 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
@Override
|
||||
public void doStore(String id, SessionData data, long lastSaveTime) throws Exception
|
||||
{
|
||||
//prepare for serialization: we need to convert the attributes now while the context
|
||||
//classloader is set, because infinispan uses a different thread and classloader to
|
||||
//perform the serialization
|
||||
if (isPassivating() && data != null)
|
||||
{
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Serializing session attributes for {}", id);
|
||||
((InfinispanSessionData)data).serializeAttributes();
|
||||
}
|
||||
//Put an idle timeout on the cache entry if the session is not immortal -
|
||||
//if no requests arrive at any node before this timeout occurs, or no node
|
||||
//scavenges the session before this timeout occurs, the session will be removed.
|
||||
|
@ -322,6 +335,11 @@ public class InfinispanSessionDataStore extends AbstractSessionDataStore
|
|||
{
|
||||
return _infinispanIdleTimeoutSec;
|
||||
}
|
||||
|
||||
public void setSerialization(boolean serialization)
|
||||
{
|
||||
_serialization = serialization;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
|
|
|
@ -32,6 +32,7 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF
|
|||
int _infinispanIdleTimeoutSec;
|
||||
BasicCache<String, SessionData> _cache;
|
||||
protected QueryManager _queryManager;
|
||||
protected boolean _serialization;
|
||||
|
||||
/**
|
||||
* @return the infinispanIdleTimeoutSec
|
||||
|
@ -61,6 +62,7 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF
|
|||
store.setCache(getCache());
|
||||
store.setSavePeriodSec(getSavePeriodSec());
|
||||
store.setQueryManager(getQueryManager());
|
||||
store.setSerialization(getSerialization());
|
||||
return store;
|
||||
}
|
||||
|
||||
|
@ -93,4 +95,14 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF
|
|||
{
|
||||
_queryManager = queryManager;
|
||||
}
|
||||
|
||||
public void setSerialization(boolean serialization)
|
||||
{
|
||||
_serialization = serialization;
|
||||
}
|
||||
|
||||
public boolean getSerialization()
|
||||
{
|
||||
return _serialization;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,10 +19,7 @@
|
|||
package org.eclipse.jetty.session.infinispan;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInput;
|
||||
import java.io.ObjectOutput;
|
||||
|
||||
import org.infinispan.commons.marshall.Externalizer;
|
||||
import org.infinispan.protostream.FileDescriptorSource;
|
||||
import org.infinispan.protostream.MessageMarshaller;
|
||||
import org.infinispan.protostream.ProtobufUtil;
|
||||
|
@ -36,8 +33,7 @@ import org.infinispan.protostream.SerializationContext;
|
|||
* control to ensure that session attributes can be deserialized using either
|
||||
* the container class loader or the webapp classloader, as appropriate.
|
||||
*/
|
||||
public class SessionDataMarshaller
|
||||
implements MessageMarshaller<InfinispanSessionData>, Externalizer<InfinispanSessionData>
|
||||
public class SessionDataMarshaller implements MessageMarshaller<InfinispanSessionData>
|
||||
{
|
||||
/**
|
||||
* The version of the serializer.
|
||||
|
@ -72,39 +68,6 @@ public class SessionDataMarshaller
|
|||
return "org_eclipse_jetty_session_infinispan.InfinispanSessionData";
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfinispanSessionData readObject(ObjectInput input) throws IOException, ClassNotFoundException
|
||||
{
|
||||
if (serializationContext == null)
|
||||
{
|
||||
initSerializationContext();
|
||||
}
|
||||
|
||||
// invokes readFrom(ProtoStreamReader)
|
||||
InfinispanSessionData data = ProtobufUtil.readFrom(serializationContext, new BoundDelegatingInputStream(input),
|
||||
InfinispanSessionData.class);
|
||||
if (data != null)
|
||||
{
|
||||
data.deserializeAttributes();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writeObject(ObjectOutput output, InfinispanSessionData object) throws IOException
|
||||
{
|
||||
if (serializationContext == null)
|
||||
{
|
||||
initSerializationContext();
|
||||
}
|
||||
|
||||
// invokes writeTo(ProtoStreamWriter, InfinispanSessionData)
|
||||
byte[] data = ProtobufUtil.toByteArray(serializationContext, object);
|
||||
int length = data.length;
|
||||
output.writeInt(length);
|
||||
output.write(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public InfinispanSessionData readFrom(ProtoStreamReader in) throws IOException
|
||||
{
|
||||
|
@ -132,6 +95,9 @@ public class SessionDataMarshaller
|
|||
if (version == 0)
|
||||
{
|
||||
byte[] attributeArray = in.readBytes("attributes");
|
||||
//only save the serialized bytes here, do NOT deserialize because
|
||||
//infinispan has called this method with their own thread without
|
||||
//the appropriate classloader being set
|
||||
sd.setSerializedAttributes(attributeArray);
|
||||
return sd;
|
||||
}
|
||||
|
@ -157,7 +123,9 @@ public class SessionDataMarshaller
|
|||
out.writeLong("expiry", sdata.getExpiry());
|
||||
out.writeLong("maxInactiveMs", sdata.getMaxInactiveMs());
|
||||
|
||||
sdata.serializeAttributes();
|
||||
//the session data attributes MUST be previously serialized
|
||||
//because this method is called from an infinispan thread that cannot
|
||||
//have the appropriate classloader set on it
|
||||
out.writeBytes("attributes", sdata.getSerializedAttributes());
|
||||
}
|
||||
|
||||
|
|
|
@ -1,78 +0,0 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
|
||||
// ------------------------------------------------------------------------
|
||||
// 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.infinispan.commons.marshall.jboss.AbstractJBossMarshaller;
|
||||
import org.jboss.marshalling.ContextClassResolver;
|
||||
|
||||
/**
|
||||
* WebAppMarshaller
|
||||
*
|
||||
* An implementation of the AbstractJBossMarshaller code that is just
|
||||
* enough to provide a ContextClassResolver that will use the Thread Context Classloader
|
||||
* in order to deserialize session attribute classes.
|
||||
*
|
||||
* This is necessary because the standard infinispan marshaller (GenericJBossMarshaller) uses the
|
||||
* classloader of the loader that loaded itself. When using the infinispan module in Jetty, all of
|
||||
* the infinispan classes will be on the container classpath. That means that the GenericJBossMarshaller
|
||||
* returns the container classloader which is unable to load any webapp classes. This class ensures
|
||||
* that it is always the webapp's classloader that will be used.
|
||||
*
|
||||
* In order to use this class, you should put a hotrod-client.properties file into the
|
||||
* ${jetty.base}/resources directory that contains this line:
|
||||
*
|
||||
* infinispan.client.hotrod.marshaller=org.eclipse.jetty.session.infinispan.WebAppMarshaller
|
||||
*
|
||||
* You will also need to add the following lines to a context xml file for your webapp to
|
||||
* permit the webapp's classloader to see the org.eclipse.jetty.session.infinispan classes for
|
||||
* the deserialization to work correctly:
|
||||
*
|
||||
* <Call name="prependServerClass">
|
||||
* <Arg>-org.eclipse.jetty.session.infinispan.</Arg>
|
||||
* </Call>
|
||||
*/
|
||||
@Deprecated
|
||||
public class WebAppMarshaller extends AbstractJBossMarshaller
|
||||
{
|
||||
|
||||
/**
|
||||
* WebAppContextClassResolver
|
||||
*
|
||||
* Provides the Thread Context Classloader to use for deserializing.
|
||||
*/
|
||||
public static class WebAppContextClassResolver extends ContextClassResolver
|
||||
{
|
||||
public WebAppContextClassResolver()
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected ClassLoader getClassLoader()
|
||||
{
|
||||
return Thread.currentThread().getContextClassLoader();
|
||||
}
|
||||
}
|
||||
|
||||
public WebAppMarshaller()
|
||||
{
|
||||
super();
|
||||
baseCfg.setClassResolver(new WebAppContextClassResolver());
|
||||
}
|
||||
}
|
|
@ -89,7 +89,6 @@
|
|||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-query</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package org.eclipse.jetty.session.infinispan;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -9,28 +8,32 @@ import org.infinispan.Cache;
|
|||
import org.infinispan.query.Search;
|
||||
import org.infinispan.query.dsl.Query;
|
||||
import org.infinispan.query.dsl.QueryFactory;
|
||||
import org.infinispan.query.dsl.QueryResult;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
public class EmbeddedQueryManager implements QueryManager
|
||||
{
|
||||
private Cache<String, SessionData> _cache;
|
||||
private QueryFactory _factory;
|
||||
|
||||
public EmbeddedQueryManager(Cache<String, SessionData> cache)
|
||||
{
|
||||
_cache = cache;
|
||||
_factory = Search.getQueryFactory(_cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> queryExpiredSessions(long time)
|
||||
{
|
||||
QueryFactory qf = Search.getQueryFactory(_cache);
|
||||
Query q = qf.from(SessionData.class).select("id").having("expiry").lte(time).build();
|
||||
|
||||
List<Object[]> list = q.list();
|
||||
Set<String> ids = new HashSet<>();
|
||||
for (Object[] sl : list)
|
||||
{
|
||||
ids.add((String)sl[0]);
|
||||
}
|
||||
Query<InfinispanSessionData> expiredQuery = _factory.create("select id from org.eclipse.jetty.server.session.SessionData where " +
|
||||
" expiry <= :expiry and expiry > 0");
|
||||
expiredQuery.setParameter("expiry", time);
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
QueryResult result = expiredQuery.execute();
|
||||
List<Object[]> list = result.list();
|
||||
Set<String> ids = list.stream().map(a -> (String)a[0]).collect(toSet());
|
||||
return ids;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@ import java.util.Set;
|
|||
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.session.infinispan.EmbeddedQueryManager;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionData;
|
||||
import org.eclipse.jetty.session.infinispan.QueryManager;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.hibernate.search.cfg.Environment;
|
||||
|
@ -33,7 +34,6 @@ import org.hibernate.search.cfg.SearchMapping;
|
|||
import org.infinispan.Cache;
|
||||
import org.infinispan.configuration.cache.Configuration;
|
||||
import org.infinispan.configuration.cache.ConfigurationBuilder;
|
||||
import org.infinispan.configuration.cache.Index;
|
||||
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
|
||||
import org.infinispan.manager.DefaultCacheManager;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
|
@ -50,7 +50,7 @@ public class EmbeddedQueryManagerTest
|
|||
public void test()
|
||||
{
|
||||
String name = DEFAULT_CACHE_NAME + System.currentTimeMillis();
|
||||
EmbeddedCacheManager cacheManager = new DefaultCacheManager(new GlobalConfigurationBuilder().globalJmxStatistics().allowDuplicateDomains(true).build());
|
||||
EmbeddedCacheManager cacheManager = new DefaultCacheManager(new GlobalConfigurationBuilder().jmx().build());
|
||||
|
||||
//TODO verify that this is being indexed properly, if you change expiry to something that is not a valid field it still passes the tests
|
||||
SearchMapping mapping = new SearchMapping();
|
||||
|
@ -64,7 +64,7 @@ public class EmbeddedQueryManagerTest
|
|||
if (dcc != null)
|
||||
b = b.read(dcc);
|
||||
|
||||
b.indexing().index(Index.ALL).addIndexedEntity(SessionData.class).withProperties(properties);
|
||||
b.indexing().addIndexedEntity(InfinispanSessionData.class).withProperties(properties);
|
||||
Configuration c = b.build();
|
||||
|
||||
cacheManager.defineConfiguration(name, c);
|
||||
|
|
|
@ -81,7 +81,12 @@
|
|||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-core</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.wildfly.common</groupId>
|
||||
<artifactId>wildfly-common</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
|
|
|
@ -20,5 +20,6 @@ infinispan.version?=@infinispan.version@
|
|||
|
||||
[ini-template]
|
||||
#jetty.session.infinispan.idleTimeout.seconds=0
|
||||
#jetty.session.infinispan.serialization=false
|
||||
#jetty.session.gracePeriod.seconds=3600
|
||||
#jetty.session.savePeriod.seconds=0
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
<name>Jetty :: Infinispan Session Manager Remote</name>
|
||||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.infinispan.remote.query</bundle-symbolic-name>
|
||||
<infinispan.docker.image.version>9.4.8.Final</infinispan.docker.image.version>
|
||||
<infinispan.docker.image.version>11.0.9.Final</infinispan.docker.image.version>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -99,17 +99,19 @@
|
|||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-query</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-remote-query-client</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>${gson.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<!-- ===================================================================== -->
|
||||
<New id="mapping" class="org.hibernate.search.cfg.SearchMapping">
|
||||
<Call name="entity">
|
||||
<Arg><Call class="java.lang.Class" name="forName"><Arg>org.eclipse.jetty.server.session.SessionData</Arg></Call></Arg>
|
||||
<Arg><Call class="java.lang.Class" name="forName"><Arg>org.eclipse.jetty.session.infinispan.InfinispanSessionData</Arg></Call></Arg>
|
||||
<Call name="indexed">
|
||||
<Call name="providedId">
|
||||
<Call name="property">
|
||||
|
@ -33,20 +33,25 @@
|
|||
<Arg><Ref refid="mapping"/></Arg>
|
||||
</Call>
|
||||
</New>
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Convert properties to configuration. -->
|
||||
<!-- ===================================================================== -->
|
||||
<New class="org.infinispan.client.hotrod.configuration.ConfigurationBuilder">
|
||||
|
||||
<Call name="withProperties">
|
||||
<Arg><Ref refid="properties"/></Arg>
|
||||
</Call>
|
||||
</Call>
|
||||
<Call name="marshaller">
|
||||
<Arg>
|
||||
<New class="org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller"/>
|
||||
<New class="org.infinispan.commons.marshall.ProtoStreamMarshaller"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="addContextInitializer">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.session.infinispan.InfinispanSerializationContextInitializer"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call id="config" name="build"/>
|
||||
</New>
|
||||
|
||||
|
@ -57,42 +62,16 @@
|
|||
<Arg><Ref refid="config"/></Arg>
|
||||
</New>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Set up custom session serialization. -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call id="serial_context" class="org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller" name="getSerializationContext">
|
||||
<Arg>
|
||||
<Ref refid="remoteCacheManager"/>
|
||||
</Arg>
|
||||
<Call name="registerProtoFiles">
|
||||
<Arg>
|
||||
<New class="org.infinispan.protostream.FileDescriptorSource">
|
||||
<Call name="addProtoFiles">
|
||||
<Arg>
|
||||
<Array type="java.lang.String">
|
||||
<Item>/session.proto</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="registerMarshaller">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.session.infinispan.SessionDataMarshaller"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Call>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Get a reference to the remote cache. -->
|
||||
<!-- ===================================================================== -->
|
||||
|
||||
<Ref refid="remoteCacheManager">
|
||||
<Call id="cache" name="getCache">
|
||||
<Arg><Property name="jetty.session.infinispan.remoteCacheName" default="sessions"/></Arg>
|
||||
</Call>
|
||||
</Ref>
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Set queryMgrFactory reference to RemoteQueryManagerFactory -->
|
||||
<!-- ===================================================================== -->
|
||||
|
|
|
@ -10,13 +10,9 @@ infinispan-remote
|
|||
[depends]
|
||||
sessions/infinispan/remote/infinispan-remote-query-libs
|
||||
|
||||
[files]
|
||||
basehome:modules/sessions/infinispan/remote/other_proto_marshallers.xml|etc/other_proto_marshallers.xml
|
||||
|
||||
[lib]
|
||||
lib/infinispan-remote-query-${jetty.version}.jar
|
||||
|
||||
[xml]
|
||||
etc/sessions/infinispan/infinispan-remote-query.xml
|
||||
etc/other_proto_marshallers.xml
|
||||
etc/sessions/infinispan/infinispan-common.xml
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
<?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">
|
||||
|
||||
<!-- ============================================================= -->
|
||||
<!-- If your sessions contain any objects of classes from your -->
|
||||
<!-- from your application, you need to describe each class in a -->
|
||||
<!-- .proto file, and supply a marshaller for each to read/write -->
|
||||
<!-- instances. These classes will need to exist on the server's -->
|
||||
<!-- classpath because they are referenced BEFORE your webapp is -->
|
||||
<!-- started. -->
|
||||
<!-- ============================================================= -->
|
||||
<Ref refid="serial_context">
|
||||
<!--
|
||||
<Call name="registerProtoFiles">
|
||||
<Arg>
|
||||
<New class="org.infinispan.protostream.FileDescriptorSource">
|
||||
<Call name="addProtoFile">
|
||||
<Arg>my.proto</Arg>
|
||||
<Arg>
|
||||
<New class="java.io.File">
|
||||
<Arg><Property name="jetty.base" default="."/>/etc/my.proto</Arg>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
-->
|
||||
<!--
|
||||
<Call name="registerMarshaller">
|
||||
<Arg>
|
||||
<New class="com.acme.MyMarshaller"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
-->
|
||||
</Ref>
|
||||
</Configure>
|
|
@ -18,7 +18,6 @@
|
|||
|
||||
package org.eclipse.jetty.session.infinispan;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
|
@ -27,6 +26,9 @@ import org.infinispan.client.hotrod.RemoteCache;
|
|||
import org.infinispan.client.hotrod.Search;
|
||||
import org.infinispan.query.dsl.Query;
|
||||
import org.infinispan.query.dsl.QueryFactory;
|
||||
import org.infinispan.query.dsl.QueryResult;
|
||||
|
||||
import static java.util.stream.Collectors.toSet;
|
||||
|
||||
/**
|
||||
* RemoteQueryManager
|
||||
|
@ -36,26 +38,25 @@ import org.infinispan.query.dsl.QueryFactory;
|
|||
public class RemoteQueryManager implements QueryManager
|
||||
{
|
||||
private RemoteCache<String, SessionData> _cache;
|
||||
private QueryFactory _factory;
|
||||
|
||||
public RemoteQueryManager(RemoteCache<String, SessionData> cache)
|
||||
{
|
||||
_cache = cache;
|
||||
_factory = Search.getQueryFactory(_cache);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> queryExpiredSessions(long time)
|
||||
{
|
||||
// TODO can the QueryFactory be created only once
|
||||
QueryFactory qf = Search.getQueryFactory(_cache);
|
||||
Query q = qf.from(InfinispanSessionData.class).select("id").having("expiry").lte(time).build();
|
||||
|
||||
List<Object[]> list = q.list();
|
||||
Set<String> ids = new HashSet<>();
|
||||
for (Object[] sl : list)
|
||||
{
|
||||
ids.add((String)sl[0]);
|
||||
}
|
||||
|
||||
Query<InfinispanSessionData> expiredQuery = _factory.create("select id from org_eclipse_jetty_session_infinispan.InfinispanSessionData where " +
|
||||
"expiry <= :expiry and expiry > 0");
|
||||
expiredQuery.setParameter("expiry", time);
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
QueryResult result = expiredQuery.execute();
|
||||
List<Object[]> list = result.list();
|
||||
Set<String> ids = list.stream().map(a -> (String)a[0]).collect(toSet());
|
||||
return ids;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ public class RemoteQueryManagerFactory implements QueryManagerFactory
|
|||
@Override
|
||||
public QueryManager getQueryManager(BasicCache<String, SessionData> cache)
|
||||
{
|
||||
System.err.println(cache.getClass().getName());
|
||||
if (!RemoteCache.class.isAssignableFrom(cache.getClass()))
|
||||
throw new IllegalArgumentException("Argument is not of type RemoteCache");
|
||||
|
||||
|
|
|
@ -25,12 +25,15 @@ import java.util.HashSet;
|
|||
import java.util.Properties;
|
||||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.session.SessionContext;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSerializationContextInitializer;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionData;
|
||||
import org.eclipse.jetty.session.infinispan.QueryManager;
|
||||
import org.eclipse.jetty.session.infinispan.RemoteQueryManager;
|
||||
import org.eclipse.jetty.session.infinispan.SessionDataMarshaller;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.hibernate.search.cfg.Environment;
|
||||
import org.hibernate.search.cfg.SearchMapping;
|
||||
|
@ -38,9 +41,8 @@ import org.infinispan.client.hotrod.RemoteCache;
|
|||
import org.infinispan.client.hotrod.RemoteCacheManager;
|
||||
import org.infinispan.client.hotrod.configuration.ClientIntelligence;
|
||||
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
|
||||
import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
|
||||
import org.infinispan.protostream.FileDescriptorSource;
|
||||
import org.infinispan.protostream.SerializationContext;
|
||||
import org.infinispan.commons.configuration.XMLStringConfiguration;
|
||||
import org.infinispan.commons.marshall.ProtoStreamMarshaller;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -51,8 +53,6 @@ import org.testcontainers.containers.output.Slf4jLogConsumer;
|
|||
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@Testcontainers(disabledWithoutDocker = true)
|
||||
|
@ -64,15 +64,21 @@ public class RemoteQueryManagerTest
|
|||
|
||||
private static final Logger INFINISPAN_LOG =
|
||||
LoggerFactory.getLogger("org.eclipse.jetty.server.session.infinispan.infinispanLogs");
|
||||
|
||||
|
||||
private static final Random r = new Random();
|
||||
private static final int NUM_SESSIONS = 10;
|
||||
private static final int MAX_EXPIRY_TIME = 1000;
|
||||
private static final String NODE_ID = "w0";
|
||||
private static int count;
|
||||
private String host;
|
||||
private int port;
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
GenericContainer infinispan =
|
||||
new GenericContainer(System.getProperty("infinispan.docker.image.name", "jboss/infinispan-server") +
|
||||
":" + System.getProperty("infinispan.docker.image.version", "9.4.8.Final"))
|
||||
.withEnv("APP_USER", "theuser")
|
||||
.withEnv("APP_PASS", "foobar")
|
||||
new GenericContainer(System.getProperty("infinispan.docker.image.name", "infinispan/server") +
|
||||
":" + System.getProperty("infinispan.docker.image.version", "11.0.9.Final"))
|
||||
.withEnv("USER", "theuser")
|
||||
.withEnv("PASS", "foobar")
|
||||
.withEnv("MGMT_USER", "admin")
|
||||
.withEnv("MGMT_PASS", "admin")
|
||||
.waitingFor(new LogMessageWaitStrategy()
|
||||
|
@ -101,27 +107,27 @@ public class RemoteQueryManagerTest
|
|||
public void testQuery() throws Exception
|
||||
{
|
||||
SearchMapping mapping = new SearchMapping();
|
||||
mapping.entity(SessionData.class).indexed().providedId().property("expiry", ElementType.FIELD).field();
|
||||
mapping.entity(InfinispanSessionData.class).indexed().providedId()
|
||||
.property("expiry", ElementType.METHOD).field();
|
||||
|
||||
Properties properties = new Properties();
|
||||
properties.put(Environment.MODEL_MAPPING, mapping);
|
||||
|
||||
ConfigurationBuilder clientBuilder = new ConfigurationBuilder();
|
||||
clientBuilder.withProperties(properties).addServer()
|
||||
.host(this.host).port(this.port)
|
||||
.clientIntelligence(ClientIntelligence.BASIC)
|
||||
.marshaller(new ProtoStreamMarshaller());
|
||||
clientBuilder.withProperties(properties)
|
||||
.addServer()
|
||||
.host(this.host).port(this.port)
|
||||
.clientIntelligence(ClientIntelligence.BASIC)
|
||||
.marshaller(new ProtoStreamMarshaller())
|
||||
.security()
|
||||
.authentication()
|
||||
.username("theuser").password("foobar");
|
||||
|
||||
clientBuilder.addContextInitializer(new InfinispanSerializationContextInitializer());
|
||||
|
||||
RemoteCacheManager remoteCacheManager = new RemoteCacheManager(clientBuilder.build());
|
||||
remoteCacheManager.administration().getOrCreateCache("remote-session-test", (String)null);
|
||||
|
||||
FileDescriptorSource fds = new FileDescriptorSource();
|
||||
fds.addProtoFiles("/session.proto");
|
||||
|
||||
SerializationContext serCtx = ProtoStreamMarshaller.getSerializationContext(remoteCacheManager);
|
||||
serCtx.registerProtoFiles(fds);
|
||||
serCtx.registerMarshaller(new SessionDataMarshaller());
|
||||
|
||||
//upload the session.proto serialization descriptor to the remote cache
|
||||
try (InputStream is = RemoteQueryManagerTest.class.getClassLoader().getResourceAsStream("session.proto");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream())
|
||||
{
|
||||
|
@ -129,45 +135,71 @@ public class RemoteQueryManagerTest
|
|||
throw new IllegalStateException("inputstream is null");
|
||||
IO.copy(is, baos);
|
||||
String content = baos.toString("UTF-8");
|
||||
remoteCacheManager.getCache("___protobuf_metadata").put("session.proto", content);
|
||||
remoteCacheManager.administration().getOrCreateCache("___protobuf_metadata", (String)null).put("session.proto", content);
|
||||
}
|
||||
|
||||
//make the remote cache encoded with protostream
|
||||
String xml = String.format("<infinispan>" +
|
||||
"<cache-container>" + "<distributed-cache name=\"%s\" mode=\"SYNC\">" +
|
||||
"<encoding media-type=\"application/x-protostream\"/>" +
|
||||
"</distributed-cache>" +
|
||||
"</cache-container>" +
|
||||
"</infinispan>", DEFAULT_CACHE_NAME);
|
||||
XMLStringConfiguration xmlConfig = new XMLStringConfiguration(xml);
|
||||
RemoteCache<String, SessionData> cache = remoteCacheManager.administration().getOrCreateCache(DEFAULT_CACHE_NAME, xmlConfig);
|
||||
|
||||
//put some sessions into the cache for "foo" context
|
||||
ContextHandler fooHandler = new ContextHandler();
|
||||
fooHandler.setContextPath("/foo");
|
||||
SessionContext fooSessionContext = new SessionContext(NODE_ID, fooHandler.getServletContext());
|
||||
Set<SessionData> fooSessions = createSessions(cache, fooSessionContext);
|
||||
|
||||
//put some sessions into the cache for "bar" context
|
||||
ContextHandler barHandler = new ContextHandler();
|
||||
barHandler.setContextPath("/bar");
|
||||
SessionContext barSessionContext = new SessionContext(NODE_ID, barHandler.getServletContext());
|
||||
Set<SessionData> barSessions = createSessions(cache, barSessionContext);
|
||||
|
||||
RemoteCache<String, SessionData> cache = remoteCacheManager.getCache(DEFAULT_CACHE_NAME);
|
||||
int time = 500;
|
||||
|
||||
//run the query for "foo" context
|
||||
checkResults(cache, fooSessionContext, time, fooSessions);
|
||||
|
||||
//run the query for the "bar" context
|
||||
checkResults(cache, barSessionContext, time, barSessions);
|
||||
}
|
||||
|
||||
//put some sessions into the remote cache
|
||||
int numSessions = 10;
|
||||
long currentTime = 500;
|
||||
int maxExpiryTime = 1000;
|
||||
Set<String> expiredSessions = new HashSet<>();
|
||||
Random r = new Random();
|
||||
private Set<SessionData> createSessions(RemoteCache<String, SessionData> cache, SessionContext sessionContext) throws Exception
|
||||
{
|
||||
Set<SessionData> sessions = new HashSet<>();
|
||||
|
||||
for (int i = 0; i < numSessions; i++)
|
||||
for (int i = 0; i < NUM_SESSIONS; i++)
|
||||
{
|
||||
String id = "sd" + i;
|
||||
//create new sessiondata with random expiry time
|
||||
long expiryTime = r.nextInt(maxExpiryTime);
|
||||
InfinispanSessionData sd = new InfinispanSessionData(id, "", "", 0, 0, 0, 0);
|
||||
sd.setLastNode("lastNode");
|
||||
long expiryTime = r.nextInt(MAX_EXPIRY_TIME);
|
||||
String id = "sd" + count;
|
||||
count++;
|
||||
InfinispanSessionData sd = new InfinispanSessionData(id, sessionContext.getCanonicalContextPath(), sessionContext.getVhost(), 0, 0, 0, 0);
|
||||
sd.setLastNode(sessionContext.getWorkerName());
|
||||
sd.setExpiry(expiryTime);
|
||||
|
||||
//if this entry has expired add it to expiry list
|
||||
if (expiryTime <= currentTime)
|
||||
expiredSessions.add(id);
|
||||
|
||||
sd.serializeAttributes();
|
||||
sessions.add(sd);
|
||||
//add to cache
|
||||
cache.put(id, sd);
|
||||
assertNotNull(cache.get(id));
|
||||
}
|
||||
return sessions;
|
||||
}
|
||||
|
||||
//run the query
|
||||
private void checkResults(RemoteCache<String, SessionData> cache, SessionContext sessionContext, int time, Set<SessionData> sessions)
|
||||
{
|
||||
QueryManager qm = new RemoteQueryManager(cache);
|
||||
Set<String> queryResult = qm.queryExpiredSessions(currentTime);
|
||||
|
||||
// Check that the result is correct
|
||||
assertEquals(expiredSessions.size(), queryResult.size());
|
||||
for (String s : expiredSessions)
|
||||
Set<String> queryResult = qm.queryExpiredSessions(time);
|
||||
|
||||
Set<SessionData> expected = sessions.stream().filter(s -> s.getExpiry() > 0 && s.getExpiry() <= time).collect(Collectors.toSet());
|
||||
for (SessionData s : expected)
|
||||
{
|
||||
assertTrue(queryResult.contains(s));
|
||||
assertTrue(queryResult.remove(s.getId()));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,13 +81,11 @@
|
|||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-client-hotrod</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-remote-query-client</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
|
|
|
@ -24,7 +24,12 @@
|
|||
</Call>
|
||||
<Call name="marshaller">
|
||||
<Arg>
|
||||
<New class="org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller"/>
|
||||
<New class="org.infinispan.commons.marshall.ProtoStreamMarshaller"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="addContextInitializer">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.session.infinispan.InfinispanSerializationContextInitializer"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call id="config" name="build"/>
|
||||
|
@ -37,35 +42,6 @@
|
|||
<Arg><Ref refid="config"/></Arg>
|
||||
</New>
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Set up custom session serialization. -->
|
||||
<!-- ===================================================================== -->
|
||||
<Call id="serial_context" class="org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller" name="getSerializationContext">
|
||||
<Arg>
|
||||
<Ref refid="hotrodMgr"/>
|
||||
</Arg>
|
||||
<Call name="registerProtoFiles">
|
||||
<Arg>
|
||||
<New class="org.infinispan.protostream.FileDescriptorSource">
|
||||
<Call name="addProtoFiles">
|
||||
<Arg>
|
||||
<Array type="java.lang.String">
|
||||
<Item>/session.proto</Item>
|
||||
</Array>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
<Call name="registerMarshaller">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.session.infinispan.SessionDataMarshaller"/>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Call>
|
||||
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- Get a reference to the remote cache. -->
|
||||
<!-- ===================================================================== -->
|
||||
|
|
|
@ -18,7 +18,6 @@ basehome:modules/sessions/infinispan/remote/resources/hotrod-client.properties|r
|
|||
[ini]
|
||||
infinispan.version?=@infinispan.version@
|
||||
|
||||
|
||||
[license]
|
||||
Infinispan is an open source project hosted on Github and released under the Apache 2.0 license.
|
||||
http://infinispan.org/
|
||||
|
@ -26,6 +25,7 @@ http://www.apache.org/licenses/LICENSE-2.0.html
|
|||
|
||||
[ini-template]
|
||||
#jetty.session.infinispan.remoteCacheName=sessions
|
||||
#jetty.session.infinispan.serialization=true
|
||||
#jetty.session.infinispan.idleTimeout.seconds=0
|
||||
#jetty.session.gracePeriod.seconds=3600
|
||||
#jetty.session.savePeriod.seconds=0
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
#infinispan.client.hotrod.server_list
|
||||
#infinispan.client.hotrod.context-initializers=
|
||||
|
|
|
@ -82,6 +82,7 @@ public class SessionData implements Serializable
|
|||
Class<?> clazz = entry.getValue().getClass();
|
||||
ClassLoader loader = clazz.getClassLoader();
|
||||
ClassLoader contextLoader = Thread.currentThread().getContextClassLoader();
|
||||
|
||||
boolean isContextLoader;
|
||||
|
||||
if (loader == contextLoader) //is it the context classloader?
|
||||
|
@ -109,7 +110,7 @@ public class SessionData implements Serializable
|
|||
isContextLoader = false; //TCCL can't see the class
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (LOG.isDebugEnabled())
|
||||
LOG.debug("Attribute {} class={} isServerLoader={}", entry.getKey(), clazz.getName(), (!isContextLoader));
|
||||
out.writeBoolean(!isContextLoader);
|
||||
|
|
40
pom.xml
40
pom.xml
|
@ -39,7 +39,7 @@
|
|||
<guice.version>5.0.1</guice.version>
|
||||
<hawtio.version>2.14.0</hawtio.version>
|
||||
<hazelcast.version>3.12.12</hazelcast.version>
|
||||
<infinispan.version>9.4.8.Final</infinispan.version>
|
||||
<infinispan.version>11.0.11.Final</infinispan.version>
|
||||
<infinispan.protostream.version>4.3.4.Final</infinispan.protostream.version>
|
||||
<jamon.version>2.82</jamon.version>
|
||||
<javax.activation.version>1.1.0.v201105071233</javax.activation.version>
|
||||
|
@ -1000,6 +1000,39 @@
|
|||
<artifactId>jna</artifactId>
|
||||
<version>${jna.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
<artifactId>infinispan-bom</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</dependency>
|
||||
<!-- jboss deps.. -->
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<version>${jboss.logging.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging-processor</artifactId>
|
||||
<version>2.2.1.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging-annotations</artifactId>
|
||||
<version>2.2.1.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logmanager</groupId>
|
||||
<artifactId>jboss-logmanager</artifactId>
|
||||
<version>2.1.15.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.threads</groupId>
|
||||
<artifactId>jboss-threads</artifactId>
|
||||
<version>3.1.0.Final</version>
|
||||
</dependency>
|
||||
<!-- Old Deps -->
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty.toolchain</groupId>
|
||||
|
@ -1031,11 +1064,6 @@
|
|||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>${slf4j.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.jboss.logging</groupId>
|
||||
<artifactId>jboss-logging</artifactId>
|
||||
<version>${jboss.logging.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.github.jnr</groupId>
|
||||
<artifactId>jnr-enxio</artifactId>
|
||||
|
|
|
@ -150,6 +150,12 @@
|
|||
<scope>test</scope>
|
||||
<type>war</type>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-remote-query</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>testcontainers</artifactId>
|
||||
|
@ -168,6 +174,9 @@
|
|||
<jettyVersion>${project.version}</jettyVersion>
|
||||
<hazelcast.version>${hazelcast.version}</hazelcast.version>
|
||||
<distribution.debug.port>$(distribution.debug.port}</distribution.debug.port>
|
||||
<home.start.timeout>${home.start.timeout}</home.start.timeout>
|
||||
<mariadb.version>${mariadb.version}</mariadb.version>
|
||||
<sessionLogLevel>${sessionLogLevel}</sessionLogLevel>
|
||||
</systemPropertyVariables>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
|
|
@ -0,0 +1,227 @@
|
|||
//
|
||||
// ========================================================================
|
||||
// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
|
||||
// ------------------------------------------------------------------------
|
||||
// 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.tests.distribution;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.eclipse.jetty.client.api.ContentResponse;
|
||||
import org.eclipse.jetty.http.HttpStatus;
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSerializationContextInitializer;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.infinispan.client.hotrod.RemoteCache;
|
||||
import org.infinispan.client.hotrod.RemoteCacheManager;
|
||||
import org.infinispan.client.hotrod.configuration.Configuration;
|
||||
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
|
||||
import org.infinispan.commons.configuration.XMLStringConfiguration;
|
||||
import org.infinispan.commons.marshall.ProtoStreamMarshaller;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
import org.testcontainers.containers.output.Slf4jLogConsumer;
|
||||
import org.testcontainers.containers.wait.strategy.LogMessageWaitStrategy;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class InfinispanSessionDistributionTests extends AbstractDistributionTest
|
||||
{
|
||||
private static final Logger LOGGER = LoggerFactory.getLogger(InfinispanSessionDistributionTests.class);
|
||||
private static final Logger INFINISPAN_LOG = LoggerFactory.getLogger("org.eclipse.jetty.tests.distribution.session.infinispan");
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
private GenericContainer infinispan;
|
||||
|
||||
private String infinispanHost;
|
||||
private int infinispanPort;
|
||||
|
||||
@Test
|
||||
public void stopRestartWebappTestSessionContentSaved() throws Exception
|
||||
{
|
||||
String jettyVersion = System.getProperty("jettyVersion");
|
||||
DistributionTester distribution = DistributionTester.Builder.newInstance()
|
||||
.jettyVersion(jettyVersion)
|
||||
.mavenLocalRepository(System.getProperty("mavenRepoPath"))
|
||||
.build();
|
||||
|
||||
startExternalSessionStorage(distribution.getJettyBase());
|
||||
|
||||
String[] args1 = {
|
||||
"--create-startd",
|
||||
"--approve-all-licenses",
|
||||
"--add-to-start=resources,server,http,webapp,deploy,jmx,servlet,servlets,logging-slf4j,slf4j-simple-impl,session-store-infinispan-remote,infinispan-remote-query"};
|
||||
|
||||
try (DistributionTester.Run run1 = distribution.start(args1))
|
||||
{
|
||||
assertTrue(run1.awaitFor(5, TimeUnit.SECONDS));
|
||||
assertEquals(0, run1.getExitValue());
|
||||
|
||||
File war = distribution.resolveArtifact("org.eclipse.jetty.tests:test-simple-session-webapp:war:" + jettyVersion);
|
||||
distribution.installWarFile(war, "test");
|
||||
|
||||
int jettyPort = distribution.freePort();
|
||||
|
||||
String[] argsStart = {
|
||||
"jetty.http.port=" + jettyPort
|
||||
};
|
||||
|
||||
configureExternalSessionStorage(distribution.getJettyBase());
|
||||
|
||||
try (DistributionTester.Run run2 = distribution.start(argsStart))
|
||||
{
|
||||
run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS);
|
||||
|
||||
startHttpClient();
|
||||
ContentResponse response = client.GET("http://localhost:" + jettyPort + "/test/session?action=CREATE");
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertThat(response.getContentAsString(), containsString("SESSION CREATED"));
|
||||
|
||||
response = client.GET("http://localhost:" + jettyPort + "/test/session?action=READ");
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertThat(response.getContentAsString(), containsString("SESSION READ CHOCOLATE THE BEST:FRENCH"));
|
||||
}
|
||||
|
||||
try (DistributionTester.Run run2 = distribution.start(argsStart))
|
||||
{
|
||||
assertTrue(run2.awaitConsoleLogsFor("Started @", 10, TimeUnit.SECONDS));
|
||||
|
||||
ContentResponse response = client.GET("http://localhost:" + jettyPort + "/test/session?action=READ");
|
||||
assertEquals(HttpStatus.OK_200, response.getStatus());
|
||||
assertThat(response.getContentAsString(), containsString("SESSION READ CHOCOLATE THE BEST:FRENCH"));
|
||||
}
|
||||
}
|
||||
stopExternalSessionStorage();
|
||||
}
|
||||
|
||||
public void startExternalSessionStorage(Path jettyBase) throws Exception
|
||||
{
|
||||
String infinispanVersion = System.getProperty("infinispan.docker.image.version", "11.0.9.Final");
|
||||
infinispan =
|
||||
new GenericContainer(System.getProperty("infinispan.docker.image.name", "infinispan/server") +
|
||||
":" + infinispanVersion)
|
||||
.withEnv("USER", "theuser")
|
||||
.withEnv("PASS", "foobar")
|
||||
.withEnv("MGMT_USER", "admin")
|
||||
.withEnv("MGMT_PASS", "admin")
|
||||
.waitingFor(new LogMessageWaitStrategy()
|
||||
.withRegEx(".*Infinispan Server.*started in.*\\s"))
|
||||
.withExposedPorts(4712, 4713, 8088, 8089, 8443, 9990, 9993, 11211, 11222, 11223, 11224)
|
||||
.withLogConsumer(new Slf4jLogConsumer(INFINISPAN_LOG));
|
||||
infinispan.start();
|
||||
infinispanHost = infinispan.getContainerIpAddress();
|
||||
infinispanPort = infinispan.getMappedPort(11222);
|
||||
|
||||
Path resourcesDirectory = jettyBase.resolve("resources");
|
||||
if (Files.exists(resourcesDirectory))
|
||||
{
|
||||
IO.delete(resourcesDirectory.toFile());
|
||||
}
|
||||
|
||||
Files.createDirectories(resourcesDirectory);
|
||||
Properties properties = new Properties();
|
||||
properties.put("infinispan.client.hotrod.server_list", infinispanHost + ":" + infinispanPort);
|
||||
properties.put("infinispan.client.hotrod.use_auth", "true");
|
||||
properties.put("infinispan.client.hotrod.sasl_mechanism", "DIGEST-MD5");
|
||||
properties.put("infinispan.client.hotrod.auth_username", "theuser");
|
||||
properties.put("infinispan.client.hotrod.auth_password", "foobar");
|
||||
|
||||
Path hotrod = resourcesDirectory.resolve("hotrod-client.properties");
|
||||
Files.deleteIfExists(hotrod);
|
||||
Files.createFile(hotrod);
|
||||
try (Writer writer = Files.newBufferedWriter(hotrod))
|
||||
{
|
||||
properties.store(writer, null);
|
||||
}
|
||||
|
||||
Configuration configuration = new ConfigurationBuilder().withProperties(properties)
|
||||
.addServer().host(infinispanHost).port(infinispanPort)
|
||||
.marshaller(new ProtoStreamMarshaller())
|
||||
.addContextInitializer(new InfinispanSerializationContextInitializer())
|
||||
.security().authentication().saslMechanism("DIGEST-MD5")
|
||||
.username("theuser").password("foobar")
|
||||
.build();
|
||||
|
||||
RemoteCacheManager remoteCacheManager = new RemoteCacheManager(configuration);
|
||||
ByteArrayOutputStream baos;
|
||||
try (InputStream is = this.getClass().getClassLoader().getResourceAsStream("session.proto"))
|
||||
{
|
||||
if (is == null)
|
||||
throw new IllegalStateException("inputstream is null");
|
||||
|
||||
baos = new ByteArrayOutputStream();
|
||||
IO.copy(is, baos);
|
||||
}
|
||||
|
||||
String content = baos.toString("UTF-8");
|
||||
remoteCacheManager.administration().getOrCreateCache("___protobuf_metadata", (String)null).put("session.proto", content);
|
||||
|
||||
String xml = String.format("<infinispan>" +
|
||||
"<cache-container>" + "<distributed-cache name=\"%s\" mode=\"SYNC\">" +
|
||||
"<encoding media-type=\"application/x-protostream\"/>" +
|
||||
"</distributed-cache>" +
|
||||
"</cache-container>" +
|
||||
"</infinispan>", "sessions");
|
||||
|
||||
XMLStringConfiguration xmlConfig = new XMLStringConfiguration(xml);
|
||||
RemoteCache<String, SessionData> cache = remoteCacheManager.administration().getOrCreateCache("sessions", xmlConfig);
|
||||
}
|
||||
|
||||
public void stopExternalSessionStorage() throws Exception
|
||||
{
|
||||
infinispan.stop();
|
||||
}
|
||||
|
||||
public void configureExternalSessionStorage(Path jettyBase) throws Exception
|
||||
{
|
||||
Path hotRodProperties = jettyBase.resolve("resources").resolve("hotrod-client.properties");
|
||||
Files.deleteIfExists(hotRodProperties);
|
||||
try (BufferedWriter writer = Files.newBufferedWriter(hotRodProperties, StandardCharsets.UTF_8, StandardOpenOption.CREATE))
|
||||
{
|
||||
writer.write("infinispan.client.hotrod.use_auth=true");
|
||||
writer.newLine();
|
||||
writer.write("infinispan.client.hotrod.server_list=" + infinispanHost + ":" + infinispanPort);
|
||||
writer.newLine();
|
||||
writer.write("infinispan.client.hotrod.sasl_mechanism=DIGEST-MD5");
|
||||
writer.newLine();
|
||||
writer.write("infinispan.client.hotrod.auth_username=theuser");
|
||||
writer.newLine();
|
||||
writer.write("infinispan.client.hotrod.auth_password=foobar");
|
||||
writer.newLine();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -29,6 +29,11 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
|||
@ExtendWith(WorkDirExtension.class)
|
||||
public class FileSessionDataStoreTest extends AbstractSessionDataStoreTest
|
||||
{
|
||||
public FileSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public WorkDir workDir;
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,6 +33,11 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||
public class GCloudSessionDataStoreTest extends AbstractSessionDataStoreTest
|
||||
{
|
||||
|
||||
public GCloudSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
public static GCloudSessionTestSupport __testSupport;
|
||||
|
||||
@BeforeAll
|
||||
|
|
|
@ -37,6 +37,10 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
*/
|
||||
public class HazelcastSessionDataStoreTest extends AbstractSessionDataStoreTest
|
||||
{
|
||||
public HazelcastSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
HazelcastTestHelper _testHelper;
|
||||
|
||||
|
|
|
@ -39,6 +39,10 @@ import static org.junit.jupiter.api.Assertions.fail;
|
|||
*/
|
||||
public class HazelcastSessionDataStoreTest extends AbstractSessionDataStoreTest
|
||||
{
|
||||
public HazelcastSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
HazelcastTestHelper _testHelper;
|
||||
|
||||
|
|
|
@ -11,9 +11,9 @@
|
|||
<properties>
|
||||
<bundle-symbolic-name>${project.groupId}.sessions.infinispan</bundle-symbolic-name>
|
||||
<!-- if changing this version please update default in RemoteInfinispanTestSupport you will get thanks from Eclipse IDE users -->
|
||||
<infinispan.docker.image.version>${infinispan.version}</infinispan.docker.image.version>
|
||||
<infinispan.docker.image.version>11.0.9.Final</infinispan.docker.image.version>
|
||||
<!-- from 10.xx it has changed to jboss/infinispan -->
|
||||
<infinispan.docker.image.name>jboss/infinispan-server</infinispan.docker.image.name>
|
||||
<infinispan.docker.image.name>infinispan/server</infinispan.docker.image.name>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
|
@ -87,10 +87,17 @@
|
|||
<artifactId>test-sessions-common</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-embedded-query</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
<artifactId>infinispan-remote-query</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.eclipse.jetty</groupId>
|
||||
|
@ -108,6 +115,12 @@
|
|||
<artifactId>infinispan-core</artifactId>
|
||||
<version>${infinispan.version}</version>
|
||||
<scope>test</scope>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>org.wildfly.common</groupId>
|
||||
<artifactId>wildfly-common</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.infinispan</groupId>
|
||||
|
|
|
@ -66,6 +66,7 @@ public class ClusteredSerializedSessionScavengingTest extends AbstractClusteredS
|
|||
public SessionDataStoreFactory createSessionDataStoreFactory()
|
||||
{
|
||||
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
|
||||
factory.setSerialization(true);
|
||||
factory.setCache(testSupport.getCache());
|
||||
return factory;
|
||||
}
|
||||
|
|
|
@ -65,6 +65,7 @@ public class ClusteredSessionScavengingTest extends AbstractClusteredSessionScav
|
|||
public SessionDataStoreFactory createSessionDataStoreFactory()
|
||||
{
|
||||
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
|
||||
factory.setSerialization(true);
|
||||
factory.setCache(testSupport.getCache());
|
||||
return factory;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@
|
|||
|
||||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import org.eclipse.jetty.session.infinispan.EmbeddedQueryManager;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
|
||||
import org.eclipse.jetty.session.infinispan.QueryManager;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -32,6 +35,11 @@ public class InfinispanFileSessionDataStoreTest extends InfinispanSessionDataSto
|
|||
|
||||
public WorkDir workDir;
|
||||
|
||||
public InfinispanFileSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception
|
||||
{
|
||||
|
@ -39,5 +47,14 @@ public class InfinispanFileSessionDataStoreTest extends InfinispanSessionDataSto
|
|||
_testSupport.setUseFileStore(true);
|
||||
_testSupport.setup(workDir.getEmptyPathDir());
|
||||
}
|
||||
|
||||
|
||||
public SessionDataStoreFactory createSessionDataStoreFactory()
|
||||
{
|
||||
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
|
||||
factory.setSerialization(true);
|
||||
factory.setCache(_testSupport.getCache());
|
||||
QueryManager qm = new EmbeddedQueryManager(_testSupport.getCache());
|
||||
factory.setQueryManager(qm);
|
||||
return factory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
|||
import org.infinispan.query.Search;
|
||||
import org.infinispan.query.dsl.Query;
|
||||
import org.infinispan.query.dsl.QueryFactory;
|
||||
import org.infinispan.query.dsl.QueryResult;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -45,7 +46,12 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
public InfinispanTestSupport _testSupport;
|
||||
|
||||
public WorkDir workDir;
|
||||
|
||||
|
||||
public InfinispanSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception
|
||||
{
|
||||
|
@ -70,7 +76,16 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public void persistSession(SessionData data) throws Exception
|
||||
{
|
||||
_testSupport.createSession(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(_contextClassLoader);
|
||||
try
|
||||
{
|
||||
_testSupport.createSession(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -82,7 +97,16 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
@Override
|
||||
public boolean checkSessionExists(SessionData data) throws Exception
|
||||
{
|
||||
return _testSupport.checkSessionExists(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return _testSupport.checkSessionExists(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -95,6 +119,7 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -160,14 +185,17 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
{
|
||||
InfinispanSessionData sd1 = new InfinispanSessionData("sd1", "", "", 0, 0, 0, 1000);
|
||||
sd1.setLastNode("fred1");
|
||||
sd1.serializeAttributes();
|
||||
_testSupport.getCache().put("session1", sd1);
|
||||
|
||||
InfinispanSessionData sd2 = new InfinispanSessionData("sd2", "", "", 0, 0, 0, 2000);
|
||||
sd2.setLastNode("fred2");
|
||||
sd2.serializeAttributes();
|
||||
_testSupport.getCache().put("session2", sd2);
|
||||
|
||||
InfinispanSessionData sd3 = new InfinispanSessionData("sd3", "", "", 0, 0, 0, 3000);
|
||||
sd3.setLastNode("fred3");
|
||||
sd3.serializeAttributes();
|
||||
_testSupport.getCache().put("session3", sd3);
|
||||
|
||||
QueryFactory qf = Search.getQueryFactory(_testSupport.getCache());
|
||||
|
@ -175,8 +203,9 @@ public class InfinispanSessionDataStoreTest extends AbstractSessionDataStoreTest
|
|||
for (int i = 0; i <= 3; i++)
|
||||
{
|
||||
long now = System.currentTimeMillis();
|
||||
Query q = qf.from(InfinispanSessionData.class).having("expiry").lt(now).build();
|
||||
assertEquals(i, q.list().size());
|
||||
Query<InfinispanSessionData> q = qf.create("from org.eclipse.jetty.session.infinispan.InfinispanSessionData where expiry < " + now);
|
||||
QueryResult<InfinispanSessionData> result = q.execute();
|
||||
assertEquals(i, result.list().size());
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ import java.nio.file.Files;
|
|||
import java.nio.file.Path;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSerializationContextInitializer;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionData;
|
||||
import org.eclipse.jetty.toolchain.test.FS;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.hibernate.search.cfg.Environment;
|
||||
|
@ -31,8 +33,9 @@ import org.hibernate.search.cfg.SearchMapping;
|
|||
import org.infinispan.Cache;
|
||||
import org.infinispan.configuration.cache.ConfigurationBuilder;
|
||||
import org.infinispan.configuration.cache.ConfigurationChildBuilder;
|
||||
import org.infinispan.configuration.cache.Index;
|
||||
import org.infinispan.configuration.cache.StorageType;
|
||||
import org.infinispan.configuration.global.GlobalConfigurationBuilder;
|
||||
import org.infinispan.eviction.EvictionStrategy;
|
||||
import org.infinispan.manager.DefaultCacheManager;
|
||||
import org.infinispan.manager.EmbeddedCacheManager;
|
||||
|
||||
|
@ -58,7 +61,10 @@ public class InfinispanTestSupport
|
|||
{
|
||||
try
|
||||
{
|
||||
_manager = new DefaultCacheManager(new GlobalConfigurationBuilder().globalJmxStatistics().allowDuplicateDomains(true).build());
|
||||
_manager = new DefaultCacheManager(new GlobalConfigurationBuilder().jmx()
|
||||
.serialization()
|
||||
.addContextInitializer(new InfinispanSerializationContextInitializer())
|
||||
.build());
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
@ -105,22 +111,28 @@ public class InfinispanTestSupport
|
|||
Properties properties = new Properties();
|
||||
properties.put(Environment.MODEL_MAPPING, mapping);
|
||||
properties.put("hibernate.search.default.indexBase", indexesDir.toString());
|
||||
properties.put("hibernate.cache.infinispan.entity.eviction.strategy", "NONE");
|
||||
|
||||
if (_useFileStore)
|
||||
{
|
||||
Path tmpDir = Files.createTempDirectory("infinispan");
|
||||
_tmpdir = tmpDir.toFile();
|
||||
|
||||
ConfigurationChildBuilder b = _builder.indexing()
|
||||
.index(Index.ALL)
|
||||
ConfigurationChildBuilder b = _builder
|
||||
.indexing()
|
||||
.addIndexedEntity(SessionData.class)
|
||||
.withProperties(properties)
|
||||
.memory()
|
||||
.whenFull(EvictionStrategy.NONE)
|
||||
.persistence()
|
||||
.addSingleFileStore()
|
||||
.segmented(false)
|
||||
.location(_tmpdir.getAbsolutePath());
|
||||
if (_serializeSessionData)
|
||||
{
|
||||
b = b.storeAsBinary().enable();
|
||||
b = b.memory().storage(StorageType.HEAP)
|
||||
.encoding()
|
||||
.mediaType("application/x-protostream");
|
||||
}
|
||||
|
||||
_manager.defineConfiguration(_name, b.build());
|
||||
|
@ -129,12 +141,13 @@ public class InfinispanTestSupport
|
|||
{
|
||||
ConfigurationChildBuilder b = _builder.indexing()
|
||||
.withProperties(properties)
|
||||
.index(Index.ALL)
|
||||
.addIndexedEntity(SessionData.class);
|
||||
|
||||
if (_serializeSessionData)
|
||||
{
|
||||
b = b.storeAsBinary().enable();
|
||||
b = b.memory().storage(StorageType.HEAP)
|
||||
.encoding()
|
||||
.mediaType("application/x-protostream");
|
||||
}
|
||||
|
||||
_manager.defineConfiguration(_name, b.build());
|
||||
|
@ -145,7 +158,7 @@ public class InfinispanTestSupport
|
|||
public void teardown() throws Exception
|
||||
{
|
||||
_cache.clear();
|
||||
_manager.removeCache(_name);
|
||||
_manager.administration().removeCache(_name);
|
||||
if (_useFileStore)
|
||||
{
|
||||
if (_tmpdir != null)
|
||||
|
@ -159,6 +172,7 @@ public class InfinispanTestSupport
|
|||
public void createSession(SessionData data)
|
||||
throws Exception
|
||||
{
|
||||
((InfinispanSessionData)data).serializeAttributes();
|
||||
_cache.put(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId(), data);
|
||||
}
|
||||
|
||||
|
@ -176,18 +190,24 @@ public class InfinispanTestSupport
|
|||
public boolean checkSessionPersisted(SessionData data)
|
||||
throws Exception
|
||||
{
|
||||
|
||||
//evicts the object from memory. Forces the cache to fetch the data from file
|
||||
if (_useFileStore)
|
||||
{
|
||||
_cache.evict(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId());
|
||||
}
|
||||
|
||||
|
||||
Object obj = _cache.get(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId());
|
||||
if (obj == null)
|
||||
return false;
|
||||
|
||||
SessionData saved = (SessionData)obj;
|
||||
|
||||
if (saved instanceof InfinispanSessionData)
|
||||
{
|
||||
InfinispanSessionData isd = (InfinispanSessionData)saved;
|
||||
if (isd.getSerializedAttributes() != null)
|
||||
isd.deserializeAttributes();
|
||||
}
|
||||
|
||||
//turn an Entity into a Session
|
||||
assertEquals(data.getId(), saved.getId());
|
||||
|
@ -202,6 +222,7 @@ public class InfinispanTestSupport
|
|||
assertEquals(data.getExpiry(), saved.getExpiry());
|
||||
assertEquals(data.getMaxInactiveMs(), saved.getMaxInactiveMs());
|
||||
|
||||
|
||||
//same number of attributes
|
||||
assertEquals(data.getAllAttributes().size(), saved.getAllAttributes().size());
|
||||
//same keys
|
||||
|
|
|
@ -19,14 +19,17 @@
|
|||
package org.eclipse.jetty.server.session;
|
||||
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.session.infinispan.EmbeddedQueryManager;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionData;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStore;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionDataStoreFactory;
|
||||
import org.eclipse.jetty.session.infinispan.QueryManager;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDir;
|
||||
import org.eclipse.jetty.toolchain.test.jupiter.WorkDirExtension;
|
||||
import org.infinispan.query.Search;
|
||||
import org.infinispan.query.dsl.Query;
|
||||
import org.infinispan.query.dsl.QueryFactory;
|
||||
import org.infinispan.query.dsl.QueryResult;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -46,6 +49,11 @@ public class SerializedInfinispanSessionDataStoreTest extends AbstractSessionDat
|
|||
|
||||
public WorkDir workDir;
|
||||
|
||||
public SerializedInfinispanSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception
|
||||
{
|
||||
|
@ -65,13 +73,25 @@ public class SerializedInfinispanSessionDataStoreTest extends AbstractSessionDat
|
|||
{
|
||||
InfinispanSessionDataStoreFactory factory = new InfinispanSessionDataStoreFactory();
|
||||
factory.setCache(_testSupport.getCache());
|
||||
factory.setSerialization(true);
|
||||
QueryManager qm = new EmbeddedQueryManager(_testSupport.getCache());
|
||||
factory.setQueryManager(qm);
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void persistSession(SessionData data) throws Exception
|
||||
{
|
||||
_testSupport.createSession(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(_contextClassLoader);
|
||||
try
|
||||
{
|
||||
_testSupport.createSession(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -83,7 +103,16 @@ public class SerializedInfinispanSessionDataStoreTest extends AbstractSessionDat
|
|||
@Override
|
||||
public boolean checkSessionExists(SessionData data) throws Exception
|
||||
{
|
||||
return _testSupport.checkSessionExists(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return _testSupport.checkSessionExists(data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -96,6 +125,7 @@ public class SerializedInfinispanSessionDataStoreTest extends AbstractSessionDat
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -161,14 +191,17 @@ public class SerializedInfinispanSessionDataStoreTest extends AbstractSessionDat
|
|||
{
|
||||
InfinispanSessionData sd1 = new InfinispanSessionData("sd1", "", "", 0, 0, 0, 1000);
|
||||
sd1.setLastNode("fred1");
|
||||
sd1.serializeAttributes();
|
||||
_testSupport.getCache().put("session1", sd1);
|
||||
|
||||
InfinispanSessionData sd2 = new InfinispanSessionData("sd2", "", "", 0, 0, 0, 2000);
|
||||
sd2.setLastNode("fred2");
|
||||
sd2.serializeAttributes();
|
||||
_testSupport.getCache().put("session2", sd2);
|
||||
|
||||
InfinispanSessionData sd3 = new InfinispanSessionData("sd3", "", "", 0, 0, 0, 3000);
|
||||
sd3.setLastNode("fred3");
|
||||
sd3.serializeAttributes();
|
||||
_testSupport.getCache().put("session3", sd3);
|
||||
|
||||
QueryFactory qf = Search.getQueryFactory(_testSupport.getCache());
|
||||
|
@ -176,8 +209,9 @@ public class SerializedInfinispanSessionDataStoreTest extends AbstractSessionDat
|
|||
for (int i = 0; i <= 3; i++)
|
||||
{
|
||||
long now = System.currentTimeMillis();
|
||||
Query q = qf.from(InfinispanSessionData.class).having("expiry").lt(now).build();
|
||||
assertEquals(i, q.list().size());
|
||||
Query<InfinispanSessionData> q = qf.create("from org.eclipse.jetty.session.infinispan.InfinispanSessionData where expiry < " + now);
|
||||
QueryResult<InfinispanSessionData> result = q.execute();
|
||||
assertEquals(i, result.list().size());
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.eclipse.jetty.session.infinispan.RemoteQueryManager;
|
|||
import org.infinispan.client.hotrod.Search;
|
||||
import org.infinispan.query.dsl.Query;
|
||||
import org.infinispan.query.dsl.QueryFactory;
|
||||
import org.infinispan.query.dsl.QueryResult;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
@ -50,6 +51,11 @@ public class RemoteInfinispanSessionDataStoreTest extends AbstractSessionDataSto
|
|||
|
||||
public static RemoteInfinispanTestSupport __testSupport;
|
||||
|
||||
public RemoteInfinispanSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception
|
||||
{
|
||||
|
@ -75,7 +81,16 @@ public class RemoteInfinispanSessionDataStoreTest extends AbstractSessionDataSto
|
|||
@Override
|
||||
public void persistSession(SessionData data) throws Exception
|
||||
{
|
||||
__testSupport.createSession(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(_contextClassLoader);
|
||||
try
|
||||
{
|
||||
__testSupport.createSession((InfinispanSessionData)data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -87,7 +102,16 @@ public class RemoteInfinispanSessionDataStoreTest extends AbstractSessionDataSto
|
|||
@Override
|
||||
public boolean checkSessionExists(SessionData data) throws Exception
|
||||
{
|
||||
return __testSupport.checkSessionExists(data);
|
||||
ClassLoader old = Thread.currentThread().getContextClassLoader();
|
||||
Thread.currentThread().setContextClassLoader(_contextClassLoader);
|
||||
try
|
||||
{
|
||||
return __testSupport.checkSessionExists((InfinispanSessionData)data);
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(old);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -140,23 +164,29 @@ public class RemoteInfinispanSessionDataStoreTest extends AbstractSessionDataSto
|
|||
{
|
||||
InfinispanSessionData sd1 = new InfinispanSessionData("sd1", "", "", 0, 0, 0, 1000);
|
||||
sd1.setLastNode("fred1");
|
||||
sd1.serializeAttributes();
|
||||
__testSupport.getCache().put("session1", sd1);
|
||||
|
||||
InfinispanSessionData sd2 = new InfinispanSessionData("sd2", "", "", 0, 0, 0, 2000);
|
||||
sd2.setLastNode("fred2");
|
||||
sd2.serializeAttributes();
|
||||
__testSupport.getCache().put("session2", sd2);
|
||||
|
||||
InfinispanSessionData sd3 = new InfinispanSessionData("sd3", "", "", 0, 0, 0, 3000);
|
||||
sd3.setLastNode("fred3");
|
||||
sd3.serializeAttributes();
|
||||
__testSupport.getCache().put("session3", sd3);
|
||||
|
||||
QueryFactory qf = Search.getQueryFactory(__testSupport.getCache());
|
||||
Query<InfinispanSessionData> query = qf.create("from org_eclipse_jetty_session_infinispan.InfinispanSessionData where " +
|
||||
" expiry < :time");
|
||||
|
||||
for (int i = 0; i <= 3; i++)
|
||||
{
|
||||
long now = System.currentTimeMillis();
|
||||
Query q = qf.from(InfinispanSessionData.class).having("expiry").lt(now).build();
|
||||
assertEquals(i, q.list().size());
|
||||
query.setParameter("time", now);
|
||||
QueryResult<InfinispanSessionData> result = query.execute();
|
||||
assertEquals(i, result.list().size());
|
||||
Thread.sleep(1000);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ import java.lang.annotation.ElementType;
|
|||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.server.session.SessionData;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSerializationContextInitializer;
|
||||
import org.eclipse.jetty.session.infinispan.InfinispanSessionData;
|
||||
import org.eclipse.jetty.session.infinispan.SessionDataMarshaller;
|
||||
import org.eclipse.jetty.util.IO;
|
||||
import org.hibernate.search.cfg.Environment;
|
||||
import org.hibernate.search.cfg.SearchMapping;
|
||||
|
@ -34,9 +34,8 @@ import org.infinispan.client.hotrod.RemoteCacheManager;
|
|||
import org.infinispan.client.hotrod.configuration.ClientIntelligence;
|
||||
import org.infinispan.client.hotrod.configuration.Configuration;
|
||||
import org.infinispan.client.hotrod.configuration.ConfigurationBuilder;
|
||||
import org.infinispan.client.hotrod.marshall.ProtoStreamMarshaller;
|
||||
import org.infinispan.protostream.FileDescriptorSource;
|
||||
import org.infinispan.protostream.SerializationContext;
|
||||
import org.infinispan.commons.configuration.XMLStringConfiguration;
|
||||
import org.infinispan.commons.marshall.ProtoStreamMarshaller;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.testcontainers.containers.GenericContainer;
|
||||
|
@ -67,18 +66,18 @@ public class RemoteInfinispanTestSupport
|
|||
{
|
||||
//Testcontainers.exposeHostPorts(11222);
|
||||
long start = System.currentTimeMillis();
|
||||
String infinispanVersion = System.getProperty("infinispan.docker.image.version", "9.4.8.Final");
|
||||
String infinispanVersion = System.getProperty("infinispan.docker.image.version", "11.0.9.Final");
|
||||
infinispan =
|
||||
new GenericContainer(System.getProperty("infinispan.docker.image.name", "jboss/infinispan-server") +
|
||||
new GenericContainer(System.getProperty("infinispan.docker.image.name", "infinispan/server") +
|
||||
":" + infinispanVersion)
|
||||
.withEnv("APP_USER", "theuser")
|
||||
.withEnv("APP_PASS", "foobar")
|
||||
.withEnv("MGMT_USER", "admin")
|
||||
.withEnv("MGMT_PASS", "admin")
|
||||
.waitingFor(new LogMessageWaitStrategy()
|
||||
.withRegEx(".*Infinispan Server.*started in.*\\s"))
|
||||
.withExposedPorts(4712, 4713, 8088, 8089, 8443, 9990, 9993, 11211, 11222, 11223, 11224)
|
||||
.withLogConsumer(new Slf4jLogConsumer(INFINISPAN_LOG));
|
||||
.withEnv("USER", "theuser")
|
||||
.withEnv("PASS", "foobar")
|
||||
.withEnv("MGMT_USER", "admin")
|
||||
.withEnv("MGMT_PASS", "admin")
|
||||
.waitingFor(new LogMessageWaitStrategy()
|
||||
.withRegEx(".*Infinispan Server.*started in.*\\s"))
|
||||
.withExposedPorts(4712, 4713, 8088, 8089, 8443, 9990, 9993, 11211, 11222, 11223, 11224)
|
||||
.withLogConsumer(new Slf4jLogConsumer(INFINISPAN_LOG));
|
||||
infinispan.start();
|
||||
String host = infinispan.getContainerIpAddress();
|
||||
System.setProperty("hotrod.host", host);
|
||||
|
@ -103,23 +102,16 @@ public class RemoteInfinispanTestSupport
|
|||
if (infinispanVersion.startsWith("1"))
|
||||
{
|
||||
configurationBuilder.security().authentication()
|
||||
.realm("default")
|
||||
.serverName("infinispan")
|
||||
.saslMechanism("DIGEST-MD5")
|
||||
.username("theuser").password("foobar");
|
||||
}
|
||||
|
||||
|
||||
configurationBuilder.addContextInitializer(new InfinispanSerializationContextInitializer());
|
||||
Configuration configuration = configurationBuilder.build();
|
||||
|
||||
_manager = new RemoteCacheManager(configuration);
|
||||
|
||||
FileDescriptorSource fds = new FileDescriptorSource();
|
||||
fds.addProtoFiles("/session.proto");
|
||||
|
||||
SerializationContext serCtx = ProtoStreamMarshaller.getSerializationContext(_manager);
|
||||
serCtx.registerProtoFiles(fds);
|
||||
serCtx.registerMarshaller(new SessionDataMarshaller());
|
||||
|
||||
//upload the session.proto file to the remote cache
|
||||
ByteArrayOutputStream baos;
|
||||
try (InputStream is = RemoteInfinispanSessionDataStoreTest.class.getClassLoader().getResourceAsStream("session.proto"))
|
||||
{
|
||||
|
@ -160,7 +152,15 @@ public class RemoteInfinispanTestSupport
|
|||
|
||||
public void setup() throws Exception
|
||||
{
|
||||
_cache = _manager.administration().getOrCreateCache(_name, (String)null);
|
||||
String xml = String.format("<infinispan>" +
|
||||
"<cache-container>" + "<distributed-cache name=\"%s\" mode=\"SYNC\">" +
|
||||
"<encoding media-type=\"application/x-protostream\"/>" +
|
||||
"</distributed-cache>" +
|
||||
"</cache-container>" +
|
||||
"</infinispan>", _name);
|
||||
|
||||
XMLStringConfiguration xmlConfig = new XMLStringConfiguration(xml);
|
||||
_cache = _manager.administration().getOrCreateCache(_name, xmlConfig);
|
||||
}
|
||||
|
||||
public void teardown() throws Exception
|
||||
|
@ -171,12 +171,13 @@ public class RemoteInfinispanTestSupport
|
|||
public void createSession(SessionData data)
|
||||
throws Exception
|
||||
{
|
||||
((InfinispanSessionData)data).serializeAttributes();
|
||||
_cache.put(data.getContextPath() + "_" + data.getVhost() + "_" + data.getId(), data);
|
||||
}
|
||||
|
||||
public void createUnreadableSession(SessionData data)
|
||||
{
|
||||
|
||||
//Unused by test
|
||||
}
|
||||
|
||||
public boolean checkSessionExists(SessionData data)
|
||||
|
@ -193,7 +194,8 @@ public class RemoteInfinispanTestSupport
|
|||
return false;
|
||||
|
||||
InfinispanSessionData saved = (InfinispanSessionData)obj;
|
||||
saved.deserializeAttributes();
|
||||
if (saved.getSerializedAttributes() != null)
|
||||
saved.deserializeAttributes();
|
||||
|
||||
assertEquals(data.getId(), saved.getId());
|
||||
assertEquals(data.getContextPath(), saved.getContextPath());
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
org.slf4j.simpleLogger.defaultLogLevel=info
|
||||
org.slf4j.simpleLogger.log.org.eclipse.jetty.server.session.remote.infinispanLogs=info
|
||||
org.slf4j.simpleLogger.log.org.eclipse.jetty.server.session.remote.RemoteInfinispanTestSupport=info
|
||||
#org.slf4j.simpleLogger.log.org.eclipse.jetty.server.session=trace
|
||||
#org.slf4j.simpleLogger.log.org.eclipse.jetty.session.infinispan=trace
|
||||
|
|
|
@ -28,6 +28,10 @@ import org.testcontainers.junit.jupiter.Testcontainers;
|
|||
@Testcontainers(disabledWithoutDocker = true)
|
||||
public class JDBCSessionDataStoreTest extends AbstractSessionDataStoreTest
|
||||
{
|
||||
public JDBCSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() throws Exception
|
||||
|
|
|
@ -44,6 +44,10 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
|||
@Testcontainers(disabledWithoutDocker = true)
|
||||
public class MongoSessionDataStoreTest extends AbstractSessionDataStoreTest
|
||||
{
|
||||
public MongoSessionDataStoreTest() throws Exception
|
||||
{
|
||||
super();
|
||||
}
|
||||
|
||||
@BeforeEach
|
||||
public void beforeEach() throws Exception
|
||||
|
|
|
@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit;
|
|||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.toolchain.test.IO;
|
||||
import org.eclipse.jetty.toolchain.test.MavenTestingUtils;
|
||||
import org.junit.jupiter.api.BeforeAll;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.hamcrest.MatcherAssert.assertThat;
|
||||
|
@ -59,8 +60,8 @@ public abstract class AbstractSessionDataStoreTest
|
|||
*/
|
||||
public static final long ANCIENT_TIMESTAMP = 100L;
|
||||
public static final long RECENT_TIMESTAMP = System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(3 * GRACE_PERIOD_SEC);
|
||||
|
||||
protected URLClassLoader _contextClassLoader = new URLClassLoader(new URL[]{}, Thread.currentThread().getContextClassLoader());
|
||||
protected static File extraClasses;
|
||||
protected URLClassLoader _contextClassLoader;
|
||||
|
||||
public abstract SessionDataStoreFactory createSessionDataStoreFactory();
|
||||
|
||||
|
@ -72,6 +73,40 @@ public abstract class AbstractSessionDataStoreTest
|
|||
|
||||
public abstract boolean checkSessionPersisted(SessionData data) throws Exception;
|
||||
|
||||
@BeforeAll
|
||||
public static void beforeAll()
|
||||
throws Exception
|
||||
{
|
||||
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Foo.clazz");
|
||||
extraClasses = new File(MavenTestingUtils.getTargetDir(), "extraClasses");
|
||||
extraClasses.mkdirs();
|
||||
File fooclass = new File(extraClasses, "Foo.class");
|
||||
IO.copy(is, new FileOutputStream(fooclass));
|
||||
is.close();
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Proxyable.clazz");
|
||||
File proxyableClass = new File(extraClasses, "Proxyable.class");
|
||||
IO.copy(is, new FileOutputStream(proxyableClass));
|
||||
is.close();
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("ProxyableInvocationHandler.clazz");
|
||||
File pihClass = new File(extraClasses, "ProxyableInvocationHandler.class");
|
||||
IO.copy(is, new FileOutputStream(pihClass));
|
||||
is.close();
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("ProxyableFactory.clazz");
|
||||
File factoryClass = new File(extraClasses, "ProxyableFactory.class");
|
||||
IO.copy(is, new FileOutputStream(factoryClass));
|
||||
is.close();
|
||||
|
||||
}
|
||||
|
||||
public AbstractSessionDataStoreTest() throws Exception
|
||||
{
|
||||
URL[] foodirUrls = new URL[]{extraClasses.toURI().toURL()};
|
||||
_contextClassLoader = new URLClassLoader(foodirUrls, Thread.currentThread().getContextClassLoader());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that the store can persist a session. The session uses an attribute
|
||||
* class that is only known to the webapp classloader. This tests that
|
||||
|
@ -80,19 +115,6 @@ public abstract class AbstractSessionDataStoreTest
|
|||
@Test
|
||||
public void testStoreSession() throws Exception
|
||||
{
|
||||
//Use a class that would only be known to the webapp classloader
|
||||
InputStream foostream = Thread.currentThread().getContextClassLoader().getResourceAsStream("Foo.clazz");
|
||||
File foodir = new File(MavenTestingUtils.getTargetDir(), "foo");
|
||||
foodir.mkdirs();
|
||||
File fooclass = new File(foodir, "Foo.class");
|
||||
IO.copy(foostream, new FileOutputStream(fooclass));
|
||||
|
||||
assertTrue(fooclass.exists());
|
||||
assertTrue(fooclass.length() != 0);
|
||||
|
||||
URL[] foodirUrls = new URL[]{foodir.toURI().toURL()};
|
||||
_contextClassLoader = new URLClassLoader(foodirUrls, Thread.currentThread().getContextClassLoader());
|
||||
|
||||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
|
@ -165,6 +187,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -182,14 +205,15 @@ public abstract class AbstractSessionDataStoreTest
|
|||
|
||||
//put it into the store
|
||||
persistSession(data);
|
||||
|
||||
|
||||
assertTrue(checkSessionExists(data));
|
||||
|
||||
//now test we can update the session
|
||||
data.setLastAccessed(now - 1);
|
||||
data.setAccessed(now);
|
||||
data.setMaxInactiveMs(TimeUnit.MINUTES.toMillis(2));
|
||||
data.setAttribute("a", "c");
|
||||
store.store("1234", data);
|
||||
|
||||
assertTrue(checkSessionPersisted(data));
|
||||
}
|
||||
|
||||
|
@ -200,36 +224,6 @@ public abstract class AbstractSessionDataStoreTest
|
|||
@Test
|
||||
public void testStoreObjectAttributes() throws Exception
|
||||
{
|
||||
|
||||
//Use classes that would only be known to the webapp classloader
|
||||
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Proxyable.clazz");
|
||||
File proxyabledir = new File(MavenTestingUtils.getTargetDir(), "proxyable");
|
||||
proxyabledir.mkdirs();
|
||||
File proxyableClass = new File(proxyabledir, "Proxyable.class");
|
||||
IO.copy(is, new FileOutputStream(proxyableClass));
|
||||
is.close();
|
||||
|
||||
assertTrue(proxyableClass.exists());
|
||||
assertTrue(proxyableClass.length() != 0);
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("ProxyableInvocationHandler.clazz");
|
||||
File pihClass = new File(proxyabledir, "ProxyableInvocationHandler.class");
|
||||
IO.copy(is, new FileOutputStream(pihClass));
|
||||
is.close();
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("ProxyableFactory.clazz");
|
||||
File factoryClass = new File(proxyabledir, "ProxyableFactory.class");
|
||||
IO.copy(is, new FileOutputStream(factoryClass));
|
||||
is.close();
|
||||
|
||||
is = Thread.currentThread().getContextClassLoader().getResourceAsStream("Foo.clazz");
|
||||
File fooClass = new File(proxyabledir, "Foo.class");
|
||||
IO.copy(is, new FileOutputStream(fooClass));
|
||||
is.close();
|
||||
|
||||
URL[] proxyabledirUrls = new URL[]{proxyabledir.toURI().toURL()};
|
||||
_contextClassLoader = new URLClassLoader(proxyabledirUrls, Thread.currentThread().getContextClassLoader());
|
||||
|
||||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
|
@ -314,6 +308,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -347,6 +342,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -381,6 +377,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -402,6 +399,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -439,6 +437,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -466,6 +465,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -502,6 +502,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -532,6 +533,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -553,6 +555,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -588,6 +591,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -622,6 +626,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -645,6 +650,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -681,6 +687,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -709,6 +716,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -735,6 +743,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -761,6 +770,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -778,6 +788,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
SessionDataStore store = factory.getSessionDataStore(context.getSessionHandler());
|
||||
|
@ -806,6 +817,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
((AbstractSessionDataStoreFactory)factory).setSavePeriodSec(20); //only save every 20sec
|
||||
|
@ -846,6 +858,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
((AbstractSessionDataStoreFactory)factory).setSavePeriodSec(20); //only save every 20sec
|
||||
|
@ -875,6 +888,7 @@ public abstract class AbstractSessionDataStoreTest
|
|||
//create the SessionDataStore
|
||||
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
|
||||
context.setContextPath("/test");
|
||||
context.setClassLoader(_contextClassLoader);
|
||||
SessionDataStoreFactory factory = createSessionDataStoreFactory();
|
||||
((AbstractSessionDataStoreFactory)factory).setGracePeriodSec(GRACE_PERIOD_SEC);
|
||||
((AbstractSessionDataStoreFactory)factory).setSavePeriodSec(20); //only save every 20sec
|
||||
|
|
Loading…
Reference in New Issue