From b3f6495864804ecad98227aa0b3a28d345beab57 Mon Sep 17 00:00:00 2001 From: Paul Ferraro Date: Sun, 3 Mar 2024 11:56:35 -0500 Subject: [PATCH] Upgrade wildfly-clustering to 1.0.7.Final. --- context/core/pom.xml | 2 +- .../SessionManagementConfiguration.java | 3 +- .../InfinispanSessionManagerFactoryBean.java | 11 +- .../remote/HotRodConfiguration.java | 1 - .../HotRodSessionManagerFactoryBean.java | 19 +-- .../remote/MutableHotRodConfiguration.java | 2 - .../config/HotRodConfigurationBean.java | 11 -- pom.xml | 6 +- session/core/pom.xml | 11 ++ .../ImmutableSessionDestroyAction.java | 8 +- .../session/JakartaServletFacadeProvider.java | 147 ------------------ .../config/HttpSessionConfiguration.java | 16 +- .../session/AbstractSessionSmokeITCase.java | 6 - .../session/servlet/SessionServlet.java | 47 ++++-- session/infinispan/embedded/pom.xml | 7 + .../embedded/UserConfigurationBean.java | 6 +- ...actInfinispanHttpSessionConfiguration.java | 2 +- .../AbstractInfinispanSessionSmokeITCase.java | 10 -- .../InfinispanSessionAuthSmokeITCase.java | 13 +- session/infinispan/remote/pom.xml | 6 + .../remote/UserConfigurationBean.java | 6 +- ...bstractHotRodHttpSessionConfiguration.java | 13 +- .../AbstractHotRodSessionSmokeITCase.java | 9 -- .../remote/HotRodSessionAuthSmokeITCase.java | 13 +- web/core/pom.xml | 7 + .../web/JakartaServletFacadeProvider.java | 147 ------------------ .../web/config/WebSessionConfiguration.java | 48 ++++-- .../spring/web/AbstractSmokeITCase.java | 123 ++------------- .../spring/web/AbstractWebSmokeITCase.java | 6 - .../spring/web/SmokeITParameters.java | 17 -- .../spring/web/context/ReactiveConfig.java | 4 +- .../spring/web/context/SessionHandler.java | 34 +++- web/infinispan/embedded/pom.xml | 7 + .../InfinispanWebSessionConfiguration.java | 2 +- .../AbstractInfinispanWebSmokeITCase.java | 6 - web/infinispan/remote/pom.xml | 6 + .../config/HotRodWebSessionConfiguration.java | 13 +- .../remote/AbstractHotRodWebSmokeITCase.java | 5 - 38 files changed, 212 insertions(+), 588 deletions(-) delete mode 100644 session/core/src/main/java/org/wildfly/clustering/spring/session/JakartaServletFacadeProvider.java delete mode 100644 web/core/src/main/java/org/wildfly/clustering/spring/web/JakartaServletFacadeProvider.java delete mode 100644 web/core/src/test/java/org/wildfly/clustering/spring/web/SmokeITParameters.java diff --git a/context/core/pom.xml b/context/core/pom.xml index 4a85c56..01f74b2 100644 --- a/context/core/pom.xml +++ b/context/core/pom.xml @@ -42,7 +42,7 @@ org.wildfly.clustering - wildfly-clustering-session-spi + wildfly-clustering-session-spec-spi diff --git a/context/core/src/main/java/org/wildfly/clustering/spring/context/config/SessionManagementConfiguration.java b/context/core/src/main/java/org/wildfly/clustering/spring/context/config/SessionManagementConfiguration.java index b4a6e3f..e10ad48 100644 --- a/context/core/src/main/java/org/wildfly/clustering/spring/context/config/SessionManagementConfiguration.java +++ b/context/core/src/main/java/org/wildfly/clustering/spring/context/config/SessionManagementConfiguration.java @@ -29,6 +29,7 @@ import org.wildfly.clustering.session.SessionManagerConfiguration; import org.wildfly.clustering.session.SessionManagerFactory; import org.wildfly.clustering.session.SessionManagerFactoryConfiguration; +import org.wildfly.clustering.session.spec.SessionSpecificationProvider; import org.wildfly.clustering.spring.context.SessionManagerBean; import org.wildfly.clustering.spring.context.SessionMarshallerFactory; import org.wildfly.common.function.Functions; @@ -37,7 +38,7 @@ * Spring configuration bean for a distributable session repository. * @author Paul Ferraro */ -public abstract class SessionManagementConfiguration implements SessionManagerFactoryConfiguration, SessionManagerConfiguration, EnvironmentAware, ImportAware, ResourceLoaderAware, Consumer { +public abstract class SessionManagementConfiguration implements SessionManagerFactoryConfiguration, SessionManagerConfiguration, EnvironmentAware, ImportAware, ResourceLoaderAware, Consumer, Supplier> { private final Class annotationClass; diff --git a/context/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/context/infinispan/embedded/InfinispanSessionManagerFactoryBean.java b/context/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/context/infinispan/embedded/InfinispanSessionManagerFactoryBean.java index c1575bc..896c262 100644 --- a/context/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/context/infinispan/embedded/InfinispanSessionManagerFactoryBean.java +++ b/context/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/context/infinispan/embedded/InfinispanSessionManagerFactoryBean.java @@ -32,6 +32,7 @@ import org.wildfly.clustering.session.infinispan.embedded.InfinispanSessionManagerFactory; import org.wildfly.clustering.session.infinispan.embedded.InfinispanSessionManagerFactoryConfiguration; import org.wildfly.clustering.session.infinispan.embedded.metadata.SessionMetaDataKey; +import org.wildfly.clustering.session.spec.SessionSpecificationProvider; import org.wildfly.clustering.spring.context.AutoDestroyBean; /** @@ -39,16 +40,18 @@ */ public class InfinispanSessionManagerFactoryBean extends AutoDestroyBean implements SessionManagerFactory, InitializingBean { - private final SessionManagerFactoryConfiguration configuration; + private final SessionManagerFactoryConfiguration configuration; + private final SessionSpecificationProvider provider; private final InfinispanConfiguration infinispan; private final ChannelEmbeddedCacheManagerCommandDispatcherFactoryConfiguration embeddedCacheManagerConfiguration; private SessionManagerFactory sessionManagerFactory; - public InfinispanSessionManagerFactoryBean(SessionManagerFactoryConfiguration configuration, InfinispanConfiguration infinispan, ChannelEmbeddedCacheManagerCommandDispatcherFactoryConfiguration embeddedCacheManagerConfiguration) { + public InfinispanSessionManagerFactoryBean(SessionManagerFactoryConfiguration configuration, SessionSpecificationProvider provider, InfinispanConfiguration infinispan, ChannelEmbeddedCacheManagerCommandDispatcherFactoryConfiguration embeddedCacheManagerConfiguration) { + this.configuration = configuration; + this.provider = provider; this.infinispan = infinispan; this.embeddedCacheManagerConfiguration = embeddedCacheManagerConfiguration; - this.configuration = configuration; } @Override @@ -120,7 +123,7 @@ public CacheContainerCommandDispatcherFactory getCommandDispatcherFactory() { } }; - this.sessionManagerFactory = new InfinispanSessionManagerFactory<>(this.configuration, infinispanConfiguration); + this.sessionManagerFactory = new InfinispanSessionManagerFactory<>(this.configuration, this.provider, infinispanConfiguration); this.accept(this.sessionManagerFactory::close); } diff --git a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodConfiguration.java b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodConfiguration.java index 5476f35..304f22a 100644 --- a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodConfiguration.java +++ b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodConfiguration.java @@ -15,5 +15,4 @@ public interface HotRodConfiguration { URI getUri(); Properties getProperties(); String getTemplateName(); - int getExpirationThreadPoolSize(); } diff --git a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodSessionManagerFactoryBean.java b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodSessionManagerFactoryBean.java index 29a00dd..eb39f94 100644 --- a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodSessionManagerFactoryBean.java +++ b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/HotRodSessionManagerFactoryBean.java @@ -13,12 +13,13 @@ import org.infinispan.client.hotrod.configuration.TransactionMode; import org.springframework.beans.factory.InitializingBean; import org.wildfly.clustering.cache.infinispan.batch.TransactionBatch; +import org.wildfly.clustering.cache.infinispan.remote.RemoteCacheConfiguration; import org.wildfly.clustering.session.SessionManager; import org.wildfly.clustering.session.SessionManagerConfiguration; import org.wildfly.clustering.session.SessionManagerFactory; import org.wildfly.clustering.session.SessionManagerFactoryConfiguration; -import org.wildfly.clustering.session.infinispan.remote.HotRodSessionFactoryConfiguration; import org.wildfly.clustering.session.infinispan.remote.HotRodSessionManagerFactory; +import org.wildfly.clustering.session.spec.SessionSpecificationProvider; import org.wildfly.clustering.spring.context.AutoDestroyBean; /** @@ -26,14 +27,16 @@ */ public class HotRodSessionManagerFactoryBean extends AutoDestroyBean implements SessionManagerFactory, InitializingBean { - private final SessionManagerFactoryConfiguration configuration; + private final SessionManagerFactoryConfiguration configuration; + private final SessionSpecificationProvider specProvider; private final HotRodConfiguration hotrod; private final RemoteCacheContainerProvider provider; private SessionManagerFactory sessionManagerFactory; - public HotRodSessionManagerFactoryBean(SessionManagerFactoryConfiguration configuration, HotRodConfiguration hotrod, RemoteCacheContainerProvider provider) { + public HotRodSessionManagerFactoryBean(SessionManagerFactoryConfiguration configuration, SessionSpecificationProvider specProvider, HotRodConfiguration hotrod, RemoteCacheContainerProvider provider) { this.hotrod = hotrod; + this.specProvider = specProvider; this.provider = provider; this.configuration = configuration; } @@ -47,18 +50,12 @@ public void afterPropertiesSet() throws Exception { container.getConfiguration().addRemoteCache(deploymentName, builder -> builder.forceReturnValues(false).nearCacheMode(maxActiveSessions.isEmpty() ? NearCacheMode.DISABLED : NearCacheMode.INVALIDATED).transactionMode(TransactionMode.NONE).templateName(templateName)); - int expirationThreadPoolSize = this.hotrod.getExpirationThreadPoolSize(); RemoteCache cache = container.getCache(deploymentName); cache.start(); this.accept(cache::stop); - HotRodSessionFactoryConfiguration hotrodConfiguration = new HotRodSessionFactoryConfiguration() { - @Override - public int getExpirationThreadPoolSize() { - return expirationThreadPoolSize; - } - + RemoteCacheConfiguration hotrodConfiguration = new RemoteCacheConfiguration() { @SuppressWarnings("unchecked") @Override public RemoteCache getCache() { @@ -66,7 +63,7 @@ public RemoteCache getCache() { } }; - this.sessionManagerFactory = new HotRodSessionManagerFactory<>(this.configuration, hotrodConfiguration); + this.sessionManagerFactory = new HotRodSessionManagerFactory<>(this.configuration, this.specProvider, hotrodConfiguration); this.accept(this.sessionManagerFactory::close); } diff --git a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/MutableHotRodConfiguration.java b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/MutableHotRodConfiguration.java index 3e30c3b..0326f06 100644 --- a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/MutableHotRodConfiguration.java +++ b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/MutableHotRodConfiguration.java @@ -27,6 +27,4 @@ default void setProperties(Properties properties) { void setProperty(String name, String value); void setTemplateName(String templateName); - - void setExpirationThreadPoolSize(int size); } diff --git a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/config/HotRodConfigurationBean.java b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/config/HotRodConfigurationBean.java index e7c53ff..630a12c 100644 --- a/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/config/HotRodConfigurationBean.java +++ b/context/infinispan/remote/src/main/java/org/wildfly/clustering/spring/context/infinispan/remote/config/HotRodConfigurationBean.java @@ -20,7 +20,6 @@ public class HotRodConfigurationBean implements MutableHotRodConfiguration { private URI uri; private Properties properties = new Properties(); private String templateName = DefaultTemplate.DIST_SYNC.getTemplateName(); - private int expirationThreadPoolSize = 16; private StringValueResolver resolver = value -> value; @Override @@ -43,11 +42,6 @@ public String getTemplateName() { return this.templateName; } - @Override - public int getExpirationThreadPoolSize() { - return this.expirationThreadPoolSize; - } - @Override public void setUri(String uri) { this.uri = URI.create(this.resolver.resolveStringValue(uri)); @@ -63,11 +57,6 @@ public void setTemplateName(String templateName) { this.templateName = this.resolver.resolveStringValue(templateName); } - @Override - public void setExpirationThreadPoolSize(int size) { - this.expirationThreadPoolSize = size; - } - @Override public void accept(AnnotationAttributes attributes) { AnnotationAttributes config = attributes.getAnnotation("config"); diff --git a/pom.xml b/pom.xml index e66ac87..dd8d76a 100644 --- a/pom.xml +++ b/pom.xml @@ -36,20 +36,20 @@ 1.11 - 3.6.2 + 3.6.3 6.1.4 6.2.2 3.2.1 14.0.25.Final 2.1.4.Final - 1.0.6.Final + 1.0.7.Final 10.1.19 1.8.0.Final 1.1.0.Final 5.10.2 - 5.10.0 + 5.11.0 1.19.6 diff --git a/session/core/pom.xml b/session/core/pom.xml index 8e87813..9c754c1 100644 --- a/session/core/pom.xml +++ b/session/core/pom.xml @@ -41,6 +41,10 @@ org.springframework.session spring-session-core + + org.wildfly.clustering + wildfly-clustering-session-spec-servlet-6.0 + org.springframework.security @@ -55,6 +59,13 @@ test + + org.wildfly.clustering + wildfly-clustering-session-spi + tests + test + + org.infinispan.protostream protostream-processor diff --git a/session/core/src/main/java/org/wildfly/clustering/spring/session/ImmutableSessionDestroyAction.java b/session/core/src/main/java/org/wildfly/clustering/spring/session/ImmutableSessionDestroyAction.java index fe73f5b..1a8de3a 100644 --- a/session/core/src/main/java/org/wildfly/clustering/spring/session/ImmutableSessionDestroyAction.java +++ b/session/core/src/main/java/org/wildfly/clustering/spring/session/ImmutableSessionDestroyAction.java @@ -10,6 +10,7 @@ import jakarta.servlet.ServletContext; import jakarta.servlet.http.HttpSession; +import jakarta.servlet.http.HttpSessionActivationListener; import jakarta.servlet.http.HttpSessionBindingEvent; import jakarta.servlet.http.HttpSessionBindingListener; @@ -18,6 +19,7 @@ import org.springframework.session.Session; import org.wildfly.clustering.cache.batch.Batch; import org.wildfly.clustering.session.ImmutableSession; +import org.wildfly.clustering.session.spec.SessionSpecificationProvider; import org.wildfly.clustering.session.user.User; import org.wildfly.clustering.session.user.UserManager; @@ -28,11 +30,13 @@ public class ImmutableSessionDestroyAction implements BiConsume private final ApplicationEventPublisher publisher; private final ServletContext context; + private final SessionSpecificationProvider provider; private final UserConfiguration indexing; - public ImmutableSessionDestroyAction(ApplicationEventPublisher publisher, ServletContext context, UserConfiguration indexing) { + public ImmutableSessionDestroyAction(ApplicationEventPublisher publisher, ServletContext context, SessionSpecificationProvider provider, UserConfiguration indexing) { this.publisher = publisher; this.context = context; + this.provider = provider; this.indexing = indexing; } @@ -40,7 +44,7 @@ public ImmutableSessionDestroyAction(ApplicationEventPublisher publisher, Servle public void accept(ImmutableSession session, BiFunction eventFactory) { ApplicationEvent event = eventFactory.apply(this, new DistributableImmutableSession(session)); this.publisher.publishEvent(event); - HttpSession httpSession = JakartaServletFacadeProvider.INSTANCE.asSession(session, this.context); + HttpSession httpSession = this.provider.asSession(session, this.context); for (Map.Entry entry : session.getAttributes().getAttributes(HttpSessionBindingListener.class).entrySet()) { HttpSessionBindingListener listener = entry.getValue(); try { diff --git a/session/core/src/main/java/org/wildfly/clustering/spring/session/JakartaServletFacadeProvider.java b/session/core/src/main/java/org/wildfly/clustering/spring/session/JakartaServletFacadeProvider.java deleted file mode 100644 index 4c97637..0000000 --- a/session/core/src/main/java/org/wildfly/clustering/spring/session/JakartaServletFacadeProvider.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.clustering.spring.session; - -import java.util.Collections; -import java.util.Enumeration; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Consumer; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpSession; -import jakarta.servlet.http.HttpSessionActivationListener; -import jakarta.servlet.http.HttpSessionEvent; - -import org.wildfly.clustering.session.ImmutableSession; -import org.wildfly.clustering.session.container.ContainerFacadeProvider; - -/** - * @author Paul Ferraro - */ -public enum JakartaServletFacadeProvider implements ContainerFacadeProvider { - INSTANCE; - - @Override - public HttpSession asSession(ImmutableSession session, ServletContext context) { - return new HttpSession() { - @Override - public String getId() { - return session.getId(); - } - - @Override - public ServletContext getServletContext() { - return context; - } - - @Override - public boolean isNew() { - return session.getMetaData().isNew(); - } - - @Override - public long getCreationTime() { - return session.getMetaData().getCreationTime().toEpochMilli(); - } - - @Override - public long getLastAccessedTime() { - return session.getMetaData().getLastAccessStartTime().toEpochMilli(); - } - - @Override - public int getMaxInactiveInterval() { - return (int) session.getMetaData().getTimeout().getSeconds(); - } - - @Override - public Enumeration getAttributeNames() { - return Collections.enumeration(session.getAttributes().getAttributeNames()); - } - - @Override - public Object getAttribute(String name) { - return session.getAttributes().getAttribute(name); - } - - @Override - public void setAttribute(String name, Object value) { - // Ignore - } - - @Override - public void removeAttribute(String name) { - // Ignore - } - - @Override - public void invalidate() { - // Ignore - } - - @Override - public void setMaxInactiveInterval(int interval) { - // Ignore - } - - @Override - public int hashCode() { - return this.getId().hashCode(); - } - - @Override - public boolean equals(Object object) { - if (!(object instanceof HttpSession session)) return false; - return Objects.equals(this.getId(), session.getId()) && Objects.equals(this.getServletContext().getVirtualServerName(), session.getServletContext().getVirtualServerName()) && Objects.equals(this.getServletContext().getContextPath(), session.getServletContext().getContextPath()); - } - - @Override - public String toString() { - return this.getId(); - } - }; - } - - @Override - public Optional asSessionActivationListener(Object attribute) { - return Optional.ofNullable(attribute).filter(HttpSessionActivationListener.class::isInstance).map(HttpSessionActivationListener.class::cast); - } - - @Override - public Consumer prePassivateNotifier(HttpSessionActivationListener listener) { - return new Consumer<>() { - @Override - public void accept(HttpSession session) { - listener.sessionWillPassivate(new HttpSessionEvent(session)); - } - }; - } - - @Override - public Consumer postActivateNotifier(HttpSessionActivationListener listener) { - return new Consumer<>() { - @Override - public void accept(HttpSession session) { - listener.sessionDidActivate(new HttpSessionEvent(session)); - } - }; - } - - @Override - public HttpSessionActivationListener asSessionActivationListener(Consumer prePassivate, Consumer postActivate) { - return new HttpSessionActivationListener() { - @Override - public void sessionWillPassivate(HttpSessionEvent event) { - prePassivate.accept(event.getSession()); - } - - @Override - public void sessionDidActivate(HttpSessionEvent event) { - postActivate.accept(event.getSession()); - } - }; - } -} diff --git a/session/core/src/main/java/org/wildfly/clustering/spring/session/config/HttpSessionConfiguration.java b/session/core/src/main/java/org/wildfly/clustering/spring/session/config/HttpSessionConfiguration.java index 3d85250..a74a86e 100644 --- a/session/core/src/main/java/org/wildfly/clustering/spring/session/config/HttpSessionConfiguration.java +++ b/session/core/src/main/java/org/wildfly/clustering/spring/session/config/HttpSessionConfiguration.java @@ -36,13 +36,13 @@ import org.wildfly.clustering.server.immutable.Immutability; import org.wildfly.clustering.session.ImmutableSession; import org.wildfly.clustering.session.SessionManager; -import org.wildfly.clustering.session.container.ContainerFacadeProvider; +import org.wildfly.clustering.session.spec.SessionSpecificationProvider; +import org.wildfly.clustering.session.spec.servlet.JakartaServletSpecificationProvider; import org.wildfly.clustering.spring.context.config.SessionManagementConfiguration; import org.wildfly.clustering.spring.security.SpringSecurityImmutability; import org.wildfly.clustering.spring.session.DistributableSessionRepository; import org.wildfly.clustering.spring.session.DistributableSessionRepositoryConfiguration; import org.wildfly.clustering.spring.session.ImmutableSessionDestroyAction; -import org.wildfly.clustering.spring.session.JakartaServletFacadeProvider; import org.wildfly.clustering.spring.session.MutableIndexingConfiguration; import org.wildfly.clustering.spring.session.SpringSession; import org.wildfly.clustering.spring.session.UserConfiguration; @@ -70,9 +70,14 @@ protected HttpSessionConfiguration(Class annotationClass, this.indexResolver = defaultIndexResolver; } + @Override + public SessionSpecificationProvider get() { + return JakartaServletSpecificationProvider.INSTANCE; + } + @Bean public FindByIndexNameSessionRepository sessionRepository(SessionManager manager, UserConfiguration userConfiguration) { - BiConsumer> sessionDestroyAction = new ImmutableSessionDestroyAction<>(this.publisher, this.getContext(), userConfiguration); + BiConsumer> sessionDestroyAction = new ImmutableSessionDestroyAction<>(this.publisher, this.getContext(), this.get(), userConfiguration); DistributableSessionRepositoryConfiguration configuration = new DistributableSessionRepositoryConfiguration<>() { @Override public SessionManager getSessionManager() { @@ -132,11 +137,6 @@ public IndexResolver getIndexResolver() { return this.indexResolver; } - @Override - public ContainerFacadeProvider getContainerFacadeProvider() { - return JakartaServletFacadeProvider.INSTANCE; - } - @Override public String getServerName() { return this.getContext().getVirtualServerName(); diff --git a/session/core/src/test/java/org/wildfly/clustering/spring/session/AbstractSessionSmokeITCase.java b/session/core/src/test/java/org/wildfly/clustering/spring/session/AbstractSessionSmokeITCase.java index b5067d8..c335361 100644 --- a/session/core/src/test/java/org/wildfly/clustering/spring/session/AbstractSessionSmokeITCase.java +++ b/session/core/src/test/java/org/wildfly/clustering/spring/session/AbstractSessionSmokeITCase.java @@ -5,8 +5,6 @@ package org.wildfly.clustering.spring.session; -import java.net.http.HttpClient; - import org.jboss.shrinkwrap.api.spec.WebArchive; import org.wildfly.clustering.spring.session.context.SpringSessionFilter; import org.wildfly.clustering.spring.session.servlet.SessionServlet; @@ -23,8 +21,4 @@ protected static WebArchive deployment(Class test .addPackage(SpringSessionFilter.class.getPackage()) ; } - - protected AbstractSessionSmokeITCase(HttpClient.Builder builder) { - super(builder); - } } diff --git a/session/core/src/test/java/org/wildfly/clustering/spring/session/servlet/SessionServlet.java b/session/core/src/test/java/org/wildfly/clustering/spring/session/servlet/SessionServlet.java index 8cec444..64744a1 100644 --- a/session/core/src/test/java/org/wildfly/clustering/spring/session/servlet/SessionServlet.java +++ b/session/core/src/test/java/org/wildfly/clustering/spring/session/servlet/SessionServlet.java @@ -5,6 +5,7 @@ package org.wildfly.clustering.spring.session.servlet; import java.io.IOException; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import jakarta.servlet.ServletException; @@ -14,12 +15,12 @@ import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; -import org.wildfly.clustering.spring.web.SmokeITParameters; +import org.wildfly.clustering.session.container.SessionManagementEndpointConfiguration; /** * @author Paul Ferraro */ -@WebServlet(SmokeITParameters.ENDPOINT_PATH) +@WebServlet(SessionManagementEndpointConfiguration.ENDPOINT_PATH) public class SessionServlet extends HttpServlet { private static final long serialVersionUID = 2878267318695777395L; @@ -28,32 +29,48 @@ protected void service(HttpServletRequest request, HttpServletResponse response) String query = request.getQueryString(); this.getServletContext().log(String.format("[%s] %s%s", request.getMethod(), request.getRequestURI(), (query != null) ? '?' + query : "")); super.service(request, response); + + HttpSession session = request.getSession(false); + if (session != null) { + response.setHeader(SessionManagementEndpointConfiguration.SESSION_ID, session.getId()); + } } @Override - public void doHead(HttpServletRequest request, HttpServletResponse response) throws IOException { + public void doHead(HttpServletRequest request, HttpServletResponse response) { + recordSession(request, response, AtomicInteger::get); + } + + @Override + public void doGet(HttpServletRequest request, HttpServletResponse response) { + recordSession(request, response, AtomicInteger::incrementAndGet); + } + + private static void recordSession(HttpServletRequest request, HttpServletResponse response, java.util.function.ToIntFunction count) { HttpSession session = request.getSession(false); if (session != null) { - response.setHeader(SmokeITParameters.SESSION_ID, session.getId()); - AtomicInteger value = (AtomicInteger) session.getAttribute(SmokeITParameters.VALUE); + AtomicInteger counter = (AtomicInteger) session.getAttribute(SessionManagementEndpointConfiguration.COUNTER); + if (counter != null) { + response.setIntHeader(SessionManagementEndpointConfiguration.COUNTER, count.applyAsInt(counter)); + } + UUID value = (UUID) session.getAttribute(SessionManagementEndpointConfiguration.IMMUTABLE); if (value != null) { - response.setIntHeader(SmokeITParameters.VALUE, value.get()); + response.setHeader(SessionManagementEndpointConfiguration.IMMUTABLE, value.toString()); } } } @Override - public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { - HttpSession session = request.getSession(); - response.setHeader(SmokeITParameters.SESSION_ID, session.getId()); + protected void doPut(HttpServletRequest request, HttpServletResponse response) { + HttpSession session = request.getSession(true); - AtomicInteger value = (AtomicInteger) session.getAttribute(SmokeITParameters.VALUE); - if (value == null) { - value = new AtomicInteger(0); - session.setAttribute(SmokeITParameters.VALUE, value); - } + UUID immutableValue = UUID.randomUUID(); + session.setAttribute(SessionManagementEndpointConfiguration.IMMUTABLE, immutableValue); + response.addHeader(SessionManagementEndpointConfiguration.IMMUTABLE, immutableValue.toString()); - response.setIntHeader(SmokeITParameters.VALUE, value.incrementAndGet()); + AtomicInteger counter = new AtomicInteger(0); + session.setAttribute(SessionManagementEndpointConfiguration.COUNTER, counter); + response.addIntHeader(SessionManagementEndpointConfiguration.COUNTER, counter.get()); } @Override diff --git a/session/infinispan/embedded/pom.xml b/session/infinispan/embedded/pom.xml index 9814aaf..eb79845 100644 --- a/session/infinispan/embedded/pom.xml +++ b/session/infinispan/embedded/pom.xml @@ -50,6 +50,13 @@ test + + org.wildfly.clustering + wildfly-clustering-session-spi + tests + test + + org.jboss.arquillian.container arquillian-tomcat-managed-8 diff --git a/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/UserConfigurationBean.java b/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/UserConfigurationBean.java index 9175110..3923eb6 100644 --- a/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/UserConfigurationBean.java +++ b/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/UserConfigurationBean.java @@ -10,8 +10,6 @@ import java.util.function.Supplier; import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpSession; -import jakarta.servlet.http.HttpSessionActivationListener; import org.infinispan.Cache; import org.infinispan.configuration.cache.ConfigurationBuilder; @@ -40,12 +38,12 @@ public class UserConfigurationBean extends AutoDestroyBean implements UserConfiguration, InitializingBean { private final Map> managers = new TreeMap<>(); - private final SessionManagerFactoryConfiguration sessionManagerFactoryConfiguration; + private final SessionManagerFactoryConfiguration sessionManagerFactoryConfiguration; private final SessionManagerConfiguration sessionManagerConfiguration; private final IndexingConfiguration indexing; private final EmbeddedCacheContainerConfiguration infinispan; - public UserConfigurationBean(SessionManagerFactoryConfiguration managerFactoryConfiguration, SessionManagerConfiguration managerConfiguration, IndexingConfiguration indexing, EmbeddedCacheContainerConfiguration infinispan) { + public UserConfigurationBean(SessionManagerFactoryConfiguration managerFactoryConfiguration, SessionManagerConfiguration managerConfiguration, IndexingConfiguration indexing, EmbeddedCacheContainerConfiguration infinispan) { this.sessionManagerFactoryConfiguration = managerFactoryConfiguration; this.sessionManagerConfiguration = managerConfiguration; this.indexing = indexing; diff --git a/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/config/AbstractInfinispanHttpSessionConfiguration.java b/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/config/AbstractInfinispanHttpSessionConfiguration.java index 4c919c0..a07c12a 100644 --- a/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/config/AbstractInfinispanHttpSessionConfiguration.java +++ b/session/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/session/infinispan/embedded/config/AbstractInfinispanHttpSessionConfiguration.java @@ -43,7 +43,7 @@ public ChannelEmbeddedCacheManagerCommandDispatcherFactoryConfiguration embedded @Bean public SessionManagerFactory sessionManagerFactory(ChannelEmbeddedCacheManagerCommandDispatcherFactoryConfiguration embeddedCacheManagerConfiguration) { - return new InfinispanSessionManagerFactoryBean<>(this, this.configuration, embeddedCacheManagerConfiguration); + return new InfinispanSessionManagerFactoryBean<>(this, this.get(), this.configuration, embeddedCacheManagerConfiguration); } @Override diff --git a/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/AbstractInfinispanSessionSmokeITCase.java b/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/AbstractInfinispanSessionSmokeITCase.java index 29bf561..b8df66a 100644 --- a/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/AbstractInfinispanSessionSmokeITCase.java +++ b/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/AbstractInfinispanSessionSmokeITCase.java @@ -5,8 +5,6 @@ package org.wildfly.clustering.spring.session.infinispan.embedded; -import java.net.http.HttpClient; - import org.jboss.shrinkwrap.api.spec.WebArchive; import org.wildfly.clustering.spring.session.AbstractSessionSmokeITCase; import org.wildfly.clustering.spring.web.AbstractSmokeITCase; @@ -21,12 +19,4 @@ protected static WebArchive deployment(Class test .addAsWebInfResource(AbstractInfinispanSessionSmokeITCase.class.getPackage(), "infinispan.xml", "infinispan.xml") ; } - - protected AbstractInfinispanSessionSmokeITCase() { - this(HttpClient.newBuilder()); - } - - protected AbstractInfinispanSessionSmokeITCase(HttpClient.Builder builder) { - super(builder); - } } diff --git a/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/InfinispanSessionAuthSmokeITCase.java b/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/InfinispanSessionAuthSmokeITCase.java index 162e1e6..9f84cd2 100644 --- a/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/InfinispanSessionAuthSmokeITCase.java +++ b/session/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/session/infinispan/embedded/InfinispanSessionAuthSmokeITCase.java @@ -8,9 +8,11 @@ import java.net.PasswordAuthentication; import java.net.URI; import java.net.http.HttpClient; +import java.net.http.HttpClient.Builder; import java.net.http.HttpRequest; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; +import java.util.function.UnaryOperator; import jakarta.servlet.http.HttpServletResponse; @@ -24,10 +26,10 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.ExtendWith; +import org.wildfly.clustering.session.container.SessionManagementEndpointConfiguration; import org.wildfly.clustering.spring.session.authentication.SecurityInitializer; import org.wildfly.clustering.spring.session.infinispan.embedded.authentication.ConfigContextLoaderListener; import org.wildfly.clustering.spring.session.servlet.SessionServlet; -import org.wildfly.clustering.spring.web.SmokeITParameters; /** * @author Paul Ferraro @@ -54,13 +56,14 @@ private static Archive deployment() { ; } - public InfinispanSessionAuthSmokeITCase() { - super(HttpClient.newBuilder().authenticator(new Authenticator() { + @Override + public UnaryOperator getHttpClientConfigurator() { + return builder -> builder.authenticator(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("admin", "password".toCharArray()); } - })); + }); } @ArquillianResource(SessionServlet.class) @@ -74,7 +77,7 @@ protected PasswordAuthentication getPasswordAuthentication() { @Test @RunAsClient public void test() throws Exception { - URI uri1 = this.baseURI1.resolve(SmokeITParameters.ENDPOINT_NAME); + URI uri1 = this.baseURI1.resolve(SessionManagementEndpointConfiguration.ENDPOINT_NAME); // Verify that authentication is required HttpResponse response = HttpClient.newHttpClient().send(HttpRequest.newBuilder(uri1).build(), BodyHandlers.discarding()); Assertions.assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.statusCode()); diff --git a/session/infinispan/remote/pom.xml b/session/infinispan/remote/pom.xml index d73b3cb..d2867fe 100644 --- a/session/infinispan/remote/pom.xml +++ b/session/infinispan/remote/pom.xml @@ -62,6 +62,12 @@ tests test + + org.wildfly.clustering + wildfly-clustering-session-spi + tests + test + org.jboss.arquillian.container diff --git a/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/UserConfigurationBean.java b/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/UserConfigurationBean.java index a056411..6ddbc17 100644 --- a/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/UserConfigurationBean.java +++ b/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/UserConfigurationBean.java @@ -10,8 +10,6 @@ import java.util.function.Supplier; import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpSession; -import jakarta.servlet.http.HttpSessionActivationListener; import org.infinispan.client.hotrod.RemoteCache; import org.infinispan.client.hotrod.RemoteCacheContainer; @@ -45,7 +43,7 @@ public class UserConfigurationBean extends AutoDestroyBean implements UserConfiguration, InitializingBean, ApplicationContextAware { private final Map> managers = new TreeMap<>(); - private final SessionManagerFactoryConfiguration managerFactoryConfiguration; + private final SessionManagerFactoryConfiguration managerFactoryConfiguration; private final SessionManagerConfiguration managerConfiguration; private final IndexingConfiguration indexing; private final HotRodConfiguration hotrod; @@ -53,7 +51,7 @@ public class UserConfigurationBean extends AutoDestroyBean implements UserConfig private ApplicationContext context; - public UserConfigurationBean(SessionManagerFactoryConfiguration managerFactoryConfiguration, SessionManagerConfiguration managerConfiguration, IndexingConfiguration indexing, HotRodConfiguration hotrod, RemoteCacheContainerProvider provider) { + public UserConfigurationBean(SessionManagerFactoryConfiguration managerFactoryConfiguration, SessionManagerConfiguration managerConfiguration, IndexingConfiguration indexing, HotRodConfiguration hotrod, RemoteCacheContainerProvider provider) { this.managerFactoryConfiguration = managerFactoryConfiguration; this.managerConfiguration = managerConfiguration; this.indexing = indexing; diff --git a/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/config/AbstractHotRodHttpSessionConfiguration.java b/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/config/AbstractHotRodHttpSessionConfiguration.java index 7f2a868..4a7d226 100644 --- a/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/config/AbstractHotRodHttpSessionConfiguration.java +++ b/session/infinispan/remote/src/main/java/org/wildfly/clustering/spring/session/infinispan/remote/config/AbstractHotRodHttpSessionConfiguration.java @@ -45,7 +45,7 @@ public RemoteCacheContainerProvider remoteCacheManagerProvider() { @Bean public SessionManagerFactory sessionManagerFactory(RemoteCacheContainerProvider provider) { - return new HotRodSessionManagerFactoryBean<>(this, this.configuration, provider); + return new HotRodSessionManagerFactoryBean<>(this, this.get(), this.configuration, provider); } @Override @@ -68,11 +68,6 @@ public String getTemplateName() { return this.configuration.getTemplateName(); } - @Override - public int getExpirationThreadPoolSize() { - return this.configuration.getExpirationThreadPoolSize(); - } - @Override @Autowired(required = false) public void setUri(String uri) { @@ -96,12 +91,6 @@ public void setTemplateName(String templateName) { this.configuration.setTemplateName(templateName); } - @Override - @Autowired(required = false) - public void setExpirationThreadPoolSize(int size) { - this.configuration.setExpirationThreadPoolSize(size); - } - @Override public void accept(AnnotationAttributes attributes) { super.accept(attributes); diff --git a/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/AbstractHotRodSessionSmokeITCase.java b/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/AbstractHotRodSessionSmokeITCase.java index 25ee57f..1818513 100644 --- a/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/AbstractHotRodSessionSmokeITCase.java +++ b/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/AbstractHotRodSessionSmokeITCase.java @@ -5,7 +5,6 @@ package org.wildfly.clustering.spring.session.infinispan.remote; -import java.net.http.HttpClient; import java.util.Properties; import org.infinispan.client.hotrod.DefaultTemplate; @@ -41,12 +40,4 @@ protected static WebArchive deployment(Class test .addAsWebInfResource(new PropertiesAsset(properties), "classes/application.properties") ; } - - protected AbstractHotRodSessionSmokeITCase() { - super(HttpClient.newBuilder()); - } - - protected AbstractHotRodSessionSmokeITCase(HttpClient.Builder builder) { - super(builder); - } } diff --git a/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/HotRodSessionAuthSmokeITCase.java b/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/HotRodSessionAuthSmokeITCase.java index ee1608e..0f2a28f 100644 --- a/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/HotRodSessionAuthSmokeITCase.java +++ b/session/infinispan/remote/src/test/java/org/wildfly/clustering/spring/session/infinispan/remote/HotRodSessionAuthSmokeITCase.java @@ -26,10 +26,12 @@ import java.net.PasswordAuthentication; import java.net.URI; import java.net.http.HttpClient; +import java.net.http.HttpClient.Builder; import java.net.http.HttpRequest; import java.net.http.HttpRequest.BodyPublishers; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; +import java.util.function.UnaryOperator; import jakarta.servlet.http.HttpServletResponse; @@ -43,10 +45,10 @@ import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; +import org.wildfly.clustering.session.container.SessionManagementEndpointConfiguration; import org.wildfly.clustering.spring.session.authentication.SecurityInitializer; import org.wildfly.clustering.spring.session.infinispan.remote.authentication.ConfigContextLoaderListener; import org.wildfly.clustering.spring.session.servlet.SessionServlet; -import org.wildfly.clustering.spring.web.SmokeITParameters; /** * @author Paul Ferraro @@ -75,13 +77,14 @@ private static Archive deployment() { ; } - public HotRodSessionAuthSmokeITCase() { - super(HttpClient.newBuilder().authenticator(new Authenticator() { + @Override + public UnaryOperator getHttpClientConfigurator() { + return builder -> builder.authenticator(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("admin", "password".toCharArray()); } - })); + }); } @ArquillianResource(SessionServlet.class) @@ -95,7 +98,7 @@ protected PasswordAuthentication getPasswordAuthentication() { @Test @RunAsClient public void test() throws Exception { - URI uri1 = this.baseURI1.resolve(SmokeITParameters.ENDPOINT_NAME); + URI uri1 = this.baseURI1.resolve(SessionManagementEndpointConfiguration.ENDPOINT_NAME); // Verify that authentication is required HttpResponse response = HttpClient.newHttpClient().send(HttpRequest.newBuilder(uri1).method("HEAD", BodyPublishers.noBody()).build(), BodyHandlers.discarding()); Assertions.assertEquals(HttpServletResponse.SC_UNAUTHORIZED, response.statusCode()); diff --git a/web/core/pom.xml b/web/core/pom.xml index 84e5f04..ed5cf38 100644 --- a/web/core/pom.xml +++ b/web/core/pom.xml @@ -43,6 +43,13 @@ runtime + + org.wildfly.clustering + wildfly-clustering-session-spi + tests + test + + org.jboss.shrinkwrap shrinkwrap-api diff --git a/web/core/src/main/java/org/wildfly/clustering/spring/web/JakartaServletFacadeProvider.java b/web/core/src/main/java/org/wildfly/clustering/spring/web/JakartaServletFacadeProvider.java deleted file mode 100644 index 0a03a84..0000000 --- a/web/core/src/main/java/org/wildfly/clustering/spring/web/JakartaServletFacadeProvider.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ -package org.wildfly.clustering.spring.web; - -import java.util.Collections; -import java.util.Enumeration; -import java.util.Objects; -import java.util.Optional; -import java.util.function.Consumer; - -import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpSession; -import jakarta.servlet.http.HttpSessionActivationListener; -import jakarta.servlet.http.HttpSessionEvent; - -import org.wildfly.clustering.session.ImmutableSession; -import org.wildfly.clustering.session.container.ContainerFacadeProvider; - -/** - * @author Paul Ferraro - */ -public enum JakartaServletFacadeProvider implements ContainerFacadeProvider { - INSTANCE; - - @Override - public HttpSession asSession(ImmutableSession session, ServletContext context) { - return new HttpSession() { - @Override - public String getId() { - return session.getId(); - } - - @Override - public ServletContext getServletContext() { - return context; - } - - @Override - public boolean isNew() { - return session.getMetaData().isNew(); - } - - @Override - public long getCreationTime() { - return session.getMetaData().getCreationTime().toEpochMilli(); - } - - @Override - public long getLastAccessedTime() { - return session.getMetaData().getLastAccessStartTime().toEpochMilli(); - } - - @Override - public int getMaxInactiveInterval() { - return (int) session.getMetaData().getTimeout().getSeconds(); - } - - @Override - public Enumeration getAttributeNames() { - return Collections.enumeration(session.getAttributes().getAttributeNames()); - } - - @Override - public Object getAttribute(String name) { - return session.getAttributes().getAttribute(name); - } - - @Override - public void setAttribute(String name, Object value) { - // Ignore - } - - @Override - public void removeAttribute(String name) { - // Ignore - } - - @Override - public void invalidate() { - // Ignore - } - - @Override - public void setMaxInactiveInterval(int interval) { - // Ignore - } - - @Override - public int hashCode() { - return this.getId().hashCode(); - } - - @Override - public boolean equals(Object object) { - if (!(object instanceof HttpSession session)) return false; - return Objects.equals(this.getId(), session.getId()) && Objects.equals(this.getServletContext().getVirtualServerName(), session.getServletContext().getVirtualServerName()) && Objects.equals(this.getServletContext().getContextPath(), session.getServletContext().getContextPath()); - } - - @Override - public String toString() { - return this.getId(); - } - }; - } - - @Override - public Optional asSessionActivationListener(Object attribute) { - return Optional.ofNullable(attribute).filter(HttpSessionActivationListener.class::isInstance).map(HttpSessionActivationListener.class::cast); - } - - @Override - public Consumer prePassivateNotifier(HttpSessionActivationListener listener) { - return new Consumer<>() { - @Override - public void accept(HttpSession session) { - listener.sessionWillPassivate(new HttpSessionEvent(session)); - } - }; - } - - @Override - public Consumer postActivateNotifier(HttpSessionActivationListener listener) { - return new Consumer<>() { - @Override - public void accept(HttpSession session) { - listener.sessionDidActivate(new HttpSessionEvent(session)); - } - }; - } - - @Override - public HttpSessionActivationListener asSessionActivationListener(Consumer prePassivate, Consumer postActivate) { - return new HttpSessionActivationListener() { - @Override - public void sessionWillPassivate(HttpSessionEvent event) { - prePassivate.accept(event.getSession()); - } - - @Override - public void sessionDidActivate(HttpSessionEvent event) { - postActivate.accept(event.getSession()); - } - }; - } -} diff --git a/web/core/src/main/java/org/wildfly/clustering/spring/web/config/WebSessionConfiguration.java b/web/core/src/main/java/org/wildfly/clustering/spring/web/config/WebSessionConfiguration.java index baaf767..483a7fd 100644 --- a/web/core/src/main/java/org/wildfly/clustering/spring/web/config/WebSessionConfiguration.java +++ b/web/core/src/main/java/org/wildfly/clustering/spring/web/config/WebSessionConfiguration.java @@ -7,11 +7,10 @@ import java.lang.annotation.Annotation; import java.time.Duration; +import java.util.Optional; import java.util.function.Consumer; import jakarta.servlet.ServletContext; -import jakarta.servlet.http.HttpSession; -import jakarta.servlet.http.HttpSessionActivationListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; @@ -23,17 +22,16 @@ import org.wildfly.clustering.cache.batch.Batch; import org.wildfly.clustering.session.ImmutableSession; import org.wildfly.clustering.session.SessionManager; -import org.wildfly.clustering.session.container.ContainerFacadeProvider; +import org.wildfly.clustering.session.spec.SessionSpecificationProvider; import org.wildfly.clustering.spring.context.config.SessionManagementConfiguration; import org.wildfly.clustering.spring.web.DistributableWebSessionManager; import org.wildfly.clustering.spring.web.DistributableWebSessionManagerConfiguration; -import org.wildfly.clustering.spring.web.JakartaServletFacadeProvider; import org.wildfly.common.function.Functions; /** * @author Paul Ferraro */ -public abstract class WebSessionConfiguration extends SessionManagementConfiguration implements ServletContextAware { +public abstract class WebSessionConfiguration extends SessionManagementConfiguration implements ServletContextAware, SessionSpecificationProvider { private WebSessionIdResolver resolver = new CookieWebSessionIdResolver(); @@ -43,6 +41,11 @@ protected WebSessionConfiguration(Class annotationClass) { super(annotationClass); } + @Override + public SessionSpecificationProvider get() { + return this; + } + @Bean(WebHttpHandlerBuilder.WEB_SESSION_MANAGER_BEAN_NAME) public WebSessionManager webSessionManager(SessionManager manager) { WebSessionIdResolver resolver = this.resolver; @@ -75,11 +78,6 @@ public void setSessionIdentifierResolver(WebSessionIdResolver resolver) { this.resolver = resolver; } - @Override - public ContainerFacadeProvider getContainerFacadeProvider() { - return JakartaServletFacadeProvider.INSTANCE; - } - @Override public String getServerName() { return this.getContext().getVirtualServerName(); @@ -99,4 +97,34 @@ public Consumer getExpirationListener() { public Duration getTimeout() { return Duration.ofMinutes(this.getContext().getSessionTimeout()); } + + @Override + public Void asSession(ImmutableSession session, ServletContext context) { + return null; + } + + @Override + public Optional asSessionActivationListener(Object attribute) { + return Optional.empty(); + } + + @Override + public Class getSessionActivationListenerClass() { + return null; + } + + @Override + public Consumer prePassivate(Void listener) { + return Functions.discardingConsumer(); + } + + @Override + public Consumer postActivate(Void listener) { + return Functions.discardingConsumer(); + } + + @Override + public Void asSessionActivationListener(Consumer prePassivate, Consumer postActivate) { + return null; + } } diff --git a/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractSmokeITCase.java b/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractSmokeITCase.java index 46d3dd8..3f86b01 100644 --- a/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractSmokeITCase.java +++ b/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractSmokeITCase.java @@ -4,142 +4,41 @@ */ package org.wildfly.clustering.spring.web; -import static org.junit.jupiter.api.Assertions.*; - -import java.net.CookieManager; import java.net.URI; -import java.net.http.HttpClient; -import java.net.http.HttpRequest; -import java.net.http.HttpRequest.BodyPublishers; -import java.net.http.HttpResponse.BodyHandlers; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicLong; -import java.util.concurrent.atomic.AtomicReference; - -import jakarta.servlet.http.HttpServletResponse; +import java.util.function.BiConsumer; import org.jboss.shrinkwrap.api.ShrinkWrap; import org.jboss.shrinkwrap.api.spec.WebArchive; import org.junit.jupiter.api.AfterEach; -import org.junit.jupiter.api.Assertions; -import org.wildfly.common.function.ExceptionBiConsumer; +import org.wildfly.clustering.session.container.ClientTester; +import org.wildfly.clustering.session.container.SessionManagementEndpointConfiguration; +import org.wildfly.clustering.session.container.SessionManagementTester; +import org.wildfly.clustering.session.container.SessionManagementTesterConfiguration; /** * @author Paul Ferraro */ -public class AbstractSmokeITCase implements ExceptionBiConsumer { +public class AbstractSmokeITCase implements BiConsumer, SessionManagementTesterConfiguration { protected static final String CONTAINER_1 = "tomcat-1"; protected static final String CONTAINER_2 = "tomcat-2"; protected static final String DEPLOYMENT_1 = "deployment-1"; protected static final String DEPLOYMENT_2 = "deployment-2"; - private static final int ITERATIONS = 4; - private static final int CONCURRENCY = ITERATIONS * 10; - protected static WebArchive deployment(Class testClass) { return ShrinkWrap.create(WebArchive.class, testClass.getSimpleName() + ".war") - .addClasses(PropertiesAsset.class, SmokeITParameters.class) + .addClasses(PropertiesAsset.class, SessionManagementEndpointConfiguration.class) ; } - private final boolean transactional; - private final ExecutorService executor; - private final HttpClient client; - - protected AbstractSmokeITCase(HttpClient.Builder builder) { - this(false, builder); - } - - protected AbstractSmokeITCase(boolean transactional, HttpClient.Builder builder) { - this.transactional = transactional; - this.executor = Executors.newFixedThreadPool(CONCURRENCY); - this.client = builder.cookieHandler(new CookieManager()).executor(this.executor).build(); - } + private final ClientTester tester = new SessionManagementTester(this); @AfterEach public void destroy() { - this.executor.shutdown(); + this.tester.close(); } @Override - public void accept(URI baseURI1, URI baseURI2) throws Exception { - URI uri1 = baseURI1.resolve(SmokeITParameters.ENDPOINT_NAME); - URI uri2 = baseURI2.resolve(SmokeITParameters.ENDPOINT_NAME); - for (URI uri : Arrays.asList(uri1, uri2)) { - // Verify a request that never starts its session - this.client.sendAsync(HttpRequest.newBuilder(uri).method("HEAD", BodyPublishers.noBody()).build(), BodyHandlers.discarding()).thenAccept(response -> { - assertEquals(HttpServletResponse.SC_OK, response.statusCode()); - assertNull(response.headers().firstValue(SmokeITParameters.SESSION_ID).orElse(null)); - assertFalse(response.headers().firstValueAsLong(SmokeITParameters.VALUE).isPresent()); - }).join(); - } - AtomicReference sessionId = new AtomicReference<>(); - AtomicLong expected = new AtomicLong(0); - for (int i = 0; i < ITERATIONS; i++) { - for (URI uri : Arrays.asList(uri1, uri2)) { - int count = i; - long value = this.client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.discarding()).thenApply(response -> { - assertEquals(HttpServletResponse.SC_OK, response.statusCode(), Integer.toString(count)); - String requestSessionId = response.headers().firstValue(SmokeITParameters.SESSION_ID).orElse(null); - assertNotNull(requestSessionId); - // Validate propagation of session ID - if (!sessionId.compareAndSet(null, requestSessionId)) { - assertEquals(sessionId.get(), requestSessionId); - } - return response.headers().firstValueAsLong(SmokeITParameters.VALUE).orElse(0); - }).join(); - Assertions.assertEquals(expected.incrementAndGet(), value); - // Validate session is still "started" - this.client.sendAsync(HttpRequest.newBuilder(uri).method("HEAD", BodyPublishers.noBody()).build(), BodyHandlers.discarding()).thenAccept(response -> { - assertEquals(HttpServletResponse.SC_OK, response.statusCode()); - assertEquals(sessionId.get(), response.headers().firstValue(SmokeITParameters.SESSION_ID).orElse(null)); - }).join(); - // Perform a number of concurrent requests incrementing the session attribute - List> futures = new ArrayList<>(CONCURRENCY); - for (int j = 0; j < CONCURRENCY; j++) { - CompletableFuture future = this.client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.discarding()).thenApply(response -> { - assertEquals(HttpServletResponse.SC_OK, response.statusCode()); - assertEquals(sessionId.get(), response.headers().firstValue(SmokeITParameters.SESSION_ID).orElse(null)); - return response.headers().firstValueAsLong(SmokeITParameters.VALUE).orElse(0); - }); - futures.add(future); - } - expected.addAndGet(CONCURRENCY); - // Verify the correct number of unique results - assertEquals(CONCURRENCY, futures.stream().map(CompletableFuture::join).distinct().count()); - // Verify expected session attribute value following concurrent updates - value = this.client.sendAsync(HttpRequest.newBuilder(uri).build(), BodyHandlers.discarding()).thenApply(response -> { - assertEquals(HttpServletResponse.SC_OK, response.statusCode()); - assertEquals(sessionId.get(), response.headers().firstValue(SmokeITParameters.SESSION_ID).orElse("none")); - return response.headers().firstValueAsLong(SmokeITParameters.VALUE).orElse(0); - }).join(); - Assertions.assertEquals(expected.incrementAndGet(), value); - if (!this.transactional) { - // Grace time between fail-over requests - TimeUnit.SECONDS.sleep(1); - } - } - } - // Invalidate session - this.client.sendAsync(HttpRequest.newBuilder(uri1).DELETE().build(), BodyHandlers.discarding()).thenAccept(response -> { - assertEquals(HttpServletResponse.SC_OK, response.statusCode()); - assertNull(response.headers().firstValue(SmokeITParameters.SESSION_ID).orElse(null)); - }).join(); - List> futures = new ArrayList<>(2); - for (URI uri : Arrays.asList(uri1, uri2)) { - // Verify session was truly invalidated - futures.add(this.client.sendAsync(HttpRequest.newBuilder(uri).method("HEAD", BodyPublishers.noBody()).build(), BodyHandlers.discarding()).thenAccept(response -> { - assertEquals(HttpServletResponse.SC_OK, response.statusCode()); - assertNull(response.headers().firstValue(SmokeITParameters.SESSION_ID).orElse(null)); - assertFalse(response.headers().firstValueAsLong(SmokeITParameters.VALUE).isPresent()); - })); - } - futures.stream().forEach(CompletableFuture::join); + public void accept(URI baseURI1, URI baseURI2) { + this.tester.test(baseURI1, baseURI2); } } diff --git a/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractWebSmokeITCase.java b/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractWebSmokeITCase.java index f6b5a4d..4fff65c 100644 --- a/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractWebSmokeITCase.java +++ b/web/core/src/test/java/org/wildfly/clustering/spring/web/AbstractWebSmokeITCase.java @@ -5,8 +5,6 @@ package org.wildfly.clustering.spring.web; -import java.net.http.HttpClient; - import org.jboss.shrinkwrap.api.spec.WebArchive; import org.wildfly.clustering.spring.web.context.SessionHandler; import org.wildfly.clustering.spring.web.servlet.DispatcherServlet; @@ -22,8 +20,4 @@ protected static WebArchive deployment(Class test .addPackage(DispatcherServlet.class.getPackage()) ; } - - protected AbstractWebSmokeITCase(HttpClient.Builder builder) { - super(builder); - } } diff --git a/web/core/src/test/java/org/wildfly/clustering/spring/web/SmokeITParameters.java b/web/core/src/test/java/org/wildfly/clustering/spring/web/SmokeITParameters.java deleted file mode 100644 index 7b90484..0000000 --- a/web/core/src/test/java/org/wildfly/clustering/spring/web/SmokeITParameters.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright The WildFly Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package org.wildfly.clustering.spring.web; - -/** - * Constants used in smoke tests. - * @author Paul Ferraro - */ -public interface SmokeITParameters { - String ENDPOINT_NAME = "session"; - String ENDPOINT_PATH = "/" + ENDPOINT_NAME; - String VALUE = "value"; - String SESSION_ID = "session-id"; -} diff --git a/web/core/src/test/java/org/wildfly/clustering/spring/web/context/ReactiveConfig.java b/web/core/src/test/java/org/wildfly/clustering/spring/web/context/ReactiveConfig.java index 8da4973..f987ecb 100644 --- a/web/core/src/test/java/org/wildfly/clustering/spring/web/context/ReactiveConfig.java +++ b/web/core/src/test/java/org/wildfly/clustering/spring/web/context/ReactiveConfig.java @@ -15,7 +15,7 @@ import org.springframework.web.reactive.result.SimpleHandlerAdapter; import org.springframework.web.server.WebHandler; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; -import org.wildfly.clustering.spring.web.SmokeITParameters; +import org.wildfly.clustering.session.container.SessionManagementEndpointConfiguration; /** * @author Paul Ferraro @@ -24,7 +24,7 @@ public class ReactiveConfig { @Bean public HandlerMapping handlerMapping() { - return new SimpleUrlHandlerMapping(Map.of(SmokeITParameters.ENDPOINT_PATH, new SessionHandler())); + return new SimpleUrlHandlerMapping(Map.of(SessionManagementEndpointConfiguration.ENDPOINT_PATH, new SessionHandler())); } @Bean(WebHttpHandlerBuilder.WEB_HANDLER_BEAN_NAME) diff --git a/web/core/src/test/java/org/wildfly/clustering/spring/web/context/SessionHandler.java b/web/core/src/test/java/org/wildfly/clustering/spring/web/context/SessionHandler.java index e0272a6..e2a03fe 100644 --- a/web/core/src/test/java/org/wildfly/clustering/spring/web/context/SessionHandler.java +++ b/web/core/src/test/java/org/wildfly/clustering/spring/web/context/SessionHandler.java @@ -6,8 +6,10 @@ package org.wildfly.clustering.spring.web.context; import java.util.Set; +import java.util.UUID; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; +import java.util.function.ToIntFunction; import jakarta.servlet.http.HttpServletResponse; @@ -18,7 +20,7 @@ import org.springframework.web.server.ServerWebExchange; import org.springframework.web.server.WebHandler; import org.springframework.web.server.WebSession; -import org.wildfly.clustering.spring.web.SmokeITParameters; +import org.wildfly.clustering.session.container.SessionManagementEndpointConfiguration; import reactor.core.publisher.Mono; @@ -26,7 +28,7 @@ * @author Paul Ferraro */ public class SessionHandler implements WebHandler, Function> { - private static final Set SUPPORTED_METHODS = Set.of(HttpMethod.GET, HttpMethod.HEAD, HttpMethod.DELETE); + private static final Set SUPPORTED_METHODS = Set.of(HttpMethod.HEAD, HttpMethod.GET, HttpMethod.PUT, HttpMethod.DELETE); @Override public Mono handle(ServerWebExchange exchange) { @@ -43,7 +45,7 @@ public Mono handle(ServerWebExchange exchange) { } return sessionPublisher.doOnNext(session -> { if (session.isStarted()) { - response.getHeaders().set(SmokeITParameters.SESSION_ID, session.getId()); + response.getHeaders().set(SessionManagementEndpointConfiguration.SESSION_ID, session.getId()); } }).then(); } @@ -54,12 +56,28 @@ public Mono apply(ServerWebExchange exchange) { HttpMethod method = request.getMethod(); ServerHttpResponse response = exchange.getResponse(); Mono sessionPublisher = exchange.getSession(); - if (method.equals(HttpMethod.GET)) { - return sessionPublisher.doOnNext(session -> { - AtomicInteger value = (AtomicInteger) session.getAttributes().computeIfAbsent(SmokeITParameters.VALUE, key -> new AtomicInteger(0)); - response.getHeaders().set(SmokeITParameters.VALUE, Integer.toString(value.incrementAndGet())); + if (method.equals(HttpMethod.PUT)) { + return sessionPublisher.doOnNext(WebSession::start).doOnNext(session -> { + UUID immutableValue = UUID.randomUUID(); + session.getAttributes().put(SessionManagementEndpointConfiguration.IMMUTABLE, immutableValue); + response.getHeaders().set(SessionManagementEndpointConfiguration.IMMUTABLE, immutableValue.toString()); + + AtomicInteger counter = new AtomicInteger(0); + session.getAttributes().put(SessionManagementEndpointConfiguration.COUNTER, counter); + response.getHeaders().set(SessionManagementEndpointConfiguration.COUNTER, Integer.toString(counter.get())); }); } - return sessionPublisher; + ToIntFunction count = method.equals(HttpMethod.GET) ? AtomicInteger::incrementAndGet : AtomicInteger::get; + return sessionPublisher.doOnNext(session -> { + UUID value = (UUID) session.getAttribute(SessionManagementEndpointConfiguration.IMMUTABLE); + if (value != null) { + response.getHeaders().set(SessionManagementEndpointConfiguration.IMMUTABLE, value.toString()); + } + + AtomicInteger counter = (AtomicInteger) session.getAttribute(SessionManagementEndpointConfiguration.COUNTER); + if (counter != null) { + response.getHeaders().set(SessionManagementEndpointConfiguration.COUNTER, Integer.toString(count.applyAsInt(counter))); + } + }); } } diff --git a/web/infinispan/embedded/pom.xml b/web/infinispan/embedded/pom.xml index 347b49f..84e24f2 100644 --- a/web/infinispan/embedded/pom.xml +++ b/web/infinispan/embedded/pom.xml @@ -44,6 +44,13 @@ test + + org.wildfly.clustering + wildfly-clustering-session-spi + tests + test + + org.jboss.arquillian.container arquillian-tomcat-managed-8 diff --git a/web/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/web/infinispan/embedded/config/InfinispanWebSessionConfiguration.java b/web/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/web/infinispan/embedded/config/InfinispanWebSessionConfiguration.java index 0d4e7f5..4ba5798 100644 --- a/web/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/web/infinispan/embedded/config/InfinispanWebSessionConfiguration.java +++ b/web/infinispan/embedded/src/main/java/org/wildfly/clustering/spring/web/infinispan/embedded/config/InfinispanWebSessionConfiguration.java @@ -41,7 +41,7 @@ public ChannelEmbeddedCacheManagerCommandDispatcherFactoryConfiguration embedded @Bean public SessionManagerFactory sessionManagerFactory(ChannelEmbeddedCacheManagerCommandDispatcherFactoryConfiguration embeddedCacheManagerConfiguration) { - return new InfinispanSessionManagerFactoryBean<>(this, this.configuration, embeddedCacheManagerConfiguration); + return new InfinispanSessionManagerFactoryBean<>(this, this.get(), this.configuration, embeddedCacheManagerConfiguration); } @Override diff --git a/web/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/web/infinispan/embedded/AbstractInfinispanWebSmokeITCase.java b/web/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/web/infinispan/embedded/AbstractInfinispanWebSmokeITCase.java index 9b867e3..6b5c193 100644 --- a/web/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/web/infinispan/embedded/AbstractInfinispanWebSmokeITCase.java +++ b/web/infinispan/embedded/src/test/java/org/wildfly/clustering/spring/web/infinispan/embedded/AbstractInfinispanWebSmokeITCase.java @@ -5,8 +5,6 @@ package org.wildfly.clustering.spring.web.infinispan.embedded; -import java.net.http.HttpClient; - import org.jboss.shrinkwrap.api.spec.WebArchive; import org.wildfly.clustering.spring.web.AbstractSmokeITCase; import org.wildfly.clustering.spring.web.AbstractWebSmokeITCase; @@ -21,8 +19,4 @@ protected static WebArchive deployment(Class test .addAsWebInfResource(AbstractInfinispanWebSmokeITCase.class.getPackage(), "infinispan.xml", "infinispan.xml") ; } - - protected AbstractInfinispanWebSmokeITCase() { - super(HttpClient.newBuilder()); - } } diff --git a/web/infinispan/remote/pom.xml b/web/infinispan/remote/pom.xml index b68b88a..3351f89 100644 --- a/web/infinispan/remote/pom.xml +++ b/web/infinispan/remote/pom.xml @@ -62,6 +62,12 @@ tests test + + org.wildfly.clustering + wildfly-clustering-session-spi + tests + test + org.jboss.arquillian.container diff --git a/web/infinispan/remote/src/main/java/org/wildfly/clustering/spring/web/infinispan/remote/config/HotRodWebSessionConfiguration.java b/web/infinispan/remote/src/main/java/org/wildfly/clustering/spring/web/infinispan/remote/config/HotRodWebSessionConfiguration.java index e43a81e..8c5bb6a 100644 --- a/web/infinispan/remote/src/main/java/org/wildfly/clustering/spring/web/infinispan/remote/config/HotRodWebSessionConfiguration.java +++ b/web/infinispan/remote/src/main/java/org/wildfly/clustering/spring/web/infinispan/remote/config/HotRodWebSessionConfiguration.java @@ -44,7 +44,7 @@ public RemoteCacheContainerProvider remoteCacheManagerProvider() { @Bean public SessionManagerFactory sessionManagerFactory(RemoteCacheContainerProvider provider) { - return new HotRodSessionManagerFactoryBean<>(this, this.configuration, provider); + return new HotRodSessionManagerFactoryBean<>(this, this.get(), this.configuration, provider); } @Override @@ -67,11 +67,6 @@ public String getTemplateName() { return this.configuration.getTemplateName(); } - @Override - public int getExpirationThreadPoolSize() { - return this.configuration.getExpirationThreadPoolSize(); - } - @Override @Autowired(required = false) public void setUri(String uri) { @@ -89,12 +84,6 @@ public void setTemplateName(String templateName) { this.configuration.setTemplateName(templateName); } - @Override - @Autowired(required = false) - public void setExpirationThreadPoolSize(int size) { - this.configuration.setExpirationThreadPoolSize(size); - } - @Override public void accept(AnnotationAttributes attributes) { this.configuration.accept(attributes); diff --git a/web/infinispan/remote/src/test/java/org/wildfly/clustering/spring/web/infinispan/remote/AbstractHotRodWebSmokeITCase.java b/web/infinispan/remote/src/test/java/org/wildfly/clustering/spring/web/infinispan/remote/AbstractHotRodWebSmokeITCase.java index 2f30ca8..3760a80 100644 --- a/web/infinispan/remote/src/test/java/org/wildfly/clustering/spring/web/infinispan/remote/AbstractHotRodWebSmokeITCase.java +++ b/web/infinispan/remote/src/test/java/org/wildfly/clustering/spring/web/infinispan/remote/AbstractHotRodWebSmokeITCase.java @@ -5,7 +5,6 @@ package org.wildfly.clustering.spring.web.infinispan.remote; -import java.net.http.HttpClient; import java.util.Properties; import org.infinispan.client.hotrod.DefaultTemplate; @@ -41,8 +40,4 @@ protected static WebArchive deployment(Class test .addAsWebInfResource(new PropertiesAsset(properties), "classes/application.properties") ; } - - protected AbstractHotRodWebSmokeITCase() { - super(HttpClient.newBuilder()); - } }