Add support for configuring Spring Session cleanup cron

This commit adds support for configuring cron expression used for
expired session cleanup job in Redis and JDBC session stores.

Closes gh-10818
This commit is contained in:
Vedran Pavic 2017-10-30 10:08:20 +01:00 committed by Stephane Nicoll
parent f59986f100
commit 3d44ef0872
7 changed files with 71 additions and 10 deletions

View File

@ -68,6 +68,7 @@ class JdbcSessionConfiguration {
setMaxInactiveIntervalInSeconds(timeout);
}
setTableName(jdbcSessionProperties.getTableName());
setCleanupCron(jdbcSessionProperties.getCleanupCron());
}
}

View File

@ -33,6 +33,8 @@ public class JdbcSessionProperties {
private static final String DEFAULT_TABLE_NAME = "SPRING_SESSION";
private static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
/**
* Path to the SQL file to use to initialize the database schema.
*/
@ -43,6 +45,11 @@ public class JdbcSessionProperties {
*/
private String tableName = DEFAULT_TABLE_NAME;
/**
* Cron expression for expired session cleanup job.
*/
private String cleanupCron = DEFAULT_CLEANUP_CRON;
/**
* Database schema initialization mode.
*/
@ -64,6 +71,14 @@ public class JdbcSessionProperties {
this.tableName = tableName;
}
public String getCleanupCron() {
return this.cleanupCron;
}
public void setCleanupCron(String cleanupCron) {
this.cleanupCron = cleanupCron;
}
public DataSourceInitializationMode getInitializeSchema() {
return this.initializeSchema;
}

View File

@ -62,6 +62,7 @@ class RedisSessionConfiguration {
}
setRedisNamespace(redisSessionProperties.getNamespace());
setRedisFlushMode(redisSessionProperties.getFlushMode());
setCleanupCron(redisSessionProperties.getCleanupCron());
}
}

View File

@ -28,6 +28,8 @@ import org.springframework.session.data.redis.RedisFlushMode;
@ConfigurationProperties(prefix = "spring.session.redis")
public class RedisSessionProperties {
private static final String DEFAULT_CLEANUP_CRON = "0 * * * * *";
/**
* Namespace for keys used to store sessions.
*/
@ -38,6 +40,11 @@ public class RedisSessionProperties {
*/
private RedisFlushMode flushMode = RedisFlushMode.ON_SAVE;
/**
* Cron expression for expired session cleanup job.
*/
private String cleanupCron = DEFAULT_CLEANUP_CRON;
public String getNamespace() {
return this.namespace;
}
@ -54,4 +61,12 @@ public class RedisSessionProperties {
this.flushMode = flushMode;
}
public String getCleanupCron() {
return this.cleanupCron;
}
public void setCleanupCron(String cleanupCron) {
this.cleanupCron = cleanupCron;
}
}

View File

@ -25,6 +25,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.session.JdbcSessionConfiguration.SpringBootJdbcHttpSessionConfiguration;
import org.springframework.boot.jdbc.DataSourceInitializationMode;
import org.springframework.boot.test.context.HideClassesClassLoader;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
@ -82,7 +83,10 @@ public class SessionAutoConfigurationJdbcTests
.isEqualTo(DataSourceInitializationMode.EMBEDDED);
assertThat(context.getBean(JdbcOperations.class)
.queryForList("select * from SPRING_SESSION")).isEmpty();
SpringBootJdbcHttpSessionConfiguration configuration = context
.getBean(SpringBootJdbcHttpSessionConfiguration.class);
assertThat(new DirectFieldAccessor(configuration).getPropertyValue("cleanupCron"))
.isEqualTo("0 * * * * *");
}
@Test
@ -114,10 +118,9 @@ public class SessionAutoConfigurationJdbcTests
@Test
public void customTableName() {
this.contextRunner
.withPropertyValues("spring.session.store-type=jdbc",
"spring.session.jdbc.table-name=FOO_BAR",
"spring.session.jdbc.schema=classpath:session/custom-schema-h2.sql")
this.contextRunner.withPropertyValues("spring.session.store-type=jdbc",
"spring.session.jdbc.table-name=FOO_BAR",
"spring.session.jdbc.schema=classpath:session/custom-schema-h2.sql")
.run((context) -> {
JdbcOperationsSessionRepository repository = validateSessionRepository(
context, JdbcOperationsSessionRepository.class);
@ -131,4 +134,20 @@ public class SessionAutoConfigurationJdbcTests
});
}
@Test
public void customCleanupCron() {
this.contextRunner
.withPropertyValues("spring.session.store-type=jdbc",
"spring.session.jdbc.cleanup-cron=0 0 12 * * *")
.run((context) -> {
assertThat(
context.getBean(JdbcSessionProperties.class).getCleanupCron())
.isEqualTo("0 0 12 * * *");
SpringBootJdbcHttpSessionConfiguration configuration = context
.getBean(SpringBootJdbcHttpSessionConfiguration.class);
assertThat(new DirectFieldAccessor(configuration)
.getPropertyValue("cleanupCron")).isEqualTo("0 0 12 * * *");
});
}
}

View File

@ -22,6 +22,7 @@ import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.session.RedisSessionConfiguration.SpringBootRedisHttpSessionConfiguration;
import org.springframework.boot.test.context.HideClassesClassLoader;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
@ -39,6 +40,7 @@ import static org.assertj.core.api.Assertions.assertThat;
* Redis specific tests for {@link SessionAutoConfiguration}.
*
* @author Stephane Nicoll
* @author Vedran Pavic
*/
public class SessionAutoConfigurationRedisTests
extends AbstractSessionAutoConfigurationTests {
@ -54,7 +56,7 @@ public class SessionAutoConfigurationRedisTests
this.contextRunner.withPropertyValues("spring.session.store-type=redis")
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
.run(validateSpringSessionUsesRedis("spring:session:event:created:",
RedisFlushMode.ON_SAVE));
RedisFlushMode.ON_SAVE, "0 * * * * *"));
}
@Test
@ -66,7 +68,7 @@ public class SessionAutoConfigurationRedisTests
MongoOperationsSessionRepository.class))
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
.run(validateSpringSessionUsesRedis("spring:session:event:created:",
RedisFlushMode.ON_SAVE));
RedisFlushMode.ON_SAVE, "0 * * * * *"));
}
@Test
@ -75,13 +77,15 @@ public class SessionAutoConfigurationRedisTests
.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.flush-mode=immediate",
"spring.session.redis.cleanup-cron=0 0 12 * * *")
.run(validateSpringSessionUsesRedis("spring:session:foo:event:created:",
RedisFlushMode.IMMEDIATE));
RedisFlushMode.IMMEDIATE, "0 0 12 * * *"));
}
private ContextConsumer<AssertableWebApplicationContext> validateSpringSessionUsesRedis(
String sessionCreatedChannelPrefix, RedisFlushMode flushMode) {
String sessionCreatedChannelPrefix, RedisFlushMode flushMode,
String cleanupCron) {
return (context) -> {
RedisOperationsSessionRepository repository = validateSessionRepository(
context, RedisOperationsSessionRepository.class);
@ -89,6 +93,10 @@ public class SessionAutoConfigurationRedisTests
.isEqualTo(sessionCreatedChannelPrefix);
assertThat(new DirectFieldAccessor(repository)
.getPropertyValue("redisFlushMode")).isEqualTo(flushMode);
SpringBootRedisHttpSessionConfiguration configuration = context
.getBean(SpringBootRedisHttpSessionConfiguration.class);
assertThat(new DirectFieldAccessor(configuration)
.getPropertyValue("cleanupCron")).isEqualTo(cleanupCron);
};
}

View File

@ -425,6 +425,7 @@ content into your application; rather pick only the properties that you need.
spring.session.hazelcast.map-name=spring:session:sessions # Name of the map used to store sessions.
# SPRING SESSION JDBC ({sc-spring-boot-autoconfigure}/session/JdbcSessionProperties.{sc-ext}[JdbcSessionProperties])
spring.session.jdbc.cleanup-cron=0 * * * * * # Cron expression for expired session cleanup job.
spring.session.jdbc.initialize-schema=embedded # Database schema initialization mode.
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-@@platform@@.sql # Path to the SQL file to use to initialize the database schema.
spring.session.jdbc.table-name=SPRING_SESSION # Name of database table used to store sessions.
@ -433,6 +434,7 @@ content into your application; rather pick only the properties that you need.
spring.session.mongodb.collection-name=sessions # Collection name used to store sessions.
# SPRING SESSION REDIS ({sc-spring-boot-autoconfigure}/session/RedisSessionProperties.{sc-ext}[RedisSessionProperties])
spring.session.redis.cleanup-cron=0 * * * * * # Cron expression for expired session cleanup job.
spring.session.redis.flush-mode=on-save # Sessions flush mode.
spring.session.redis.namespace= # Namespace for keys used to store sessions.