From 42a83f937acf80e5fc1fc536ef68d13bcc42afbf Mon Sep 17 00:00:00 2001 From: Greg Turnquist Date: Wed, 30 Aug 2017 10:29:38 -0500 Subject: [PATCH] Allow overriding Mongo parameters through reactive annotation --- ...ctiveMongoOperationsSessionRepository.java | 7 +-- .../web/reactive/EnableMongoWebSession.java | 15 +++++ .../ReactiveMongoWebSessionConfiguration.java | 58 ++++++++++++++++++- ...ctiveMongoWebSessionConfigurationTest.java | 30 ++++++++++ 4 files changed, 103 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/springframework/session/data/mongo/ReactiveMongoOperationsSessionRepository.java b/src/main/java/org/springframework/session/data/mongo/ReactiveMongoOperationsSessionRepository.java index ac65afb..df7bbe6 100644 --- a/src/main/java/org/springframework/session/data/mongo/ReactiveMongoOperationsSessionRepository.java +++ b/src/main/java/org/springframework/session/data/mongo/ReactiveMongoOperationsSessionRepository.java @@ -19,7 +19,6 @@ import static org.springframework.session.data.mongo.MongoSessionUtils.*; import org.bson.Document; import reactor.core.publisher.Mono; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.session.ReactorSessionRepository; @@ -34,14 +33,13 @@ public class ReactiveMongoOperationsSessionRepository implements ReactorSessionR public static final int DEFAULT_INACTIVE_INTERVAL = 1800; /** - * the default collection name for storing session. + * The default collection name for storing session. */ public static final String DEFAULT_COLLECTION_NAME = "sessions"; private final ReactiveMongoOperations mongoOperations; private AbstractMongoSessionConverter mongoSessionConverter = SessionConverterProvider.getDefaultMongoConverter(); - private Integer maxInactiveIntervalInSeconds = DEFAULT_INACTIVE_INTERVAL; private String collectionName = DEFAULT_COLLECTION_NAME; @@ -120,7 +118,6 @@ public class ReactiveMongoOperationsSessionRepository implements ReactorSessionR return this.mongoOperations.findById(id, Document.class, this.collectionName); } - @Autowired(required = false) public void setMongoSessionConverter(AbstractMongoSessionConverter mongoSessionConverter) { this.mongoSessionConverter = mongoSessionConverter; } @@ -132,5 +129,5 @@ public class ReactiveMongoOperationsSessionRepository implements ReactorSessionR public void setCollectionName(String collectionName) { this.collectionName = collectionName; } - + } diff --git a/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/EnableMongoWebSession.java b/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/EnableMongoWebSession.java index be8f33b..9bc9eb9 100644 --- a/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/EnableMongoWebSession.java +++ b/src/main/java/org/springframework/session/data/mongo/config/annotation/web/reactive/EnableMongoWebSession.java @@ -22,6 +22,7 @@ import java.lang.annotation.Target; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.session.EnableSpringWebSession; +import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository; /** * Add this annotation to a {@code @Configuration} class to configure a MongoDB-based {@code WebSessionManager} for a @@ -53,4 +54,18 @@ import org.springframework.session.EnableSpringWebSession; @Import(ReactiveMongoWebSessionConfiguration.class) @Configuration public @interface EnableMongoWebSession { + + /** + * The maximum time a session will be kept if it is inactive. + * + * @return default max inactive interval in seconds + */ + int maxInactiveIntervalInSeconds() default ReactiveMongoOperationsSessionRepository.DEFAULT_INACTIVE_INTERVAL; + + /** + * The collection name to use. + * + * @return name of the collection to store session + */ + String collectionName() default ReactiveMongoOperationsSessionRepository.DEFAULT_COLLECTION_NAME; } 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 d8ae83b..43775d9 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 @@ -15,10 +15,18 @@ */ package org.springframework.session.data.mongo.config.annotation.web.reactive; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.EmbeddedValueResolverAware; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.ImportAware; +import org.springframework.core.annotation.AnnotationAttributes; +import org.springframework.core.type.AnnotationMetadata; import org.springframework.data.mongodb.core.ReactiveMongoOperations; +import org.springframework.session.data.mongo.AbstractMongoSessionConverter; import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository; +import org.springframework.util.StringUtils; +import org.springframework.util.StringValueResolver; /** * Configure a {@link ReactiveMongoOperationsSessionRepository} using a provided {@link ReactiveMongoOperations}. @@ -26,10 +34,56 @@ import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepo * @author Greg Turnquist */ @Configuration -public class ReactiveMongoWebSessionConfiguration { +public class ReactiveMongoWebSessionConfiguration implements EmbeddedValueResolverAware, ImportAware { + + private AbstractMongoSessionConverter mongoSessionConverter; + private Integer maxInactiveIntervalInSeconds; + private String collectionName; + + private StringValueResolver embeddedValueResolver; @Bean public ReactiveMongoOperationsSessionRepository reactiveMongoOperationsSessionRepository(ReactiveMongoOperations operations) { - return new ReactiveMongoOperationsSessionRepository(operations); + + ReactiveMongoOperationsSessionRepository repository = new ReactiveMongoOperationsSessionRepository(operations); + + if (this.mongoSessionConverter != null) { + repository.setMongoSessionConverter(this.mongoSessionConverter); + } + + if (this.maxInactiveIntervalInSeconds != null) { + repository.setMaxInactiveIntervalInSeconds(this.maxInactiveIntervalInSeconds); + } + + if (this.collectionName != null) { + repository.setCollectionName(this.collectionName); + } + + return repository; + } + + @Autowired(required = false) + public void setMongoSessionConverter(AbstractMongoSessionConverter mongoSessionConverter) { + this.mongoSessionConverter = mongoSessionConverter; + } + + @Override + public void setImportMetadata(AnnotationMetadata importMetadata) { + + AnnotationAttributes attributes = AnnotationAttributes.fromMap( + importMetadata.getAnnotationAttributes(EnableMongoWebSession.class.getName())); + + this.maxInactiveIntervalInSeconds = attributes.getNumber("maxInactiveIntervalInSeconds"); + + String collectionNameValue = attributes.getString("collectionName"); + if (StringUtils.hasText(collectionNameValue)) { + this.collectionName = this.embeddedValueResolver.resolveStringValue(collectionNameValue); + } + + } + + @Override + public void setEmbeddedValueResolver(StringValueResolver embeddedValueResolver) { + this.embeddedValueResolver = embeddedValueResolver; } } 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 68f6f49..7f6858e 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 @@ -103,6 +103,27 @@ public class ReactiveMongoWebSessionConfigurationTest { .contains(JdkMongoSessionConverter.class); } + @Test + public void overridingIntervalAndCollectionNameThroughAnnotationShouldWork() throws IllegalAccessException { + + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(OverrideMongoParametersConfig.class); + ctx.refresh(); + + ReactiveMongoOperationsSessionRepository repository = ctx.getBean(ReactiveMongoOperationsSessionRepository.class); + + Field inactiveField = ReflectionUtils.findField(ReactiveMongoOperationsSessionRepository.class, "maxInactiveIntervalInSeconds"); + ReflectionUtils.makeAccessible(inactiveField); + Integer inactiveSeconds = (Integer) inactiveField.get(repository); + + Field collectionNameField = ReflectionUtils.findField(ReactiveMongoOperationsSessionRepository.class, "collectionName"); + ReflectionUtils.makeAccessible(collectionNameField); + String collectionName = (String) collectionNameField.get(repository); + + assertThat(inactiveSeconds).isEqualTo(123); + assertThat(collectionName).isEqualTo("test-case"); + } + /** * Reflectively extract the {@link AbstractMongoSessionConverter} from the {@link ReactiveMongoOperationsSessionRepository}. * This is to avoid expanding the surface area of the API. @@ -154,4 +175,13 @@ public class ReactiveMongoWebSessionConfigurationTest { return new JdkMongoSessionConverter(); } } + + @EnableMongoWebSession(maxInactiveIntervalInSeconds = 123, collectionName = "test-case") + static class OverrideMongoParametersConfig { + + @Bean + ReactiveMongoOperations operations() { + return mock(ReactiveMongoOperations.class); + } + } }