Add support for configuring custom IndexResolver

See: #1467
This commit is contained in:
Vedran Pavic
2019-09-26 22:18:37 +02:00
parent b357a76ce3
commit feaf8780a8
9 changed files with 144 additions and 13 deletions

View File

@@ -280,8 +280,6 @@ public class RedisIndexedSessionRepository
private final RedisSessionExpirationPolicy expirationPolicy;
private final IndexResolver<RedisSession> indexResolver;
private ApplicationEventPublisher eventPublisher = (event) -> {
};
@@ -291,6 +289,8 @@ public class RedisIndexedSessionRepository
*/
private Integer defaultMaxInactiveInterval;
private IndexResolver<Session> indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
private RedisSerializer<Object> defaultSerializer = new JdkSerializationRedisSerializer();
private FlushMode flushMode = FlushMode.ON_SAVE;
@@ -307,7 +307,6 @@ public class RedisIndexedSessionRepository
this.sessionRedisOperations = sessionRedisOperations;
this.expirationPolicy = new RedisSessionExpirationPolicy(sessionRedisOperations, this::getExpirationsKey,
this::getSessionKey);
this.indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
configureSessionChannels();
}
@@ -334,6 +333,15 @@ public class RedisIndexedSessionRepository
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
}
/**
* Set the {@link IndexResolver} to use.
* @param indexResolver the index resolver
*/
public void setIndexResolver(IndexResolver<Session> indexResolver) {
Assert.notNull(indexResolver, "indexResolver cannot be null");
this.indexResolver = indexResolver;
}
/**
* Sets the default redis serializer. Replaces default serializer which is based on
* {@link JdkSerializationRedisSerializer}.

View File

@@ -51,8 +51,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.MapSession;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.data.redis.RedisFlushMode;
@@ -98,6 +100,8 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
private RedisConnectionFactory redisConnectionFactory;
private IndexResolver<Session> indexResolver;
private RedisSerializer<Object> defaultRedisSerializer;
private ApplicationEventPublisher applicationEventPublisher;
@@ -117,6 +121,9 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
RedisTemplate<Object, Object> redisTemplate = createRedisTemplate();
RedisIndexedSessionRepository sessionRepository = new RedisIndexedSessionRepository(redisTemplate);
sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher);
if (this.indexResolver != null) {
sessionRepository.setIndexResolver(this.indexResolver);
}
if (this.defaultRedisSerializer != null) {
sessionRepository.setDefaultSerializer(this.defaultRedisSerializer);
}
@@ -216,6 +223,11 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
this.applicationEventPublisher = applicationEventPublisher;
}
@Autowired(required = false)
public void setIndexResolver(IndexResolver<Session> indexResolver) {
this.indexResolver = indexResolver;
}
@Autowired(required = false)
@Qualifier("springSessionRedisTaskExecutor")
public void setRedisTaskExecutor(Executor redisTaskExecutor) {

View File

@@ -36,7 +36,9 @@ import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.session.data.redis.RedisFlushMode;
import org.springframework.session.data.redis.RedisIndexedSessionRepository;
@@ -228,6 +230,17 @@ class RedisHttpSessionConfigurationTests {
.withMessageContaining("expected single matching bean but found 2");
}
@Test
void customIndexResolverConfiguration() {
registerAndRefresh(RedisConfig.class, CustomIndexResolverConfiguration.class);
RedisIndexedSessionRepository repository = this.context.getBean(RedisIndexedSessionRepository.class);
@SuppressWarnings("unchecked")
IndexResolver<Session> indexResolver = this.context.getBean(IndexResolver.class);
assertThat(repository).isNotNull();
assertThat(indexResolver).isNotNull();
assertThat(repository).hasFieldOrPropertyWithValue("indexResolver", indexResolver);
}
@Test // gh-1252
void customRedisMessageListenerContainerConfig() {
registerAndRefresh(RedisConfig.class, CustomRedisMessageListenerContainerConfig.class);
@@ -414,6 +427,18 @@ class RedisHttpSessionConfigurationTests {
}
@Configuration
@EnableRedisHttpSession
static class CustomIndexResolverConfiguration {
@Bean
@SuppressWarnings("unchecked")
public IndexResolver<Session> indexResolver() {
return mock(IndexResolver.class);
}
}
@Configuration
@EnableRedisHttpSession
static class CustomRedisMessageListenerContainerConfig {

View File

@@ -133,8 +133,6 @@ public class HazelcastIndexedSessionRepository
private final HazelcastInstance hazelcastInstance;
private final IndexResolver<HazelcastSession> indexResolver;
private ApplicationEventPublisher eventPublisher = (event) -> {
};
@@ -144,6 +142,8 @@ public class HazelcastIndexedSessionRepository
*/
private Integer defaultMaxInactiveInterval;
private IndexResolver<Session> indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
private String sessionMapName = DEFAULT_SESSION_MAP_NAME;
private FlushMode flushMode = FlushMode.ON_SAVE;
@@ -161,7 +161,6 @@ public class HazelcastIndexedSessionRepository
public HazelcastIndexedSessionRepository(HazelcastInstance hazelcastInstance) {
Assert.notNull(hazelcastInstance, "HazelcastInstance must not be null");
this.hazelcastInstance = hazelcastInstance;
this.indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
}
@PostConstruct
@@ -197,6 +196,15 @@ public class HazelcastIndexedSessionRepository
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
}
/**
* Set the {@link IndexResolver} to use.
* @param indexResolver the index resolver
*/
public void setIndexResolver(IndexResolver<Session> indexResolver) {
Assert.notNull(indexResolver, "indexResolver cannot be null");
this.indexResolver = indexResolver;
}
/**
* Set the name of map used to store sessions.
* @param sessionMapName the session map name

View File

@@ -31,8 +31,10 @@ import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.MapSession;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.hazelcast.HazelcastFlushMode;
@@ -66,6 +68,8 @@ public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfigur
private ApplicationEventPublisher applicationEventPublisher;
private IndexResolver<Session> indexResolver;
private List<SessionRepositoryCustomizer<HazelcastIndexedSessionRepository>> sessionRepositoryCustomizers;
@Bean
@@ -73,6 +77,9 @@ public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfigur
HazelcastIndexedSessionRepository sessionRepository = new HazelcastIndexedSessionRepository(
this.hazelcastInstance);
sessionRepository.setApplicationEventPublisher(this.applicationEventPublisher);
if (this.indexResolver != null) {
sessionRepository.setIndexResolver(this.indexResolver);
}
if (StringUtils.hasText(this.sessionMapName)) {
sessionRepository.setSessionMapName(this.sessionMapName);
}
@@ -121,6 +128,11 @@ public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfigur
this.applicationEventPublisher = applicationEventPublisher;
}
@Autowired(required = false)
public void setIndexResolver(IndexResolver<Session> indexResolver) {
this.indexResolver = indexResolver;
}
@Autowired(required = false)
public void setSessionRepositoryCustomizer(
ObjectProvider<SessionRepositoryCustomizer<HazelcastIndexedSessionRepository>> sessionRepositoryCustomizers) {

View File

@@ -28,7 +28,9 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.annotation.Order;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.session.hazelcast.HazelcastFlushMode;
import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository;
@@ -223,6 +225,17 @@ class HazelcastHttpSessionConfigurationTests {
.withMessageContaining("expected single matching bean but found 2");
}
@Test
void customIndexResolverConfiguration() {
registerAndRefresh(CustomIndexResolverConfiguration.class);
HazelcastIndexedSessionRepository repository = this.context.getBean(HazelcastIndexedSessionRepository.class);
@SuppressWarnings("unchecked")
IndexResolver<Session> indexResolver = this.context.getBean(IndexResolver.class);
assertThat(repository).isNotNull();
assertThat(indexResolver).isNotNull();
assertThat(repository).hasFieldOrPropertyWithValue("indexResolver", indexResolver);
}
@Test
void sessionRepositoryCustomizer() {
registerAndRefresh(SessionRepositoryCustomizerConfiguration.class);
@@ -433,6 +446,17 @@ class HazelcastHttpSessionConfigurationTests {
}
@EnableHazelcastHttpSession
static class CustomIndexResolverConfiguration extends BaseConfiguration {
@Bean
@SuppressWarnings("unchecked")
public IndexResolver<Session> indexResolver() {
return mock(IndexResolver.class);
}
}
@EnableHazelcastHttpSession
static class SessionRepositoryCustomizerConfiguration extends BaseConfiguration {

View File

@@ -198,8 +198,6 @@ public class JdbcIndexedSessionRepository
private final ResultSetExtractor<List<JdbcSession>> extractor = new SessionResultSetExtractor();
private final IndexResolver<JdbcSession> indexResolver;
/**
* The name of database table used by Spring Session to store sessions.
*/
@@ -229,9 +227,11 @@ public class JdbcIndexedSessionRepository
*/
private Integer defaultMaxInactiveInterval;
private ConversionService conversionService;
private IndexResolver<Session> indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
private LobHandler lobHandler;
private ConversionService conversionService = createDefaultConversionService();
private LobHandler lobHandler = new DefaultLobHandler();
private FlushMode flushMode = FlushMode.ON_SAVE;
@@ -248,9 +248,6 @@ public class JdbcIndexedSessionRepository
Assert.notNull(transactionOperations, "transactionOperations must not be null");
this.jdbcOperations = jdbcOperations;
this.transactionOperations = transactionOperations;
this.indexResolver = new DelegatingIndexResolver<>(new PrincipalNameIndexResolver<>());
this.conversionService = createDefaultConversionService();
this.lobHandler = new DefaultLobHandler();
prepareQueries();
}
@@ -355,6 +352,15 @@ public class JdbcIndexedSessionRepository
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
}
/**
* Set the {@link IndexResolver} to use.
* @param indexResolver the index resolver
*/
public void setIndexResolver(IndexResolver<Session> indexResolver) {
Assert.notNull(indexResolver, "indexResolver cannot be null");
this.indexResolver = indexResolver;
}
public void setLobHandler(LobHandler lobHandler) {
Assert.notNull(lobHandler, "LobHandler must not be null");
this.lobHandler = lobHandler;

View File

@@ -45,8 +45,10 @@ import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
import org.springframework.scheduling.config.ScheduledTaskRegistrar;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.MapSession;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.jdbc.JdbcIndexedSessionRepository;
@@ -95,6 +97,8 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
private TransactionOperations transactionOperations;
private IndexResolver<Session> indexResolver;
private LobHandler lobHandler;
private ConversionService springSessionConversionService;
@@ -121,6 +125,9 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
sessionRepository.setDefaultMaxInactiveInterval(this.maxInactiveIntervalInSeconds);
sessionRepository.setFlushMode(this.flushMode);
sessionRepository.setSaveMode(this.saveMode);
if (this.indexResolver != null) {
sessionRepository.setIndexResolver(this.indexResolver);
}
if (this.lobHandler != null) {
sessionRepository.setLobHandler(this.lobHandler);
}
@@ -194,6 +201,11 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
this.transactionOperations = transactionOperations;
}
@Autowired(required = false)
public void setIndexResolver(IndexResolver<Session> indexResolver) {
this.indexResolver = indexResolver;
}
@Autowired(required = false)
@Qualifier("springSessionLobHandler")
public void setLobHandler(LobHandler lobHandler) {

View File

@@ -33,7 +33,9 @@ import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.mock.env.MockEnvironment;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.session.jdbc.JdbcIndexedSessionRepository;
import org.springframework.session.jdbc.config.annotation.SpringSessionDataSource;
@@ -242,6 +244,17 @@ class JdbcHttpSessionConfigurationTests {
assertThat(repository).hasFieldOrPropertyWithValue("transactionOperations", transactionOperations);
}
@Test
void customIndexResolverConfiguration() {
registerAndRefresh(DataSourceConfiguration.class, CustomIndexResolverConfiguration.class);
JdbcIndexedSessionRepository repository = this.context.getBean(JdbcIndexedSessionRepository.class);
@SuppressWarnings("unchecked")
IndexResolver<Session> indexResolver = this.context.getBean(IndexResolver.class);
assertThat(repository).isNotNull();
assertThat(indexResolver).isNotNull();
assertThat(repository).hasFieldOrPropertyWithValue("indexResolver", indexResolver);
}
@Test
void customLobHandlerConfiguration() {
registerAndRefresh(DataSourceConfiguration.class, CustomLobHandlerConfiguration.class);
@@ -452,6 +465,17 @@ class JdbcHttpSessionConfigurationTests {
}
@EnableJdbcHttpSession
static class CustomIndexResolverConfiguration {
@Bean
@SuppressWarnings("unchecked")
public IndexResolver<Session> indexResolver() {
return mock(IndexResolver.class);
}
}
@EnableJdbcHttpSession
static class CustomLobHandlerConfiguration {