Allow overriding Mongo parameters through reactive annotation

This commit is contained in:
Greg Turnquist
2017-08-30 10:29:38 -05:00
parent b22ec3fa00
commit 42a83f937a
4 changed files with 103 additions and 7 deletions

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -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);
}
}
}