Add support for configuring Spring Session SaveMode
See gh-17514
This commit is contained in:
parent
b7d349db83
commit
e073792448
|
@ -59,6 +59,7 @@ class HazelcastSessionConfiguration {
|
|||
}
|
||||
setSessionMapName(hazelcastSessionProperties.getMapName());
|
||||
setFlushMode(hazelcastSessionProperties.getFlushMode());
|
||||
setSaveMode(hazelcastSessionProperties.getSaveMode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.session;
|
|||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.session.FlushMode;
|
||||
import org.springframework.session.SaveMode;
|
||||
|
||||
/**
|
||||
* Configuration properties for Hazelcast backed Spring Session.
|
||||
|
@ -38,6 +39,12 @@ public class HazelcastSessionProperties {
|
|||
*/
|
||||
private FlushMode flushMode = FlushMode.ON_SAVE;
|
||||
|
||||
/**
|
||||
* Sessions save mode. Determines how session changes are tracked and saved to the
|
||||
* session store.
|
||||
*/
|
||||
private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE;
|
||||
|
||||
public String getMapName() {
|
||||
return this.mapName;
|
||||
}
|
||||
|
@ -54,4 +61,12 @@ public class HazelcastSessionProperties {
|
|||
this.flushMode = flushMode;
|
||||
}
|
||||
|
||||
public SaveMode getSaveMode() {
|
||||
return this.saveMode;
|
||||
}
|
||||
|
||||
public void setSaveMode(SaveMode saveMode) {
|
||||
this.saveMode = saveMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ class JdbcSessionConfiguration {
|
|||
}
|
||||
setTableName(jdbcSessionProperties.getTableName());
|
||||
setCleanupCron(jdbcSessionProperties.getCleanupCron());
|
||||
setSaveMode(jdbcSessionProperties.getSaveMode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright 2012-2017 the original author or authors.
|
||||
* Copyright 2012-2019 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.
|
||||
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.session;
|
|||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.boot.jdbc.DataSourceInitializationMode;
|
||||
import org.springframework.session.SaveMode;
|
||||
|
||||
/**
|
||||
* Configuration properties for JDBC backed Spring Session.
|
||||
|
@ -55,6 +56,12 @@ public class JdbcSessionProperties {
|
|||
*/
|
||||
private DataSourceInitializationMode initializeSchema = DataSourceInitializationMode.EMBEDDED;
|
||||
|
||||
/**
|
||||
* Sessions save mode. Determines how session changes are tracked and saved to the
|
||||
* session store.
|
||||
*/
|
||||
private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE;
|
||||
|
||||
public String getSchema() {
|
||||
return this.schema;
|
||||
}
|
||||
|
@ -87,4 +94,12 @@ public class JdbcSessionProperties {
|
|||
this.initializeSchema = initializeSchema;
|
||||
}
|
||||
|
||||
public SaveMode getSaveMode() {
|
||||
return this.saveMode;
|
||||
}
|
||||
|
||||
public void setSaveMode(SaveMode saveMode) {
|
||||
this.saveMode = saveMode;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -53,6 +53,7 @@ class RedisReactiveSessionConfiguration {
|
|||
setMaxInactiveIntervalInSeconds((int) timeout.getSeconds());
|
||||
}
|
||||
setRedisNamespace(redisSessionProperties.getNamespace());
|
||||
setSaveMode(redisSessionProperties.getSaveMode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -76,6 +76,7 @@ class RedisSessionConfiguration {
|
|||
setRedisNamespace(redisSessionProperties.getNamespace());
|
||||
setFlushMode(redisSessionProperties.getFlushMode());
|
||||
setCleanupCron(redisSessionProperties.getCleanupCron());
|
||||
setSaveMode(redisSessionProperties.getSaveMode());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package org.springframework.boot.autoconfigure.session;
|
|||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.session.FlushMode;
|
||||
import org.springframework.session.SaveMode;
|
||||
|
||||
/**
|
||||
* Configuration properties for Redis backed Spring Session.
|
||||
|
@ -51,6 +52,12 @@ public class RedisSessionProperties {
|
|||
*/
|
||||
private String cleanupCron = DEFAULT_CLEANUP_CRON;
|
||||
|
||||
/**
|
||||
* Sessions save mode. Determines how session changes are tracked and saved to the
|
||||
* session store.
|
||||
*/
|
||||
private SaveMode saveMode = SaveMode.ON_SET_ATTRIBUTE;
|
||||
|
||||
public String getNamespace() {
|
||||
return this.namespace;
|
||||
}
|
||||
|
@ -83,6 +90,14 @@ public class RedisSessionProperties {
|
|||
this.configureAction = configureAction;
|
||||
}
|
||||
|
||||
public SaveMode getSaveMode() {
|
||||
return this.saveMode;
|
||||
}
|
||||
|
||||
public void setSaveMode(SaveMode saveMode) {
|
||||
this.saveMode = saveMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Strategies for configuring and validating Redis.
|
||||
*/
|
||||
|
|
|
@ -25,6 +25,7 @@ import org.springframework.boot.test.context.FilteredClassLoader;
|
|||
import org.springframework.boot.test.context.assertj.AssertableReactiveWebApplicationContext;
|
||||
import org.springframework.boot.test.context.runner.ContextConsumer;
|
||||
import org.springframework.boot.test.context.runner.ReactiveWebApplicationContextRunner;
|
||||
import org.springframework.session.SaveMode;
|
||||
import org.springframework.session.data.mongo.ReactiveMongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepository;
|
||||
|
||||
|
@ -47,7 +48,7 @@ class ReactiveSessionAutoConfigurationRedisTests extends AbstractSessionAutoConf
|
|||
this.contextRunner.withPropertyValues("spring.session.store-type=redis")
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class))
|
||||
.run(validateSpringSessionUsesRedis("spring:session:"));
|
||||
.run(validateSpringSessionUsesRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -55,7 +56,7 @@ class ReactiveSessionAutoConfigurationRedisTests extends AbstractSessionAutoConf
|
|||
this.contextRunner.withClassLoader(new FilteredClassLoader(ReactiveMongoOperationsSessionRepository.class))
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class))
|
||||
.run(validateSpringSessionUsesRedis("spring:session:"));
|
||||
.run(validateSpringSessionUsesRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -63,15 +64,18 @@ class ReactiveSessionAutoConfigurationRedisTests extends AbstractSessionAutoConf
|
|||
this.contextRunner
|
||||
.withConfiguration(
|
||||
AutoConfigurations.of(RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class))
|
||||
.withPropertyValues("spring.session.store-type=redis", "spring.session.redis.namespace=foo")
|
||||
.run(validateSpringSessionUsesRedis("foo:"));
|
||||
.withPropertyValues("spring.session.store-type=redis", "spring.session.redis.namespace=foo",
|
||||
"spring.session.redis.save-mode=on-get-attribute")
|
||||
.run(validateSpringSessionUsesRedis("foo:", SaveMode.ON_GET_ATTRIBUTE));
|
||||
}
|
||||
|
||||
private ContextConsumer<AssertableReactiveWebApplicationContext> validateSpringSessionUsesRedis(String namespace) {
|
||||
private ContextConsumer<AssertableReactiveWebApplicationContext> validateSpringSessionUsesRedis(String namespace,
|
||||
SaveMode saveMode) {
|
||||
return (context) -> {
|
||||
ReactiveRedisOperationsSessionRepository repository = validateSessionRepository(context,
|
||||
ReactiveRedisOperationsSessionRepository.class);
|
||||
assertThat(repository).hasFieldOrPropertyWithValue("namespace", namespace);
|
||||
assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
|||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.session.FlushMode;
|
||||
import org.springframework.session.SaveMode;
|
||||
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.hazelcast.HazelcastSessionRepository;
|
||||
|
@ -88,6 +89,16 @@ class SessionAutoConfigurationHazelcastTests extends AbstractSessionAutoConfigur
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customSaveMode() {
|
||||
this.contextRunner.withPropertyValues("spring.session.store-type=hazelcast",
|
||||
"spring.session.hazelcast.save-mode=on-get-attribute").run((context) -> {
|
||||
HazelcastSessionRepository repository = validateSessionRepository(context,
|
||||
HazelcastSessionRepository.class);
|
||||
assertThat(repository).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE);
|
||||
});
|
||||
}
|
||||
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
static class HazelcastConfiguration {
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
|
|||
import org.springframework.boot.web.servlet.FilterRegistrationBean;
|
||||
import org.springframework.jdbc.BadSqlGrammarException;
|
||||
import org.springframework.jdbc.core.JdbcOperations;
|
||||
import org.springframework.session.SaveMode;
|
||||
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.hazelcast.HazelcastSessionRepository;
|
||||
|
@ -129,4 +130,17 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration
|
|||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
void customSaveMode() {
|
||||
this.contextRunner
|
||||
.withPropertyValues("spring.session.store-type=jdbc", "spring.session.jdbc.save-mode=on-get-attribute")
|
||||
.run((context) -> {
|
||||
assertThat(context.getBean(JdbcSessionProperties.class).getSaveMode())
|
||||
.isEqualTo(SaveMode.ON_GET_ATTRIBUTE);
|
||||
SpringBootJdbcHttpSessionConfiguration configuration = context
|
||||
.getBean(SpringBootJdbcHttpSessionConfiguration.class);
|
||||
assertThat(configuration).hasFieldOrPropertyWithValue("saveMode", SaveMode.ON_GET_ATTRIBUTE);
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ import org.springframework.boot.testsupport.testcontainers.RedisContainer;
|
|||
import org.springframework.data.redis.connection.RedisConnection;
|
||||
import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.session.FlushMode;
|
||||
import org.springframework.session.SaveMode;
|
||||
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
|
||||
import org.springframework.session.data.redis.config.ConfigureNotifyKeyspaceEventsAction;
|
||||
|
@ -64,8 +65,8 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
|
|||
.withPropertyValues("spring.session.store-type=redis",
|
||||
"spring.redis.port=" + redis.getFirstMappedPort())
|
||||
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
|
||||
.run(validateSpringSessionUsesRedis("spring:session:event:0:created:", FlushMode.ON_SAVE,
|
||||
"0 * * * * *"));
|
||||
.run(validateSpringSessionUsesRedis("spring:session:event:0:created:", FlushMode.ON_SAVE, "0 * * * * *",
|
||||
SaveMode.ON_SET_ATTRIBUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -75,8 +76,8 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
|
|||
JdbcOperationsSessionRepository.class, MongoOperationsSessionRepository.class))
|
||||
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
|
||||
.withPropertyValues("spring.redis.port=" + redis.getFirstMappedPort())
|
||||
.run(validateSpringSessionUsesRedis("spring:session:event:0:created:", FlushMode.ON_SAVE,
|
||||
"0 * * * * *"));
|
||||
.run(validateSpringSessionUsesRedis("spring:session:event:0:created:", FlushMode.ON_SAVE, "0 * * * * *",
|
||||
SaveMode.ON_SET_ATTRIBUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -84,8 +85,10 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
|
|||
this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
|
||||
.withPropertyValues("spring.session.store-type=redis", "spring.session.redis.namespace=foo",
|
||||
"spring.session.redis.flush-mode=immediate", "spring.session.redis.cleanup-cron=0 0 12 * * *",
|
||||
"spring.session.redis.save-mode=on-get-attribute",
|
||||
"spring.redis.port=" + redis.getFirstMappedPort())
|
||||
.run(validateSpringSessionUsesRedis("foo:event:0:created:", FlushMode.IMMEDIATE, "0 0 12 * * *"));
|
||||
.run(validateSpringSessionUsesRedis("foo:event:0:created:", FlushMode.IMMEDIATE, "0 0 12 * * *",
|
||||
SaveMode.ON_GET_ATTRIBUTE));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -116,7 +119,7 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
|
|||
}
|
||||
|
||||
private ContextConsumer<AssertableWebApplicationContext> validateSpringSessionUsesRedis(
|
||||
String sessionCreatedChannelPrefix, FlushMode flushMode, String cleanupCron) {
|
||||
String sessionCreatedChannelPrefix, FlushMode flushMode, String cleanupCron, SaveMode saveMode) {
|
||||
return (context) -> {
|
||||
RedisOperationsSessionRepository repository = validateSessionRepository(context,
|
||||
RedisOperationsSessionRepository.class);
|
||||
|
@ -125,6 +128,7 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
|
|||
SpringBootRedisHttpSessionConfiguration configuration = context
|
||||
.getBean(SpringBootRedisHttpSessionConfiguration.class);
|
||||
assertThat(configuration).hasFieldOrPropertyWithValue("cleanupCron", cleanupCron);
|
||||
assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue