From 1c7d5e5d917c698a84f958090e993b9404a39744 Mon Sep 17 00:00:00 2001 From: Greg Turnquist Date: Fri, 27 Sep 2019 11:28:34 -0500 Subject: [PATCH] Implement support for Spring Session's repository customiers. Resolves #105. --- .../http/MongoHttpSessionConfiguration.java | 14 ++++++++ .../ReactiveMongoWebSessionConfiguration.java | 14 ++++++++ .../MongoHttpSessionConfigurationTest.java | 28 +++++++++++++++ ...ctiveMongoWebSessionConfigurationTest.java | 36 +++++++++++++++++++ 4 files changed, 92 insertions(+) diff --git a/src/main/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfiguration.java b/src/main/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfiguration.java index a2a08b0..e6614d0 100644 --- a/src/main/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfiguration.java +++ b/src/main/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfiguration.java @@ -16,8 +16,11 @@ package org.springframework.session.data.mongo.config.annotation.web.http; import java.time.Duration; +import java.util.List; +import java.util.stream.Collectors; import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.context.annotation.Bean; @@ -28,6 +31,7 @@ import org.springframework.core.serializer.support.DeserializingConverter; import org.springframework.core.serializer.support.SerializingConverter; import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.mongodb.core.MongoOperations; +import org.springframework.session.config.SessionRepositoryCustomizer; import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration; import org.springframework.session.data.mongo.AbstractMongoSessionConverter; import org.springframework.session.data.mongo.JdkMongoSessionConverter; @@ -51,6 +55,7 @@ public class MongoHttpSessionConfiguration extends SpringHttpSessionConfiguratio private Integer maxInactiveIntervalInSeconds; private String collectionName; private StringValueResolver embeddedValueResolver; + private List> sessionRepositoryCustomizers; private ClassLoader classLoader; @Bean @@ -72,6 +77,9 @@ public class MongoHttpSessionConfiguration extends SpringHttpSessionConfiguratio repository.setCollectionName(this.collectionName); } + this.sessionRepositoryCustomizers + .forEach(sessionRepositoryCustomizer -> sessionRepositoryCustomizer.customize(repository)); + return repository; } @@ -105,6 +113,12 @@ public class MongoHttpSessionConfiguration extends SpringHttpSessionConfiguratio this.mongoSessionConverter = mongoSessionConverter; } + @Autowired(required = false) + public void setSessionRepositoryCustomizers( + ObjectProvider> sessionRepositoryCustomizers) { + this.sessionRepositoryCustomizers = sessionRepositoryCustomizers.orderedStream().collect(Collectors.toList()); + } + @Override public void setBeanClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; diff --git a/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfiguration.java b/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfiguration.java index bf03ecd..100f81f 100644 --- a/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfiguration.java +++ b/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfiguration.java @@ -16,8 +16,11 @@ package org.springframework.session.data.mongo.config.annotation.web.reactive; import java.time.Duration; +import java.util.List; +import java.util.stream.Collectors; import org.springframework.beans.factory.BeanClassLoaderAware; +import org.springframework.beans.factory.ObjectProvider; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.context.annotation.Bean; @@ -29,6 +32,7 @@ import org.springframework.core.serializer.support.SerializingConverter; import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.session.config.ReactiveSessionRepositoryCustomizer; import org.springframework.session.config.annotation.web.server.SpringWebSessionConfiguration; import org.springframework.session.data.mongo.AbstractMongoSessionConverter; import org.springframework.session.data.mongo.JdkMongoSessionConverter; @@ -50,6 +54,7 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig private Integer maxInactiveIntervalInSeconds; private String collectionName; private StringValueResolver embeddedValueResolver; + private List> sessionRepositoryCustomizers; @Autowired(required = false) private MongoOperations mongoOperations; private ClassLoader classLoader; @@ -80,6 +85,9 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig repository.setBlockingMongoOperations(this.mongoOperations); } + this.sessionRepositoryCustomizers + .forEach(sessionRepositoryCustomizer -> sessionRepositoryCustomizer.customize(repository)); + return repository; } @@ -132,4 +140,10 @@ public class ReactiveMongoWebSessionConfiguration extends SpringWebSessionConfig public void setCollectionName(String collectionName) { this.collectionName = collectionName; } + + @Autowired(required = false) + public void setSessionRepositoryCustomizers( + ObjectProvider> sessionRepositoryCustomizers) { + this.sessionRepositoryCustomizers = sessionRepositoryCustomizers.orderedStream().collect(Collectors.toList()); + } } diff --git a/src/test/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfigurationTest.java b/src/test/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfigurationTest.java index 45aeab3..9a55375 100644 --- a/src/test/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfigurationTest.java +++ b/src/test/java/org/springframework/session/data/mongo/config/annotation/web/http/MongoHttpSessionConfigurationTest.java @@ -22,6 +22,7 @@ import static org.mockito.BDDMockito.*; import java.net.UnknownHostException; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -32,6 +33,7 @@ import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.mock.env.MockEnvironment; +import org.springframework.session.config.SessionRepositoryCustomizer; import org.springframework.session.data.mongo.AbstractMongoSessionConverter; import org.springframework.session.data.mongo.MongoIndexedSessionRepository; import org.springframework.test.util.ReflectionTestUtils; @@ -144,6 +146,16 @@ public class MongoHttpSessionConfigurationTest { assertThat(ReflectionTestUtils.getField(configuration, "collectionName")).isEqualTo(COLLECTION_NAME); } + @Test + public void sessionRepositoryCustomizer() { + + registerAndRefresh(MongoConfiguration.class, SessionRepositoryCustomizerConfiguration.class); + + MongoIndexedSessionRepository sessionRepository = this.context.getBean(MongoIndexedSessionRepository.class); + + assertThat(sessionRepository).hasFieldOrPropertyWithValue("maxInactiveIntervalInSeconds", 10000); + } + private void registerAndRefresh(Class... annotatedClasses) { this.context.register(annotatedClasses); @@ -236,4 +248,20 @@ public class MongoHttpSessionConfigurationTest { } + @EnableMongoHttpSession + static class SessionRepositoryCustomizerConfiguration { + + @Bean + @Order(0) + public SessionRepositoryCustomizer sessionRepositoryCustomizerOne() { + return sessionRepository -> sessionRepository.setMaxInactiveIntervalInSeconds(0); + } + + @Bean + @Order(1) + public SessionRepositoryCustomizer sessionRepositoryCustomizerTwo() { + return sessionRepository -> sessionRepository.setMaxInactiveIntervalInSeconds(10000); + } + } + } diff --git a/src/test/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfigurationTest.java b/src/test/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfigurationTest.java index 6e55ee9..2aa913d 100644 --- a/src/test/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfigurationTest.java +++ b/src/test/java/org/springframework/session/data/mongo/config/annotation/web/reactive/ReactiveMongoWebSessionConfigurationTest.java @@ -22,6 +22,7 @@ import java.lang.reflect.Field; import java.util.Collections; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.Order; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -30,6 +31,7 @@ import org.springframework.data.mongodb.core.MongoOperations; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.data.mongodb.core.index.IndexOperations; import org.springframework.session.ReactiveSessionRepository; +import org.springframework.session.config.ReactiveSessionRepositoryCustomizer; import org.springframework.session.config.annotation.web.server.EnableSpringWebSession; import org.springframework.session.data.mongo.AbstractMongoSessionConverter; import org.springframework.session.data.mongo.JacksonMongoSessionConverter; @@ -163,6 +165,18 @@ public class ReactiveMongoWebSessionConfigurationTest { assertThat(repository.getMaxInactiveIntervalInSeconds()).isEqualTo(123); } + @Test + public void sessionRepositoryCustomizer() { + + this.context = new AnnotationConfigApplicationContext(); + this.context.register(SessionRepositoryCustomizerConfiguration.class); + this.context.refresh(); + + ReactiveMongoSessionRepository repository = this.context.getBean(ReactiveMongoSessionRepository.class); + + assertThat(repository).hasFieldOrPropertyWithValue("maxInactiveIntervalInSeconds", 10000); + } + /** * Reflectively extract the {@link AbstractMongoSessionConverter} from the {@link ReactiveMongoSessionRepository}. * This is to avoid expanding the surface area of the API. @@ -263,4 +277,26 @@ public class ReactiveMongoWebSessionConfigurationTest { return mock(ReactiveMongoOperations.class); } } + + @EnableMongoWebSession + static class SessionRepositoryCustomizerConfiguration { + + @Bean + ReactiveMongoOperations operations() { + return mock(ReactiveMongoOperations.class); + } + + @Bean + @Order(0) + public ReactiveSessionRepositoryCustomizer sessionRepositoryCustomizerOne() { + return sessionRepository -> sessionRepository.setMaxInactiveIntervalInSeconds(0); + } + + @Bean + @Order(1) + public ReactiveSessionRepositoryCustomizer sessionRepositoryCustomizerTwo() { + return sessionRepository -> sessionRepository.setMaxInactiveIntervalInSeconds(10000); + } + + } }