From 4aed1f33772a685689ff48af9e178dd62951a112 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Fri, 8 Oct 2021 10:49:20 +1100 Subject: [PATCH] Cherry pick update to infinispan 11.0.11 back to jetty-9.4.x(#6766) (#6889) * Issue #6687 Update to infinispan 11.0.11 Signed-off-by: Jan Bartel Co-authored-by: Olivier Lamy --- jetty-home/pom.xml | 10 + jetty-infinispan/infinispan-common/pom.xml | 9 +- .../sessions/infinispan/infinispan-common.xml | 1 + ...nispanSerializationContextInitializer.java | 51 ++++ .../infinispan/InfinispanSessionData.java | 1 - .../InfinispanSessionDataStore.java | 22 +- .../InfinispanSessionDataStoreFactory.java | 12 + .../infinispan/SessionDataMarshaller.java | 46 +--- .../session/infinispan/WebAppMarshaller.java | 78 ------ .../infinispan-embedded-query/pom.xml | 1 - .../infinispan/EmbeddedQueryManager.java | 23 +- .../infinispan/EmbeddedQueryManagerTest.java | 6 +- jetty-infinispan/infinispan-embedded/pom.xml | 7 +- .../session-store-infinispan-embedded.mod | 1 + .../infinispan-remote-query/pom.xml | 10 +- .../infinispan/infinispan-remote-query.xml | 43 +--- .../modules/infinispan-remote-query.mod | 4 - .../remote/other_proto_marshallers.xml | 38 --- .../infinispan/RemoteQueryManager.java | 25 +- .../infinispan/RemoteQueryManagerFactory.java | 1 - .../infinispan/RemoteQueryManagerTest.java | 132 ++++++---- jetty-infinispan/infinispan-remote/pom.xml | 2 - .../sessions/infinispan/infinispan-remote.xml | 36 +-- .../session-store-infinispan-remote.mod | 2 +- .../remote/resources/hotrod-client.properties | 1 + .../jetty/server/session/SessionData.java | 3 +- pom.xml | 40 ++- tests/test-distribution/pom.xml | 9 + .../InfinispanSessionDistributionTests.java | 227 ++++++++++++++++++ .../session/FileSessionDataStoreTest.java | 5 + .../session/GCloudSessionDataStoreTest.java | 5 + .../HazelcastSessionDataStoreTest.java | 4 + .../client/HazelcastSessionDataStoreTest.java | 4 + .../test-infinispan-sessions/pom.xml | 17 +- ...steredSerializedSessionScavengingTest.java | 1 + .../ClusteredSessionScavengingTest.java | 1 + .../InfinispanFileSessionDataStoreTest.java | 19 +- .../InfinispanSessionDataStoreTest.java | 39 ++- .../server/session/InfinispanTestSupport.java | 41 +++- ...ializedInfinispanSessionDataStoreTest.java | 42 +++- .../RemoteInfinispanSessionDataStoreTest.java | 38 ++- .../remote/RemoteInfinispanTestSupport.java | 56 ++--- .../test/resources/simplelogger.properties | 2 + .../session/JDBCSessionDataStoreTest.java | 4 + .../mongodb/MongoSessionDataStoreTest.java | 4 + .../session/AbstractSessionDataStoreTest.java | 108 +++++---- 46 files changed, 812 insertions(+), 419 deletions(-) create mode 100644 jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java delete mode 100644 jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java delete mode 100644 jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/sessions/infinispan/remote/other_proto_marshallers.xml create mode 100644 tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/InfinispanSessionDistributionTests.java diff --git a/jetty-home/pom.xml b/jetty-home/pom.xml index 3f562733736..08882507dd2 100644 --- a/jetty-home/pom.xml +++ b/jetty-home/pom.xml @@ -722,22 +722,32 @@ infinispan-embedded ${project.version} pom + true org.eclipse.jetty infinispan-embedded-query ${project.version} + true org.eclipse.jetty infinispan-remote ${project.version} pom + true + + + org.wildfly.common + * + + org.eclipse.jetty infinispan-remote-query ${project.version} + true org.eclipse.jetty diff --git a/jetty-infinispan/infinispan-common/pom.xml b/jetty-infinispan/infinispan-common/pom.xml index 32671671c9b..78261d768aa 100644 --- a/jetty-infinispan/infinispan-common/pom.xml +++ b/jetty-infinispan/infinispan-common/pom.xml @@ -37,8 +37,13 @@ org.infinispan infinispan-core - ${infinispan.version} true + + + org.wildfly.common + wildfly-common + + org.infinispan.protostream @@ -55,13 +60,11 @@ org.infinispan infinispan-client-hotrod - ${infinispan.version} provided org.infinispan infinispan-remote-query-client - ${infinispan.version} provided diff --git a/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml b/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml index 6745e570497..9aa43e27281 100644 --- a/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml +++ b/jetty-infinispan/infinispan-common/src/main/config/etc/sessions/infinispan/infinispan-common.xml @@ -9,6 +9,7 @@ + diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java new file mode 100644 index 00000000000..352ac535775 --- /dev/null +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSerializationContextInitializer.java @@ -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()); + } +} diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java index b88b088c134..5f5969c1db3 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionData.java @@ -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; diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java index 7669b1ac794..d672a62b287 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStore.java @@ -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() diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java index 9a5bf4b4ae2..4b422b1fb43 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/InfinispanSessionDataStoreFactory.java @@ -32,6 +32,7 @@ public class InfinispanSessionDataStoreFactory extends AbstractSessionDataStoreF int _infinispanIdleTimeoutSec; BasicCache _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; + } } diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java index 1a6b0a4cfdb..2f2d6cae900 100644 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java +++ b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/SessionDataMarshaller.java @@ -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, Externalizer +public class SessionDataMarshaller implements MessageMarshaller { /** * 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()); } diff --git a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java b/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java deleted file mode 100644 index 05154241e5b..00000000000 --- a/jetty-infinispan/infinispan-common/src/main/java/org/eclipse/jetty/session/infinispan/WebAppMarshaller.java +++ /dev/null @@ -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()); - } -} diff --git a/jetty-infinispan/infinispan-embedded-query/pom.xml b/jetty-infinispan/infinispan-embedded-query/pom.xml index 74405af66a9..79da2fcd0b7 100644 --- a/jetty-infinispan/infinispan-embedded-query/pom.xml +++ b/jetty-infinispan/infinispan-embedded-query/pom.xml @@ -89,7 +89,6 @@ org.infinispan infinispan-query - ${infinispan.version} org.eclipse.jetty.toolchain diff --git a/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java b/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java index 621d003d185..5247abf31e1 100644 --- a/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java +++ b/jetty-infinispan/infinispan-embedded-query/src/main/java/org/eclipse/jetty/session/infinispan/EmbeddedQueryManager.java @@ -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 _cache; + private QueryFactory _factory; public EmbeddedQueryManager(Cache cache) { _cache = cache; + _factory = Search.getQueryFactory(_cache); } @Override public Set queryExpiredSessions(long time) { - QueryFactory qf = Search.getQueryFactory(_cache); - Query q = qf.from(SessionData.class).select("id").having("expiry").lte(time).build(); - - List list = q.list(); - Set ids = new HashSet<>(); - for (Object[] sl : list) - { - ids.add((String)sl[0]); - } + Query 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 list = result.list(); + Set ids = list.stream().map(a -> (String)a[0]).collect(toSet()); return ids; } diff --git a/jetty-infinispan/infinispan-embedded-query/src/test/java/org/eclipse/jetty/server/session/infinispan/EmbeddedQueryManagerTest.java b/jetty-infinispan/infinispan-embedded-query/src/test/java/org/eclipse/jetty/server/session/infinispan/EmbeddedQueryManagerTest.java index 6b760866449..9dda1c89d8f 100644 --- a/jetty-infinispan/infinispan-embedded-query/src/test/java/org/eclipse/jetty/server/session/infinispan/EmbeddedQueryManagerTest.java +++ b/jetty-infinispan/infinispan-embedded-query/src/test/java/org/eclipse/jetty/server/session/infinispan/EmbeddedQueryManagerTest.java @@ -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); diff --git a/jetty-infinispan/infinispan-embedded/pom.xml b/jetty-infinispan/infinispan-embedded/pom.xml index 172b1b2e785..6f23b452fd3 100644 --- a/jetty-infinispan/infinispan-embedded/pom.xml +++ b/jetty-infinispan/infinispan-embedded/pom.xml @@ -81,7 +81,12 @@ org.infinispan infinispan-core - ${infinispan.version} + + + org.wildfly.common + wildfly-common + + diff --git a/jetty-infinispan/infinispan-embedded/src/main/config-template/modules/session-store-infinispan-embedded.mod b/jetty-infinispan/infinispan-embedded/src/main/config-template/modules/session-store-infinispan-embedded.mod index bff64cdba50..b6ed7e0ee09 100644 --- a/jetty-infinispan/infinispan-embedded/src/main/config-template/modules/session-store-infinispan-embedded.mod +++ b/jetty-infinispan/infinispan-embedded/src/main/config-template/modules/session-store-infinispan-embedded.mod @@ -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 diff --git a/jetty-infinispan/infinispan-remote-query/pom.xml b/jetty-infinispan/infinispan-remote-query/pom.xml index a1cafcba393..ea3a6cde0a9 100644 --- a/jetty-infinispan/infinispan-remote-query/pom.xml +++ b/jetty-infinispan/infinispan-remote-query/pom.xml @@ -9,7 +9,7 @@ Jetty :: Infinispan Session Manager Remote ${project.groupId}.infinispan.remote.query - 9.4.8.Final + 11.0.9.Final @@ -99,17 +99,19 @@ org.infinispan infinispan-query - ${infinispan.version} org.infinispan infinispan-client-hotrod - ${infinispan.version} org.infinispan infinispan-remote-query-client - ${infinispan.version} + + + com.google.code.gson + gson + ${gson.version} org.slf4j diff --git a/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml b/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml index 5df051b455a..f714abf95e4 100644 --- a/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml +++ b/jetty-infinispan/infinispan-remote-query/src/main/config-template/etc/sessions/infinispan/infinispan-remote-query.xml @@ -7,7 +7,7 @@ - org.eclipse.jetty.server.session.SessionData + org.eclipse.jetty.session.infinispan.InfinispanSessionData @@ -33,20 +33,25 @@ - + - + - + + + + + + @@ -57,42 +62,16 @@ - - - - - - - - - - - - - - /session.proto - - - - - - - - - - - - - + - + diff --git a/jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/infinispan-remote-query.mod b/jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/infinispan-remote-query.mod index 7cb7c40ec30..f1e266d9f21 100644 --- a/jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/infinispan-remote-query.mod +++ b/jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/infinispan-remote-query.mod @@ -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 diff --git a/jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/sessions/infinispan/remote/other_proto_marshallers.xml b/jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/sessions/infinispan/remote/other_proto_marshallers.xml deleted file mode 100644 index 312ac64549c..00000000000 --- a/jetty-infinispan/infinispan-remote-query/src/main/config-template/modules/sessions/infinispan/remote/other_proto_marshallers.xml +++ /dev/null @@ -1,38 +0,0 @@ - - - - - - - - - - - - - - - - diff --git a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java index d592bad325e..8bb4c8499cf 100644 --- a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java +++ b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManager.java @@ -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 _cache; + private QueryFactory _factory; public RemoteQueryManager(RemoteCache cache) { _cache = cache; + _factory = Search.getQueryFactory(_cache); } @Override public Set 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 list = q.list(); - Set ids = new HashSet<>(); - for (Object[] sl : list) - { - ids.add((String)sl[0]); - } - + Query 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 list = result.list(); + Set ids = list.stream().map(a -> (String)a[0]).collect(toSet()); return ids; } diff --git a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java index 750aec2564b..e12e3f044dd 100644 --- a/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java +++ b/jetty-infinispan/infinispan-remote-query/src/main/java/org/eclipse/jetty/session/infinispan/RemoteQueryManagerFactory.java @@ -28,7 +28,6 @@ public class RemoteQueryManagerFactory implements QueryManagerFactory @Override public QueryManager getQueryManager(BasicCache cache) { - System.err.println(cache.getClass().getName()); if (!RemoteCache.class.isAssignableFrom(cache.getClass())) throw new IllegalArgumentException("Argument is not of type RemoteCache"); diff --git a/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java b/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java index fbcdaf88800..1c59e00f745 100644 --- a/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java +++ b/jetty-infinispan/infinispan-remote-query/src/test/java/org/eclipse/jetty/server/session/infinispan/RemoteQueryManagerTest.java @@ -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("" + + "" + "" + + "" + + "" + + "" + + "", DEFAULT_CACHE_NAME); + XMLStringConfiguration xmlConfig = new XMLStringConfiguration(xml); + RemoteCache 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 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 barSessions = createSessions(cache, barSessionContext); - RemoteCache 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 expiredSessions = new HashSet<>(); - Random r = new Random(); + private Set createSessions(RemoteCache cache, SessionContext sessionContext) throws Exception + { + Set 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 cache, SessionContext sessionContext, int time, Set sessions) + { QueryManager qm = new RemoteQueryManager(cache); - Set queryResult = qm.queryExpiredSessions(currentTime); - - // Check that the result is correct - assertEquals(expiredSessions.size(), queryResult.size()); - for (String s : expiredSessions) + Set queryResult = qm.queryExpiredSessions(time); + + Set 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())); } + } } diff --git a/jetty-infinispan/infinispan-remote/pom.xml b/jetty-infinispan/infinispan-remote/pom.xml index f6901c6d85b..7648ba04fbe 100644 --- a/jetty-infinispan/infinispan-remote/pom.xml +++ b/jetty-infinispan/infinispan-remote/pom.xml @@ -81,13 +81,11 @@ org.infinispan infinispan-client-hotrod - ${infinispan.version} provided org.infinispan infinispan-remote-query-client - ${infinispan.version} provided diff --git a/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml b/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml index fa10e9b2387..3f2a48cf54f 100644 --- a/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml +++ b/jetty-infinispan/infinispan-remote/src/main/config-template/etc/sessions/infinispan/infinispan-remote.xml @@ -24,7 +24,12 @@ - + + + + + + @@ -37,35 +42,6 @@ - - - - - - - - - - - - - - - /session.proto - - - - - - - - - - - - - - diff --git a/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod b/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod index dc1a043119e..e9c6b75039f 100644 --- a/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod +++ b/jetty-infinispan/infinispan-remote/src/main/config-template/modules/session-store-infinispan-remote.mod @@ -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 diff --git a/jetty-infinispan/infinispan-remote/src/main/config-template/modules/sessions/infinispan/remote/resources/hotrod-client.properties b/jetty-infinispan/infinispan-remote/src/main/config-template/modules/sessions/infinispan/remote/resources/hotrod-client.properties index bb774cd9c52..44edf0748fe 100644 --- a/jetty-infinispan/infinispan-remote/src/main/config-template/modules/sessions/infinispan/remote/resources/hotrod-client.properties +++ b/jetty-infinispan/infinispan-remote/src/main/config-template/modules/sessions/infinispan/remote/resources/hotrod-client.properties @@ -1 +1,2 @@ #infinispan.client.hotrod.server_list +#infinispan.client.hotrod.context-initializers= diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java index 978d3d8a66d..7c4b8f73fd8 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/session/SessionData.java @@ -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); diff --git a/pom.xml b/pom.xml index 23bc00716ed..7871f2c9f5d 100644 --- a/pom.xml +++ b/pom.xml @@ -39,7 +39,7 @@ 5.0.1 2.14.0 3.12.12 - 9.4.8.Final + 11.0.11.Final 4.3.4.Final 2.82 1.1.0.v201105071233 @@ -1000,6 +1000,39 @@ jna ${jna.version} + + org.infinispan + infinispan-bom + ${infinispan.version} + pom + import + + + + org.jboss.logging + jboss-logging + ${jboss.logging.version} + + + org.jboss.logging + jboss-logging-processor + 2.2.1.Final + + + org.jboss.logging + jboss-logging-annotations + 2.2.1.Final + + + org.jboss.logmanager + jboss-logmanager + 2.1.15.Final + + + org.jboss.threads + jboss-threads + 3.1.0.Final + org.eclipse.jetty.toolchain @@ -1031,11 +1064,6 @@ slf4j-simple ${slf4j.version} - - org.jboss.logging - jboss-logging - ${jboss.logging.version} - com.github.jnr jnr-enxio diff --git a/tests/test-distribution/pom.xml b/tests/test-distribution/pom.xml index 18ea6f1636c..3c153c94403 100644 --- a/tests/test-distribution/pom.xml +++ b/tests/test-distribution/pom.xml @@ -150,6 +150,12 @@ test war + + org.eclipse.jetty + infinispan-remote-query + ${project.version} + test + org.testcontainers testcontainers @@ -168,6 +174,9 @@ ${project.version} ${hazelcast.version} $(distribution.debug.port} + ${home.start.timeout} + ${mariadb.version} + ${sessionLogLevel} diff --git a/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/InfinispanSessionDistributionTests.java b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/InfinispanSessionDistributionTests.java new file mode 100644 index 00000000000..e33050b7b97 --- /dev/null +++ b/tests/test-distribution/src/test/java/org/eclipse/jetty/tests/distribution/InfinispanSessionDistributionTests.java @@ -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("" + + "" + "" + + "" + + "" + + "" + + "", "sessions"); + + XMLStringConfiguration xmlConfig = new XMLStringConfiguration(xml); + RemoteCache 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(); + } + } +} diff --git a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java index d97b03a301f..9023adc4be1 100644 --- a/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java +++ b/tests/test-sessions/test-file-sessions/src/test/java/org/eclipse/jetty/server/session/FileSessionDataStoreTest.java @@ -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 diff --git a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java index b9b0b43c620..5b3bd648ffd 100644 --- a/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java +++ b/tests/test-sessions/test-gcloud-sessions/src/test/java/org/eclipse/jetty/gcloud/session/GCloudSessionDataStoreTest.java @@ -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 diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java index a5bd5f0f9c2..e5fe7cab55f 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/HazelcastSessionDataStoreTest.java @@ -37,6 +37,10 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class HazelcastSessionDataStoreTest extends AbstractSessionDataStoreTest { + public HazelcastSessionDataStoreTest() throws Exception + { + super(); + } HazelcastTestHelper _testHelper; diff --git a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java index f9d8ddb2f24..8dbad44433f 100644 --- a/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java +++ b/tests/test-sessions/test-hazelcast-sessions/src/test/java/org/eclipse/jetty/hazelcast/session/client/HazelcastSessionDataStoreTest.java @@ -39,6 +39,10 @@ import static org.junit.jupiter.api.Assertions.fail; */ public class HazelcastSessionDataStoreTest extends AbstractSessionDataStoreTest { + public HazelcastSessionDataStoreTest() throws Exception + { + super(); + } HazelcastTestHelper _testHelper; diff --git a/tests/test-sessions/test-infinispan-sessions/pom.xml b/tests/test-sessions/test-infinispan-sessions/pom.xml index 4c299d8b7b5..89a148a1e22 100644 --- a/tests/test-sessions/test-infinispan-sessions/pom.xml +++ b/tests/test-sessions/test-infinispan-sessions/pom.xml @@ -11,9 +11,9 @@ ${project.groupId}.sessions.infinispan - ${infinispan.version} + 11.0.9.Final - jboss/infinispan-server + infinispan/server @@ -87,10 +87,17 @@ test-sessions-common ${project.version} + + org.eclipse.jetty + infinispan-embedded-query + ${project.version} + test + org.eclipse.jetty infinispan-remote-query ${project.version} + test org.eclipse.jetty @@ -108,6 +115,12 @@ infinispan-core ${infinispan.version} test + + + org.wildfly.common + wildfly-common + + org.infinispan diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSerializedSessionScavengingTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSerializedSessionScavengingTest.java index 5746425d6da..652e345f212 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSerializedSessionScavengingTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSerializedSessionScavengingTest.java @@ -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; } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java index 7e92f975bec..5a218f532b6 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/ClusteredSessionScavengingTest.java @@ -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; } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanFileSessionDataStoreTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanFileSessionDataStoreTest.java index d79408d1280..650cc7da5b5 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanFileSessionDataStoreTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanFileSessionDataStoreTest.java @@ -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; + } } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java index 9b7a85e258e..4adc0ab4e87 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanSessionDataStoreTest.java @@ -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 q = qf.create("from org.eclipse.jetty.session.infinispan.InfinispanSessionData where expiry < " + now); + QueryResult result = q.execute(); + assertEquals(i, result.list().size()); Thread.sleep(1000); } } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java index 663e8ddca39..35294ac3067 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/InfinispanTestSupport.java @@ -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 diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SerializedInfinispanSessionDataStoreTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SerializedInfinispanSessionDataStoreTest.java index 898c37bb7ce..0b8bcc3d64d 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SerializedInfinispanSessionDataStoreTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/SerializedInfinispanSessionDataStoreTest.java @@ -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 q = qf.create("from org.eclipse.jetty.session.infinispan.InfinispanSessionData where expiry < " + now); + QueryResult result = q.execute(); + assertEquals(i, result.list().size()); Thread.sleep(1000); } } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java index 532e4731f1d..a29b508b873 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanSessionDataStoreTest.java @@ -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 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 result = query.execute(); + assertEquals(i, result.list().size()); Thread.sleep(1000); } } diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java index ba9723420d2..bad63828f5e 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java +++ b/tests/test-sessions/test-infinispan-sessions/src/test/java/org/eclipse/jetty/server/session/remote/RemoteInfinispanTestSupport.java @@ -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("" + + "" + "" + + "" + + "" + + "" + + "", _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()); diff --git a/tests/test-sessions/test-infinispan-sessions/src/test/resources/simplelogger.properties b/tests/test-sessions/test-infinispan-sessions/src/test/resources/simplelogger.properties index cc6528beeee..e0718a50a56 100644 --- a/tests/test-sessions/test-infinispan-sessions/src/test/resources/simplelogger.properties +++ b/tests/test-sessions/test-infinispan-sessions/src/test/resources/simplelogger.properties @@ -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 diff --git a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java index 242d330c3af..17dbf792637 100644 --- a/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java +++ b/tests/test-sessions/test-jdbc-sessions/src/test/java/org/eclipse/jetty/server/session/JDBCSessionDataStoreTest.java @@ -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 diff --git a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java index 791b6a05399..3fed6c3881c 100644 --- a/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java +++ b/tests/test-sessions/test-mongodb-sessions/src/test/java/org/eclipse/jetty/nosql/mongodb/MongoSessionDataStoreTest.java @@ -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 diff --git a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java index 377931e74ec..2a303512542 100644 --- a/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java +++ b/tests/test-sessions/test-sessions-common/src/main/java/org/eclipse/jetty/server/session/AbstractSessionDataStoreTest.java @@ -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