Harmonize Redis configurations
This commit improves reactive Redis configuration by adding support for connection factory qualifier and Redis operations resolver annotations.
This commit is contained in:
@@ -37,8 +37,8 @@ import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.data.SessionEventRegistry;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.SpringSessionRedisOperations;
|
||||
import org.springframework.session.events.SessionCreatedEvent;
|
||||
import org.springframework.session.events.SessionDestroyedEvent;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
|
||||
@@ -31,8 +31,8 @@ import org.springframework.core.task.TaskExecutor;
|
||||
import org.springframework.data.redis.core.BoundSetOperations;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.session.data.redis.AbstractRedisITests;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.SpringSessionRedisOperations;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.session.data.redis.config.annotation.web.http;
|
||||
package org.springframework.session.data.redis.config.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -14,7 +14,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.session.data.redis.config.annotation.web.http;
|
||||
package org.springframework.session.data.redis.config.annotation;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
@@ -48,6 +48,7 @@ import org.springframework.session.data.redis.RedisFlushMode;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction;
|
||||
import org.springframework.session.data.redis.config.ConfigureRedisAction;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory;
|
||||
import org.springframework.session.web.http.SessionRepositoryFilter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
@@ -18,6 +18,8 @@ package org.springframework.session.data.redis.config.annotation.web.server;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.EmbeddedValueResolverAware;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
@@ -33,6 +35,7 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
|
||||
import org.springframework.session.config.annotation.web.server.SpringWebSessionConfiguration;
|
||||
import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.RedisFlushMode;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.StringValueResolver;
|
||||
@@ -61,20 +64,19 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
|
||||
private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE;
|
||||
|
||||
private ReactiveRedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
private StringValueResolver embeddedValueResolver;
|
||||
|
||||
@Bean
|
||||
public ReactiveRedisOperationsSessionRepository sessionRepository(
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory) {
|
||||
public ReactiveRedisOperationsSessionRepository sessionRepository() {
|
||||
ReactiveRedisOperationsSessionRepository sessionRepository = new ReactiveRedisOperationsSessionRepository(
|
||||
createDefaultTemplate(redisConnectionFactory));
|
||||
createDefaultTemplate(this.redisConnectionFactory));
|
||||
sessionRepository
|
||||
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
|
||||
String redisNamespace = getRedisNamespace();
|
||||
|
||||
if (StringUtils.hasText(redisNamespace)) {
|
||||
sessionRepository.setRedisKeyNamespace(redisNamespace);
|
||||
if (StringUtils.hasText(this.redisNamespace)) {
|
||||
sessionRepository.setRedisKeyNamespace(this.redisNamespace);
|
||||
}
|
||||
|
||||
sessionRepository.setRedisFlushMode(this.redisFlushMode);
|
||||
@@ -95,6 +97,18 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
this.redisFlushMode = redisFlushMode;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setRedisConnectionFactory(
|
||||
@SpringSessionRedisConnectionFactory ObjectProvider<ReactiveRedisConnectionFactory> springSessionRedisConnectionFactory,
|
||||
ObjectProvider<ReactiveRedisConnectionFactory> redisConnectionFactory) {
|
||||
ReactiveRedisConnectionFactory redisConnectionFactoryToUse = springSessionRedisConnectionFactory
|
||||
.getIfAvailable();
|
||||
if (redisConnectionFactoryToUse == null) {
|
||||
redisConnectionFactoryToUse = redisConnectionFactory.getObject();
|
||||
}
|
||||
this.redisConnectionFactory = redisConnectionFactoryToUse;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setEmbeddedValueResolver(StringValueResolver resolver) {
|
||||
this.embeddedValueResolver = resolver;
|
||||
@@ -127,12 +141,4 @@ public class RedisWebSessionConfiguration extends SpringWebSessionConfiguration
|
||||
return new ReactiveRedisTemplate<>(connectionFactory, serializationContext);
|
||||
}
|
||||
|
||||
private String getRedisNamespace() {
|
||||
if (StringUtils.hasText(this.redisNamespace)) {
|
||||
return this.redisNamespace;
|
||||
}
|
||||
|
||||
return System.getProperty("spring.session.redis.namespace", "");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.serializer.RedisSerializer;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
@@ -35,6 +35,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@@ -18,14 +18,20 @@ package org.springframework.session.data.redis.config.annotation.web.server;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Primary;
|
||||
import org.springframework.data.redis.connection.ReactiveRedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.ReactiveRedisOperations;
|
||||
import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.RedisFlushMode;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisConnectionFactory;
|
||||
import org.springframework.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -42,6 +48,9 @@ public class RedisWebSessionConfigurationTests {
|
||||
|
||||
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600;
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
@@ -58,7 +67,7 @@ public class RedisWebSessionConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
registerAndRefresh(RedisConfiguration.class, DefaultConfiguration.class);
|
||||
registerAndRefresh(RedisConfig.class, DefaultConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
@@ -67,7 +76,7 @@ public class RedisWebSessionConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void customNamespace() {
|
||||
registerAndRefresh(RedisConfiguration.class, CustomNamespaceConfiguration.class);
|
||||
registerAndRefresh(RedisConfig.class, CustomNamespaceConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
@@ -78,8 +87,7 @@ public class RedisWebSessionConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void customMaxInactiveInterval() {
|
||||
registerAndRefresh(RedisConfiguration.class,
|
||||
CustomMaxInactiveIntervalConfiguration.class);
|
||||
registerAndRefresh(RedisConfig.class, CustomMaxInactiveIntervalConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
@@ -90,7 +98,7 @@ public class RedisWebSessionConfigurationTests {
|
||||
|
||||
@Test
|
||||
public void customFlushMode() {
|
||||
registerAndRefresh(RedisConfiguration.class, CustomFlushModeConfiguration.class);
|
||||
registerAndRefresh(RedisConfig.class, CustomFlushModeConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
@@ -99,13 +107,160 @@ public class RedisWebSessionConfigurationTests {
|
||||
.isEqualTo(RedisFlushMode.IMMEDIATE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean(
|
||||
"qualifiedRedisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void primaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, PrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean(
|
||||
"primaryRedisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedAndPrimaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedAndPrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context.getBean(
|
||||
"qualifiedRedisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, NamedConnectionFactoryRedisConfig.class);
|
||||
|
||||
ReactiveRedisOperationsSessionRepository repository = this.context
|
||||
.getBean(ReactiveRedisOperationsSessionRepository.class);
|
||||
ReactiveRedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("redisConnectionFactory", ReactiveRedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
ReactiveRedisOperations redisOperations = (ReactiveRedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleConnectionFactoryRedisConfig() {
|
||||
this.thrown.expect(BeanCreationException.class);
|
||||
this.thrown.expectMessage("expected single matching bean but found 2");
|
||||
|
||||
registerAndRefresh(RedisConfig.class, MultipleConnectionFactoryRedisConfig.class);
|
||||
}
|
||||
|
||||
private void registerAndRefresh(Class<?>... annotatedClasses) {
|
||||
this.context.register(annotatedClasses);
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class RedisConfiguration {
|
||||
static class RedisConfig {
|
||||
|
||||
@Bean
|
||||
public ReactiveRedisConnectionFactory defaultRedisConnectionFactory() {
|
||||
return mock(ReactiveRedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession
|
||||
static class DefaultConfig {
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession(redisNamespace = REDIS_NAMESPACE)
|
||||
static class CustomNamespaceConfig {
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
static class CustomMaxInactiveIntervalConfig {
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession(redisFlushMode = RedisFlushMode.IMMEDIATE)
|
||||
static class CustomFlushModeConfig {
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession
|
||||
static class QualifiedConnectionFactoryRedisConfig {
|
||||
|
||||
@Bean
|
||||
@SpringSessionRedisConnectionFactory
|
||||
public ReactiveRedisConnectionFactory qualifiedRedisConnectionFactory() {
|
||||
return mock(ReactiveRedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession
|
||||
static class PrimaryConnectionFactoryRedisConfig {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public ReactiveRedisConnectionFactory primaryRedisConnectionFactory() {
|
||||
return mock(ReactiveRedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession
|
||||
static class QualifiedAndPrimaryConnectionFactoryRedisConfig {
|
||||
|
||||
@Bean
|
||||
@SpringSessionRedisConnectionFactory
|
||||
public ReactiveRedisConnectionFactory qualifiedRedisConnectionFactory() {
|
||||
return mock(ReactiveRedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public ReactiveRedisConnectionFactory primaryRedisConnectionFactory() {
|
||||
return mock(ReactiveRedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@EnableRedisWebSession
|
||||
static class NamedConnectionFactoryRedisConfig {
|
||||
|
||||
@Bean
|
||||
public ReactiveRedisConnectionFactory redisConnectionFactory() {
|
||||
@@ -114,27 +269,13 @@ public class RedisWebSessionConfigurationTests {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisWebSession
|
||||
static class DefaultConfiguration {
|
||||
static class MultipleConnectionFactoryRedisConfig {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisWebSession(redisNamespace = REDIS_NAMESPACE)
|
||||
static class CustomNamespaceConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisWebSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
|
||||
static class CustomMaxInactiveIntervalConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisWebSession(redisFlushMode = RedisFlushMode.IMMEDIATE)
|
||||
static class CustomFlushModeConfiguration {
|
||||
@Bean
|
||||
public ReactiveRedisConnectionFactory secondaryRedisConnectionFactory() {
|
||||
return mock(ReactiveRedisConnectionFactory.class);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user