From b22ec3fa0087fd6412f78ad30f892dba3ae256bc Mon Sep 17 00:00:00 2001 From: Greg Turnquist Date: Wed, 30 Aug 2017 09:53:08 -0500 Subject: [PATCH] Make AbstractMongoSessionConverter injectable While it defaults to the coverter based on whether or not Jackson is on the classpath, this attribute must be overridable based on whatever is in the application context. --- ...ctiveMongoOperationsSessionRepository.java | 2 + ...ctiveMongoWebSessionConfigurationTest.java | 71 +++++++++++++++++++ 2 files changed, 73 insertions(+) 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 b49dc2d..ac65afb 100644 --- a/src/main/java/org/springframework/session/data/mongo/ReactiveMongoOperationsSessionRepository.java +++ b/src/main/java/org/springframework/session/data/mongo/ReactiveMongoOperationsSessionRepository.java @@ -19,6 +19,7 @@ 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; @@ -119,6 +120,7 @@ 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; } 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 7013bf5..68f6f49 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 @@ -18,6 +18,8 @@ package org.springframework.session.data.mongo.config.annotation.web.reactive; import static org.assertj.core.api.Assertions.*; import static org.mockito.Mockito.*; +import java.lang.reflect.Field; + import org.junit.Test; import org.springframework.beans.factory.UnsatisfiedDependencyException; import org.springframework.context.annotation.AnnotationConfigApplicationContext; @@ -25,6 +27,11 @@ import org.springframework.context.annotation.Bean; import org.springframework.data.mongodb.core.ReactiveMongoOperations; import org.springframework.session.EnableSpringWebSession; import org.springframework.session.ReactorSessionRepository; +import org.springframework.session.data.mongo.AbstractMongoSessionConverter; +import org.springframework.session.data.mongo.JacksonMongoSessionConverter; +import org.springframework.session.data.mongo.JdkMongoSessionConverter; +import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository; +import org.springframework.util.ReflectionUtils; import org.springframework.web.server.adapter.WebHttpHandlerBuilder; import org.springframework.web.server.session.WebSessionManager; @@ -64,6 +71,56 @@ public class ReactiveMongoWebSessionConfigurationTest { .withMessageContaining("No qualifying bean of type '" + ReactiveMongoOperations.class.getCanonicalName()); } + @Test + public void defaultSessionConverterShouldBeJacksonWhenOnClasspath() throws IllegalAccessException { + + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(GoodConfig.class); + ctx.refresh(); + + ReactiveMongoOperationsSessionRepository repository = ctx.getBean(ReactiveMongoOperationsSessionRepository.class); + + AbstractMongoSessionConverter converter = findMongoSessionConverter(repository); + + assertThat(converter) + .extracting(AbstractMongoSessionConverter::getClass) + .contains(JacksonMongoSessionConverter.class); + } + + @Test + public void overridingMongoSessionConverterWithBeanShouldWork() throws IllegalAccessException { + + AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); + ctx.register(OverrideSessionConverterConfig.class); + ctx.refresh(); + + ReactiveMongoOperationsSessionRepository repository = ctx.getBean(ReactiveMongoOperationsSessionRepository.class); + + AbstractMongoSessionConverter converter = findMongoSessionConverter(repository); + + assertThat(converter) + .extracting(AbstractMongoSessionConverter::getClass) + .contains(JdkMongoSessionConverter.class); + } + + /** + * Reflectively extract the {@link AbstractMongoSessionConverter} from the {@link ReactiveMongoOperationsSessionRepository}. + * This is to avoid expanding the surface area of the API. + * + * @param repository + * @return + */ + private AbstractMongoSessionConverter findMongoSessionConverter(ReactiveMongoOperationsSessionRepository repository) { + + Field field = ReflectionUtils.findField(ReactiveMongoOperationsSessionRepository.class, "mongoSessionConverter"); + ReflectionUtils.makeAccessible(field); + try { + return (AbstractMongoSessionConverter) field.get(repository); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + /** * A configuration with all the right parts. */ @@ -83,4 +140,18 @@ public class ReactiveMongoWebSessionConfigurationTest { static class BadConfig { } + + @EnableMongoWebSession + static class OverrideSessionConverterConfig { + + @Bean + ReactiveMongoOperations operations() { + return mock(ReactiveMongoOperations.class); + } + + @Bean + JdkMongoSessionConverter mongoSessionConverter() { + return new JdkMongoSessionConverter(); + } + } }