Improve Redis configuration
This commit improves Redis configuration by introducing `@SpringSessionRedisConnectionFactory` qualifier for explicitly declaring a `RedisConnectionFactory` to be used by Spring Session. This is in particular useful in scenarios with multiple `RedisConnectionFactory` beans present in the application context. Redis configuration is simplified and no longer registers a Spring Session specific `RedisOperations<Object,Object>` bean with the application context. Users are however able to obtain `RedisOperations<Object,Object>` instance used by Spring Session using newly introduced `@SpringSessionRedisOperations` annotation.
This commit is contained in:
@@ -38,6 +38,7 @@ 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.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;
|
||||
@@ -61,7 +62,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
@Autowired
|
||||
private SessionEventRegistry registry;
|
||||
|
||||
@Autowired
|
||||
@SpringSessionRedisOperations
|
||||
private RedisOperations<Object, Object> redis;
|
||||
|
||||
private SecurityContext context;
|
||||
|
||||
@@ -32,6 +32,7 @@ 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.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;
|
||||
@@ -49,7 +50,7 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
@Autowired
|
||||
private SessionTaskExecutor executor;
|
||||
|
||||
@Autowired
|
||||
@SpringSessionRedisOperations
|
||||
private RedisOperations<Object, Object> redis;
|
||||
|
||||
@Test
|
||||
|
||||
@@ -385,6 +385,10 @@ public class RedisOperationsSessionRepository implements
|
||||
this.redisFlushMode = redisFlushMode;
|
||||
}
|
||||
|
||||
public RedisOperations<Object, Object> getSessionRedisOperations() {
|
||||
return this.sessionRedisOperations;
|
||||
}
|
||||
|
||||
public void save(RedisSession session) {
|
||||
session.saveDelta();
|
||||
if (session.isNew()) {
|
||||
|
||||
@@ -17,12 +17,14 @@
|
||||
package org.springframework.session.data.redis.config.annotation.web.http;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.ObjectProvider;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
@@ -35,7 +37,6 @@ import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.listener.PatternTopic;
|
||||
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
|
||||
@@ -59,6 +60,7 @@ import org.springframework.util.StringValueResolver;
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Eddú Meléndez
|
||||
* @author Vedran Pavic
|
||||
* @see EnableRedisHttpSession
|
||||
* @since 1.0
|
||||
*/
|
||||
@@ -69,12 +71,14 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
|
||||
private Integer maxInactiveIntervalInSeconds = 1800;
|
||||
|
||||
private ConfigureRedisAction configureRedisAction = new ConfigureNotifyKeyspaceEventsAction();
|
||||
|
||||
private String redisNamespace = "";
|
||||
|
||||
private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE;
|
||||
|
||||
private ConfigureRedisAction configureRedisAction = new ConfigureNotifyKeyspaceEventsAction();
|
||||
|
||||
private RedisConnectionFactory redisConnectionFactory;
|
||||
|
||||
private RedisSerializer<Object> defaultRedisSerializer;
|
||||
|
||||
private Executor redisTaskExecutor;
|
||||
@@ -84,12 +88,31 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
private StringValueResolver embeddedValueResolver;
|
||||
|
||||
@Bean
|
||||
public RedisMessageListenerContainer redisMessageListenerContainer(
|
||||
RedisConnectionFactory connectionFactory,
|
||||
RedisOperationsSessionRepository messageListener) {
|
||||
public RedisOperationsSessionRepository sessionRepository(
|
||||
ApplicationEventPublisher applicationEventPublisher) {
|
||||
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate(
|
||||
this.redisConnectionFactory, this.defaultRedisSerializer);
|
||||
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
|
||||
redisTemplate);
|
||||
sessionRepository.setApplicationEventPublisher(applicationEventPublisher);
|
||||
if (this.defaultRedisSerializer != null) {
|
||||
sessionRepository.setDefaultSerializer(this.defaultRedisSerializer);
|
||||
}
|
||||
sessionRepository
|
||||
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
String redisNamespace = getRedisNamespace();
|
||||
if (StringUtils.hasText(redisNamespace)) {
|
||||
sessionRepository.setRedisKeyNamespace(redisNamespace);
|
||||
}
|
||||
sessionRepository.setRedisFlushMode(this.redisFlushMode);
|
||||
return sessionRepository;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisMessageListenerContainer redisMessageListenerContainer(
|
||||
RedisOperationsSessionRepository messageListener) {
|
||||
RedisMessageListenerContainer container = new RedisMessageListenerContainer();
|
||||
container.setConnectionFactory(connectionFactory);
|
||||
container.setConnectionFactory(this.redisConnectionFactory);
|
||||
if (this.redisTaskExecutor != null) {
|
||||
container.setTaskExecutor(this.redisTaskExecutor);
|
||||
}
|
||||
@@ -99,44 +122,25 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
container.addMessageListener(messageListener,
|
||||
Arrays.asList(new PatternTopic("__keyevent@*:del"),
|
||||
new PatternTopic("__keyevent@*:expired")));
|
||||
container.addMessageListener(messageListener, Arrays.asList(new PatternTopic(
|
||||
messageListener.getSessionCreatedChannelPrefix() + "*")));
|
||||
container.addMessageListener(messageListener,
|
||||
Collections.singletonList(new PatternTopic(
|
||||
messageListener.getSessionCreatedChannelPrefix() + "*")));
|
||||
return container;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RedisTemplate<Object, Object> sessionRedisTemplate(
|
||||
RedisConnectionFactory connectionFactory) {
|
||||
RedisTemplate<Object, Object> template = new RedisTemplate<>();
|
||||
template.setKeySerializer(new StringRedisSerializer());
|
||||
template.setHashKeySerializer(new StringRedisSerializer());
|
||||
if (this.defaultRedisSerializer != null) {
|
||||
template.setDefaultSerializer(this.defaultRedisSerializer);
|
||||
}
|
||||
template.setConnectionFactory(connectionFactory);
|
||||
return template;
|
||||
public InitializingBean enableRedisKeyspaceNotificationsInitializer() {
|
||||
return new EnableRedisKeyspaceNotificationsInitializer(
|
||||
this.redisConnectionFactory, this.configureRedisAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Property placeholder to process the @Scheduled annotation.
|
||||
* @return the {@link PropertySourcesPlaceholderConfigurer} to use
|
||||
*/
|
||||
@Bean
|
||||
public RedisOperationsSessionRepository sessionRepository(
|
||||
@Qualifier("sessionRedisTemplate") RedisOperations<Object, Object> sessionRedisTemplate,
|
||||
ApplicationEventPublisher applicationEventPublisher) {
|
||||
RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(
|
||||
sessionRedisTemplate);
|
||||
sessionRepository.setApplicationEventPublisher(applicationEventPublisher);
|
||||
sessionRepository
|
||||
.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
|
||||
if (this.defaultRedisSerializer != null) {
|
||||
sessionRepository.setDefaultSerializer(this.defaultRedisSerializer);
|
||||
}
|
||||
|
||||
String redisNamespace = getRedisNamespace();
|
||||
if (StringUtils.hasText(redisNamespace)) {
|
||||
sessionRepository.setRedisKeyNamespace(redisNamespace);
|
||||
}
|
||||
|
||||
sessionRepository.setRedisFlushMode(this.redisFlushMode);
|
||||
return sessionRepository;
|
||||
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
}
|
||||
|
||||
public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) {
|
||||
@@ -152,45 +156,29 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
this.redisFlushMode = redisFlushMode;
|
||||
}
|
||||
|
||||
private String getRedisNamespace() {
|
||||
if (StringUtils.hasText(this.redisNamespace)) {
|
||||
return this.redisNamespace;
|
||||
}
|
||||
return System.getProperty("spring.session.redis.namespace", "");
|
||||
}
|
||||
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
|
||||
Map<String, Object> enableAttrMap = importMetadata
|
||||
.getAnnotationAttributes(EnableRedisHttpSession.class.getName());
|
||||
AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
|
||||
this.maxInactiveIntervalInSeconds = enableAttrs
|
||||
.getNumber("maxInactiveIntervalInSeconds");
|
||||
String redisNamespaceValue = enableAttrs.getString("redisNamespace");
|
||||
if (StringUtils.hasText(redisNamespaceValue)) {
|
||||
this.redisNamespace = this.embeddedValueResolver.resolveStringValue(redisNamespaceValue);
|
||||
}
|
||||
this.redisFlushMode = enableAttrs.getEnum("redisFlushMode");
|
||||
}
|
||||
|
||||
@Bean
|
||||
public InitializingBean enableRedisKeyspaceNotificationsInitializer(
|
||||
RedisConnectionFactory connectionFactory) {
|
||||
return new EnableRedisKeyspaceNotificationsInitializer(connectionFactory,
|
||||
this.configureRedisAction);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the action to perform for configuring Redis.
|
||||
*
|
||||
* @param configureRedisAction the configureRedis to set. The default is
|
||||
* {@link ConfigureNotifyKeyspaceEventsAction}.
|
||||
* {@link ConfigureNotifyKeyspaceEventsAction}.
|
||||
*/
|
||||
@Autowired(required = false)
|
||||
public void setConfigureRedisAction(ConfigureRedisAction configureRedisAction) {
|
||||
this.configureRedisAction = configureRedisAction;
|
||||
}
|
||||
|
||||
@Autowired
|
||||
public void setRedisConnectionFactory(
|
||||
@SpringSessionRedisConnectionFactory ObjectProvider<RedisConnectionFactory> springSessionRedisConnectionFactory,
|
||||
ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
|
||||
RedisConnectionFactory redisConnectionFactoryToUse = springSessionRedisConnectionFactory
|
||||
.getIfAvailable();
|
||||
if (redisConnectionFactoryToUse == null) {
|
||||
redisConnectionFactoryToUse = redisConnectionFactory.getObject();
|
||||
}
|
||||
this.redisConnectionFactory = redisConnectionFactoryToUse;
|
||||
}
|
||||
|
||||
@Autowired(required = false)
|
||||
@Qualifier("springSessionDefaultRedisSerializer")
|
||||
public void setDefaultRedisSerializer(
|
||||
@@ -214,13 +202,39 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
this.embeddedValueResolver = resolver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Property placeholder to process the @Scheduled annotation.
|
||||
* @return the {@link PropertySourcesPlaceholderConfigurer} to use
|
||||
*/
|
||||
@Bean
|
||||
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
|
||||
return new PropertySourcesPlaceholderConfigurer();
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
Map<String, Object> enableAttrMap = importMetadata
|
||||
.getAnnotationAttributes(EnableRedisHttpSession.class.getName());
|
||||
AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap);
|
||||
this.maxInactiveIntervalInSeconds = enableAttrs
|
||||
.getNumber("maxInactiveIntervalInSeconds");
|
||||
String redisNamespaceValue = enableAttrs.getString("redisNamespace");
|
||||
if (StringUtils.hasText(redisNamespaceValue)) {
|
||||
this.redisNamespace = this.embeddedValueResolver
|
||||
.resolveStringValue(redisNamespaceValue);
|
||||
}
|
||||
this.redisFlushMode = enableAttrs.getEnum("redisFlushMode");
|
||||
}
|
||||
|
||||
private static RedisTemplate<Object, Object> createRedisTemplate(
|
||||
RedisConnectionFactory redisConnectionFactory,
|
||||
RedisSerializer<Object> defaultRedisSerializer) {
|
||||
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setKeySerializer(new StringRedisSerializer());
|
||||
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
|
||||
if (defaultRedisSerializer != null) {
|
||||
redisTemplate.setDefaultSerializer(defaultRedisSerializer);
|
||||
}
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return redisTemplate;
|
||||
}
|
||||
|
||||
private String getRedisNamespace() {
|
||||
if (StringUtils.hasText(this.redisNamespace)) {
|
||||
return this.redisNamespace;
|
||||
}
|
||||
return System.getProperty("spring.session.redis.namespace", "");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,6 +245,7 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
* up.
|
||||
*/
|
||||
static class EnableRedisKeyspaceNotificationsInitializer implements InitializingBean {
|
||||
|
||||
private final RedisConnectionFactory connectionFactory;
|
||||
|
||||
private ConfigureRedisAction configure;
|
||||
@@ -255,10 +270,12 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
|
||||
connection.close();
|
||||
}
|
||||
catch (Exception e) {
|
||||
LogFactory.getLog(getClass()).error("Error closing RedisConnection", e);
|
||||
LogFactory.getLog(getClass()).error("Error closing RedisConnection",
|
||||
e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.session.data.redis.config.annotation.web.http;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
|
||||
/**
|
||||
* Qualifier annotation for a {@link RedisConnectionFactory} to be injected in
|
||||
* {@link RedisOperationsSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE,
|
||||
ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Qualifier
|
||||
public @interface SpringSessionRedisConnectionFactory {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2014-2017 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.session.data.redis.config.annotation.web.http;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.data.redis.core.RedisOperations;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
|
||||
/**
|
||||
* Annotation used to inject the {@link RedisOperations} instance used by Spring Session's
|
||||
* {@link RedisOperationsSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0.0
|
||||
*/
|
||||
@Target({ ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER,
|
||||
ElementType.ANNOTATION_TYPE })
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Value("#{sessionRepository.sessionRedisOperations}")
|
||||
public @interface SpringSessionRedisOperations {
|
||||
|
||||
}
|
||||
@@ -47,7 +47,7 @@ import static org.mockito.Mockito.mock;
|
||||
@WebAppConfiguration
|
||||
public class RedisHttpSessionConfigurationOverrideDefaultSerializerTests {
|
||||
|
||||
@Autowired
|
||||
@SpringSessionRedisOperations
|
||||
RedisTemplate<Object, Object> template;
|
||||
|
||||
@Autowired
|
||||
|
||||
@@ -20,15 +20,21 @@ import java.util.Properties;
|
||||
|
||||
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.context.support.PropertySourcesPlaceholderConfigurer;
|
||||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
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.test.util.ReflectionTestUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
@@ -37,11 +43,17 @@ import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
|
||||
/**
|
||||
* Tests for {@link RedisHttpSessionConfiguration}.
|
||||
*
|
||||
* @author Eddú Meléndez
|
||||
* @author Mark Paluch
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class RedisHttpSessionConfigurationTests {
|
||||
|
||||
@Rule
|
||||
public final ExpectedException thrown = ExpectedException.none();
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@Before
|
||||
@@ -59,16 +71,101 @@ public class RedisHttpSessionConfigurationTests {
|
||||
@Test
|
||||
public void resolveValue() {
|
||||
registerAndRefresh(RedisConfig.class, CustomRedisHttpSessionConfiguration.class);
|
||||
RedisHttpSessionConfiguration configuration = this.context.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace")).isEqualTo("myRedisNamespace");
|
||||
RedisHttpSessionConfiguration configuration = this.context
|
||||
.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace"))
|
||||
.isEqualTo("myRedisNamespace");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void resolveValueByPlaceholder() {
|
||||
this.context.setEnvironment(new MockEnvironment().withProperty("session.redis.namespace", "customRedisNamespace"));
|
||||
registerAndRefresh(RedisConfig.class, PropertySourceConfiguration.class, CustomRedisHttpSessionConfiguration2.class);
|
||||
RedisHttpSessionConfiguration configuration = this.context.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace")).isEqualTo("customRedisNamespace");
|
||||
this.context.setEnvironment(new MockEnvironment()
|
||||
.withProperty("session.redis.namespace", "customRedisNamespace"));
|
||||
registerAndRefresh(RedisConfig.class, PropertySourceConfiguration.class,
|
||||
CustomRedisHttpSessionConfiguration2.class);
|
||||
RedisHttpSessionConfiguration configuration = this.context
|
||||
.getBean(RedisHttpSessionConfiguration.class);
|
||||
assertThat(ReflectionTestUtils.getField(configuration, "redisNamespace"))
|
||||
.isEqualTo("customRedisNamespace");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("qualifiedRedisConnectionFactory", RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void primaryConnectionFactoryRedisConfig() {
|
||||
registerAndRefresh(RedisConfig.class, PrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("primaryRedisConnectionFactory", RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void qualifiedAndPrimaryDataSourceConfiguration() {
|
||||
registerAndRefresh(RedisConfig.class,
|
||||
QualifiedAndPrimaryConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("qualifiedRedisConnectionFactory", RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void namedDataSourceConfiguration() {
|
||||
registerAndRefresh(RedisConfig.class, NamedConnectionFactoryRedisConfig.class);
|
||||
|
||||
RedisOperationsSessionRepository repository = this.context
|
||||
.getBean(RedisOperationsSessionRepository.class);
|
||||
RedisConnectionFactory redisConnectionFactory = this.context
|
||||
.getBean("redisConnectionFactory", RedisConnectionFactory.class);
|
||||
assertThat(repository).isNotNull();
|
||||
assertThat(redisConnectionFactory).isNotNull();
|
||||
RedisOperations redisOperations = (RedisOperations) ReflectionTestUtils
|
||||
.getField(repository, "sessionRedisOperations");
|
||||
assertThat(redisOperations).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(redisOperations, "connectionFactory"))
|
||||
.isEqualTo(redisConnectionFactory);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void multipleDataSourceConfiguration() {
|
||||
this.thrown.expect(BeanCreationException.class);
|
||||
this.thrown.expectMessage(
|
||||
"secondaryRedisConnectionFactory,defaultRedisConnectionFactory");
|
||||
|
||||
registerAndRefresh(MultipleConnectionFactoryRedisConfig.class);
|
||||
}
|
||||
|
||||
private void registerAndRefresh(Class<?>... annotatedClasses) {
|
||||
@@ -76,6 +173,14 @@ public class RedisHttpSessionConfigurationTests {
|
||||
this.context.refresh();
|
||||
}
|
||||
|
||||
private static RedisConnectionFactory mockRedisConnectionFactory() {
|
||||
RedisConnectionFactory connectionFactory = mock(RedisConnectionFactory.class);
|
||||
RedisConnection connection = mock(RedisConnection.class);
|
||||
given(connectionFactory.getConnection()).willReturn(connection);
|
||||
given(connection.getConfig(anyString())).willReturn(new Properties());
|
||||
return connectionFactory;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
static class PropertySourceConfiguration {
|
||||
|
||||
@@ -89,13 +194,73 @@ public class RedisHttpSessionConfigurationTests {
|
||||
@Configuration
|
||||
static class RedisConfig {
|
||||
|
||||
@Bean
|
||||
public RedisConnectionFactory defaultRedisConnectionFactory() {
|
||||
return mockRedisConnectionFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
static class QualifiedConnectionFactoryRedisConfig extends RedisConfig {
|
||||
|
||||
@Bean
|
||||
@SpringSessionRedisConnectionFactory
|
||||
public RedisConnectionFactory qualifiedRedisConnectionFactory() {
|
||||
return mockRedisConnectionFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
static class PrimaryConnectionFactoryRedisConfig extends RedisConfig {
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public RedisConnectionFactory primaryRedisConnectionFactory() {
|
||||
return mockRedisConnectionFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
static class QualifiedAndPrimaryConnectionFactoryRedisConfig extends RedisConfig {
|
||||
|
||||
@Bean
|
||||
@SpringSessionRedisConnectionFactory
|
||||
public RedisConnectionFactory qualifiedRedisConnectionFactory() {
|
||||
return mockRedisConnectionFactory();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Primary
|
||||
public RedisConnectionFactory primaryRedisConnectionFactory() {
|
||||
return mockRedisConnectionFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
static class NamedConnectionFactoryRedisConfig extends RedisConfig {
|
||||
|
||||
@Bean
|
||||
public RedisConnectionFactory redisConnectionFactory() {
|
||||
RedisConnectionFactory connectionFactory = mock(RedisConnectionFactory.class);
|
||||
RedisConnection connection = mock(RedisConnection.class);
|
||||
given(connectionFactory.getConnection()).willReturn(connection);
|
||||
given(connection.getConfig(anyString())).willReturn(new Properties());
|
||||
return connectionFactory;
|
||||
return mockRedisConnectionFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession
|
||||
static class MultipleConnectionFactoryRedisConfig extends RedisConfig {
|
||||
|
||||
@Bean
|
||||
public RedisConnectionFactory secondaryRedisConnectionFactory() {
|
||||
return mockRedisConnectionFactory();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -63,7 +63,6 @@ public class Gh109Tests {
|
||||
* override sessionRepository construction to set the custom session-timeout
|
||||
*/
|
||||
@Bean
|
||||
@Override
|
||||
public RedisOperationsSessionRepository sessionRepository(
|
||||
RedisOperations<Object, Object> sessionRedisTemplate,
|
||||
ApplicationEventPublisher applicationEventPublisher) {
|
||||
|
||||
Reference in New Issue
Block a user