Skip to content

Commit 5ecf390

Browse files
author
Rob Winch
committed
Add spring.session.cleanup.cron.expression
Fixes gh-616
1 parent 8167b43 commit 5ecf390

File tree

7 files changed

+183
-2
lines changed

7 files changed

+183
-2
lines changed

spring-session/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ public void save(RedisSession session) {
393393
}
394394
}
395395

396-
@Scheduled(cron = "0 * * * * *")
396+
@Scheduled(cron = "${spring.session.cleanup.cron.expression:0 * * * * *}")
397397
public void cleanupExpiredSessions() {
398398
this.expirationPolicy.cleanExpiredSessions();
399399
}

spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.springframework.context.annotation.Bean;
2828
import org.springframework.context.annotation.Configuration;
2929
import org.springframework.context.annotation.ImportAware;
30+
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
3031
import org.springframework.core.annotation.AnnotationAttributes;
3132
import org.springframework.core.type.AnnotationMetadata;
3233
import org.springframework.data.redis.connection.RedisConnection;
@@ -200,6 +201,15 @@ public void setRedisSubscriptionExecutor(Executor redisSubscriptionExecutor) {
200201
this.redisSubscriptionExecutor = redisSubscriptionExecutor;
201202
}
202203

204+
/**
205+
* Property placeholder to process the @Scheduled annotation.
206+
* @return the {@link PropertySourcesPlaceholderConfigurer} to use
207+
*/
208+
@Bean
209+
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
210+
return new PropertySourcesPlaceholderConfigurer();
211+
}
212+
203213
/**
204214
* Ensures that Redis is configured to send keyspace notifications. This is important
205215
* to ensure that expiration and deletion of sessions trigger SessionDestroyedEvents.

spring-session/src/main/java/org/springframework/session/jdbc/JdbcOperationsSessionRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -561,7 +561,7 @@ public void setValues(PreparedStatement ps) throws SQLException {
561561
return sessionMap;
562562
}
563563

564-
@Scheduled(cron = "0 * * * * *")
564+
@Scheduled(cron = "${spring.session.cleanup.cron.expression:0 * * * * *}")
565565
public void cleanUpExpiredSessions() {
566566
int deletedCount = this.transactionOperations.execute(new TransactionCallback<Integer>() {
567567

spring-session/src/main/java/org/springframework/session/jdbc/config/annotation/web/http/JdbcHttpSessionConfiguration.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import org.springframework.context.annotation.Bean;
2727
import org.springframework.context.annotation.Configuration;
2828
import org.springframework.context.annotation.ImportAware;
29+
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
2930
import org.springframework.core.annotation.AnnotationAttributes;
3031
import org.springframework.core.convert.ConversionService;
3132
import org.springframework.core.convert.support.GenericConversionService;
@@ -190,4 +191,12 @@ public void setImportMetadata(AnnotationMetadata importMetadata) {
190191
.getNumber("maxInactiveIntervalInSeconds");
191192
}
192193

194+
/**
195+
* Property placeholder to process the @Scheduled annotation.
196+
* @return the {@link PropertySourcesPlaceholderConfigurer} to use
197+
*/
198+
@Bean
199+
public static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() {
200+
return new PropertySourcesPlaceholderConfigurer();
201+
}
193202
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
/*
2+
* Copyright 2014-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.session.data.redis.config.annotation.web.http;
18+
19+
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
20+
import org.junit.After;
21+
import org.junit.Before;
22+
import org.junit.Test;
23+
24+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
25+
import org.springframework.context.annotation.Bean;
26+
import org.springframework.context.annotation.Configuration;
27+
import org.springframework.context.annotation.PropertySource;
28+
import org.springframework.data.redis.connection.RedisConnection;
29+
import org.springframework.data.redis.connection.RedisConnectionFactory;
30+
31+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
32+
import static org.mockito.BDDMockito.given;
33+
import static org.mockito.Mockito.mock;
34+
35+
/**
36+
* @author Rob Winch
37+
*
38+
*/
39+
public class RedisHttpSessionConfigurationCustomCronTests {
40+
41+
AnnotationConfigApplicationContext context;
42+
43+
@Before
44+
public void setup() {
45+
this.context = new AnnotationConfigApplicationContext();
46+
}
47+
48+
@After
49+
public void closeContext() {
50+
if (this.context != null) {
51+
this.context.close();
52+
}
53+
}
54+
55+
@Test
56+
public void overrideCron() {
57+
this.context.register(Config.class);
58+
59+
assertThatThrownBy(new ThrowingCallable() {
60+
public void call() throws Throwable {
61+
RedisHttpSessionConfigurationCustomCronTests.this.context.refresh();
62+
}
63+
}).hasStackTraceContaining(
64+
"Encountered invalid @Scheduled method 'cleanupExpiredSessions': Cron expression must consist of 6 fields (found 1 in \"oops\")");
65+
}
66+
67+
@EnableRedisHttpSession
68+
@Configuration
69+
@PropertySource("classpath:spring-session-cleanup-cron-expression-oops.properties")
70+
static class Config {
71+
@Bean
72+
public RedisConnectionFactory connectionFactory() {
73+
RedisConnectionFactory factory = mock(RedisConnectionFactory.class);
74+
RedisConnection connection = mock(RedisConnection.class);
75+
given(factory.getConnection()).willReturn(connection);
76+
77+
return factory;
78+
}
79+
}
80+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
/*
2+
* Copyright 2014-2016 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.session.jdbc.config.annotation.web.http;
18+
19+
import javax.sql.DataSource;
20+
21+
import org.assertj.core.api.ThrowableAssert.ThrowingCallable;
22+
import org.junit.After;
23+
import org.junit.Before;
24+
import org.junit.Test;
25+
26+
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
27+
import org.springframework.context.annotation.Bean;
28+
import org.springframework.context.annotation.Configuration;
29+
import org.springframework.context.annotation.PropertySource;
30+
import org.springframework.transaction.PlatformTransactionManager;
31+
32+
import static org.assertj.core.api.Assertions.assertThatThrownBy;
33+
import static org.mockito.Mockito.mock;
34+
35+
/**
36+
* @author Rob Winch
37+
*
38+
*/
39+
public class JdbcHttpSessionConfigurationCustomCronTests {
40+
41+
AnnotationConfigApplicationContext context;
42+
43+
@Before
44+
public void setup() {
45+
this.context = new AnnotationConfigApplicationContext();
46+
}
47+
48+
@After
49+
public void closeContext() {
50+
if (this.context != null) {
51+
this.context.close();
52+
}
53+
}
54+
55+
@Test
56+
public void overrideCron() {
57+
this.context.register(Config.class);
58+
59+
assertThatThrownBy(new ThrowingCallable() {
60+
public void call() throws Throwable {
61+
JdbcHttpSessionConfigurationCustomCronTests.this.context.refresh();
62+
}
63+
}).hasStackTraceContaining(
64+
"Encountered invalid @Scheduled method 'cleanUpExpiredSessions': Cron expression must consist of 6 fields (found 1 in \"oops\")");
65+
}
66+
67+
@EnableJdbcHttpSession
68+
@Configuration
69+
@PropertySource("classpath:spring-session-cleanup-cron-expression-oops.properties")
70+
static class Config {
71+
@Bean
72+
public DataSource dataSource() {
73+
return mock(DataSource.class);
74+
}
75+
76+
@Bean
77+
public PlatformTransactionManager transactionManager() {
78+
return mock(PlatformTransactionManager.class);
79+
}
80+
}
81+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
spring.session.cleanup.cron.expression=oops

0 commit comments

Comments
 (0)