Add spring.session.cleanup.cron.expression

Fixes gh-616
This commit is contained in:
Rob Winch
2016-09-13 10:31:03 -05:00
parent 8167b43e63
commit 5ecf390932
7 changed files with 183 additions and 2 deletions

View File

@@ -393,7 +393,7 @@ public class RedisOperationsSessionRepository implements
}
}
@Scheduled(cron = "0 * * * * *")
@Scheduled(cron = "${spring.session.cleanup.cron.expression:0 * * * * *}")
public void cleanupExpiredSessions() {
this.expirationPolicy.cleanExpiredSessions();
}

View File

@@ -27,6 +27,7 @@ import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.data.redis.connection.RedisConnection;
@@ -200,6 +201,15 @@ public class RedisHttpSessionConfiguration extends SpringHttpSessionConfiguratio
this.redisSubscriptionExecutor = redisSubscriptionExecutor;
}
/**
* Property placeholder to process the @Scheduled annotation.
* @return the {@link PropertySourcesPlaceholderConfigurer} to use
*/
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
/**
* Ensures that Redis is configured to send keyspace notifications. This is important
* to ensure that expiration and deletion of sessions trigger SessionDestroyedEvents.

View File

@@ -561,7 +561,7 @@ public class JdbcOperationsSessionRepository implements
return sessionMap;
}
@Scheduled(cron = "0 * * * * *")
@Scheduled(cron = "${spring.session.cleanup.cron.expression:0 * * * * *}")
public void cleanUpExpiredSessions() {
int deletedCount = this.transactionOperations.execute(new TransactionCallback<Integer>() {

View File

@@ -26,6 +26,7 @@ import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.GenericConversionService;
@@ -190,4 +191,12 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
.getNumber("maxInactiveIntervalInSeconds");
}
/**
* Property placeholder to process the @Scheduled annotation.
* @return the {@link PropertySourcesPlaceholderConfigurer} to use
*/
@Bean
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
return new PropertySourcesPlaceholderConfigurer();
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright 2014-2016 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 org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* @author Rob Winch
*
*/
public class RedisHttpSessionConfigurationCustomCronTests {
AnnotationConfigApplicationContext context;
@Before
public void setup() {
this.context = new AnnotationConfigApplicationContext();
}
@After
public void closeContext() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void overrideCron() {
this.context.register(Config.class);
assertThatThrownBy(new ThrowingCallable() {
public void call() throws Throwable {
RedisHttpSessionConfigurationCustomCronTests.this.context.refresh();
}
}).hasStackTraceContaining(
"Encountered invalid @Scheduled method 'cleanupExpiredSessions': Cron expression must consist of 6 fields (found 1 in \"oops\")");
}
@EnableRedisHttpSession
@Configuration
@PropertySource("classpath:spring-session-cleanup-cron-expression-oops.properties")
static class Config {
@Bean
public RedisConnectionFactory connectionFactory() {
RedisConnectionFactory factory = mock(RedisConnectionFactory.class);
RedisConnection connection = mock(RedisConnection.class);
given(factory.getConnection()).willReturn(connection);
return factory;
}
}
}

View File

@@ -0,0 +1,81 @@
/*
* Copyright 2014-2016 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.jdbc.config.annotation.web.http;
import javax.sql.DataSource;
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.PlatformTransactionManager;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.mock;
/**
* @author Rob Winch
*
*/
public class JdbcHttpSessionConfigurationCustomCronTests {
AnnotationConfigApplicationContext context;
@Before
public void setup() {
this.context = new AnnotationConfigApplicationContext();
}
@After
public void closeContext() {
if (this.context != null) {
this.context.close();
}
}
@Test
public void overrideCron() {
this.context.register(Config.class);
assertThatThrownBy(new ThrowingCallable() {
public void call() throws Throwable {
JdbcHttpSessionConfigurationCustomCronTests.this.context.refresh();
}
}).hasStackTraceContaining(
"Encountered invalid @Scheduled method 'cleanUpExpiredSessions': Cron expression must consist of 6 fields (found 1 in \"oops\")");
}
@EnableJdbcHttpSession
@Configuration
@PropertySource("classpath:spring-session-cleanup-cron-expression-oops.properties")
static class Config {
@Bean
public DataSource dataSource() {
return mock(DataSource.class);
}
@Bean
public PlatformTransactionManager transactionManager() {
return mock(PlatformTransactionManager.class);
}
}
}

View File

@@ -0,0 +1 @@
spring.session.cleanup.cron.expression=oops