Commit 9f090c4f authored by Stephane Nicoll's avatar Stephane Nicoll

Merge pull request #17514 from vpavic

* pr/17514:
  Polish "Add support for configuring Spring Session SaveMode"
  Add support for configuring Spring Session SaveMode

Closes gh-17514
parents b7d349db 1f7615a9
......@@ -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());
}
}
......
/*
* 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());
}
}
......
......@@ -75,6 +75,7 @@ class RedisSessionConfiguration {
}
setRedisNamespace(redisSessionProperties.getNamespace());
setFlushMode(redisSessionProperties.getFlushMode());
setSaveMode(redisSessionProperties.getSaveMode());
setCleanupCron(redisSessionProperties.getCleanupCron());
}
......
......@@ -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.
......@@ -40,6 +41,12 @@ public class RedisSessionProperties {
*/
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;
/**
* The configure action to apply when no user defined ConfigureRedisAction bean is
* present.
......@@ -67,6 +74,14 @@ public class RedisSessionProperties {
this.flushMode = flushMode;
}
public SaveMode getSaveMode() {
return this.saveMode;
}
public void setSaveMode(SaveMode saveMode) {
this.saveMode = saveMode;
}
public String getCleanupCron() {
return this.cleanupCron;
}
......
......@@ -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;
......@@ -65,7 +66,7 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
"spring.redis.port=" + redis.getFirstMappedPort())
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
.run(validateSpringSessionUsesRedis("spring:session:event:0:created:", FlushMode.ON_SAVE,
"0 * * * * *"));
SaveMode.ON_SET_ATTRIBUTE, "0 * * * * *"));
}
@Test
......@@ -76,16 +77,18 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
.withPropertyValues("spring.redis.port=" + redis.getFirstMappedPort())
.run(validateSpringSessionUsesRedis("spring:session:event:0:created:", FlushMode.ON_SAVE,
"0 * * * * *"));
SaveMode.ON_SET_ATTRIBUTE, "0 * * * * *"));
}
@Test
void redisSessionStoreWithCustomizations() {
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.flush-mode=immediate", "spring.session.redis.save-mode=on-get-attribute",
"spring.session.redis.cleanup-cron=0 0 12 * * *",
"spring.redis.port=" + redis.getFirstMappedPort())
.run(validateSpringSessionUsesRedis("foo:event:0:created:", FlushMode.IMMEDIATE, "0 0 12 * * *"));
.run(validateSpringSessionUsesRedis("foo:event:0:created:", FlushMode.IMMEDIATE,
SaveMode.ON_GET_ATTRIBUTE, "0 0 12 * * *"));
}
@Test
......@@ -116,7 +119,7 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio
}
private ContextConsumer<AssertableWebApplicationContext> validateSpringSessionUsesRedis(
String sessionCreatedChannelPrefix, FlushMode flushMode, String cleanupCron) {
String sessionCreatedChannelPrefix, FlushMode flushMode, SaveMode saveMode, String cleanupCron) {
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);
};
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment