diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java index 28c7c9d85a..15fbb27b0d 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/HazelcastSessionConfiguration.java @@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -52,8 +53,9 @@ class HazelcastSessionConfiguration { @Autowired public void customize(SessionProperties sessionProperties, - HazelcastSessionProperties hazelcastSessionProperties) { - Duration timeout = sessionProperties.getTimeout(); + HazelcastSessionProperties hazelcastSessionProperties, ServerProperties serverProperties) { + Duration timeout = sessionProperties + .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()); if (timeout != null) { setMaxInactiveIntervalInSeconds((int) timeout.getSeconds()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java index d141586840..dfdc789dbd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/JdbcSessionConfiguration.java @@ -24,6 +24,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -60,8 +61,10 @@ class JdbcSessionConfiguration { static class SpringBootJdbcHttpSessionConfiguration extends JdbcHttpSessionConfiguration { @Autowired - void customize(SessionProperties sessionProperties, JdbcSessionProperties jdbcSessionProperties) { - Duration timeout = sessionProperties.getTimeout(); + void customize(SessionProperties sessionProperties, JdbcSessionProperties jdbcSessionProperties, + ServerProperties serverProperties) { + Duration timeout = sessionProperties + .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()); if (timeout != null) { setMaxInactiveIntervalInSeconds((int) timeout.getSeconds()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java index 5bdf15cd75..2118bdbdc6 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/MongoSessionConfiguration.java @@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; @@ -48,8 +49,10 @@ class MongoSessionConfiguration { public static class SpringBootMongoHttpSessionConfiguration extends MongoHttpSessionConfiguration { @Autowired - public void customize(SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties) { - Duration timeout = sessionProperties.getTimeout(); + public void customize(SessionProperties sessionProperties, MongoSessionProperties mongoSessionProperties, + ServerProperties serverProperties) { + Duration timeout = sessionProperties + .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()); if (timeout != null) { setMaxInactiveIntervalInSeconds((int) timeout.getSeconds()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java index 2d01e22ab6..e31c794c85 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/RedisSessionConfiguration.java @@ -22,6 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; @@ -68,8 +69,10 @@ class RedisSessionConfiguration { public static class SpringBootRedisHttpSessionConfiguration extends RedisHttpSessionConfiguration { @Autowired - public void customize(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties) { - Duration timeout = sessionProperties.getTimeout(); + public void customize(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties, + ServerProperties serverProperties) { + Duration timeout = sessionProperties + .determineTimeout(() -> serverProperties.getServlet().getSession().getTimeout()); if (timeout != null) { setMaxInactiveIntervalInSeconds((int) timeout.getSeconds()); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java index 7f5bb4b6a0..2e9f4d3378 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/session/SessionProperties.java @@ -21,14 +21,11 @@ import java.time.temporal.ChronoUnit; import java.util.Arrays; import java.util.HashSet; import java.util.Set; +import java.util.function.Supplier; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.convert.DurationUnit; import org.springframework.boot.web.servlet.DispatcherType; -import org.springframework.boot.web.servlet.server.Session; import org.springframework.session.web.http.SessionRepositoryFilter; /** @@ -55,13 +52,6 @@ public class SessionProperties { private Servlet servlet = new Servlet(); - private ServerProperties serverProperties; - - @Autowired - void setServerProperties(ObjectProvider serverProperties) { - this.serverProperties = serverProperties.getIfUnique(); - } - public StoreType getStoreType() { return this.storeType; } @@ -70,14 +60,8 @@ public class SessionProperties { this.storeType = storeType; } - /** - * Return the session timeout. - * @return the session timeout - * @see Session#getTimeout() - */ public Duration getTimeout() { - return (this.timeout == null && this.serverProperties != null) - ? this.serverProperties.getServlet().getSession().getTimeout() : this.timeout; + return this.timeout; } public void setTimeout(Duration timeout) { @@ -92,6 +76,17 @@ public class SessionProperties { this.servlet = servlet; } + /** + * Determine the session timeout. If no timeout is configured, the + * {@code fallbackTimeout} is used. + * @param fallbackTimeout a fallback timeout value if the timeout isn't configured + * @return the session timeout + * @since 2.4.0 + */ + public Duration determineTimeout(Supplier fallbackTimeout) { + return (this.timeout != null) ? this.timeout : fallbackTimeout.get(); + } + /** * Servlet-related properties. */ diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java index bff4724409..fe221ebebd 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationMongoTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -61,6 +61,19 @@ class ReactiveSessionAutoConfigurationMongoTests extends AbstractSessionAutoConf .run(validateSpringSessionUsesMongo("sessions")); } + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner.withPropertyValues("spring.session.store-type=mongodb", "spring.session.timeout=1m") + .withConfiguration(AutoConfigurations.of(EmbeddedMongoAutoConfiguration.class, + MongoAutoConfiguration.class, MongoDataAutoConfiguration.class, + MongoReactiveAutoConfiguration.class, MongoReactiveDataAutoConfiguration.class)) + .run((context) -> { + ReactiveMongoSessionRepository repository = validateSessionRepository(context, + ReactiveMongoSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("maxInactiveIntervalInSeconds", 60); + }); + } + @Test void mongoSessionStoreWithCustomizations() { this.contextRunner @@ -77,6 +90,8 @@ class ReactiveSessionAutoConfigurationMongoTests extends AbstractSessionAutoConf ReactiveMongoSessionRepository repository = validateSessionRepository(context, ReactiveMongoSessionRepository.class); assertThat(repository.getCollectionName()).isEqualTo(collectionName); + assertThat(repository).hasFieldOrPropertyWithValue("maxInactiveIntervalInSeconds", + ReactiveMongoSessionRepository.DEFAULT_INACTIVE_INTERVAL); }; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java index 8ab4e9c581..c85272dd15 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/ReactiveSessionAutoConfigurationRedisTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -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.MapSession; import org.springframework.session.SaveMode; import org.springframework.session.data.mongo.ReactiveMongoSessionRepository; import org.springframework.session.data.redis.ReactiveRedisSessionRepository; @@ -59,6 +60,18 @@ class ReactiveSessionAutoConfigurationRedisTests extends AbstractSessionAutoConf .run(validateSpringSessionUsesRedis("spring:session:", SaveMode.ON_SET_ATTRIBUTE)); } + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner.withPropertyValues("spring.session.store-type=redis", "spring.session.timeout=1m") + .withConfiguration( + AutoConfigurations.of(RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class)) + .run((context) -> { + ReactiveRedisSessionRepository repository = validateSessionRepository(context, + ReactiveRedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", 60); + }); + } + @Test void redisSessionStoreWithCustomizations() { this.contextRunner @@ -74,6 +87,8 @@ class ReactiveSessionAutoConfigurationRedisTests extends AbstractSessionAutoConf return (context) -> { ReactiveRedisSessionRepository repository = validateSessionRepository(context, ReactiveRedisSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS); assertThat(repository).hasFieldOrPropertyWithValue("namespace", namespace); assertThat(repository).hasFieldOrPropertyWithValue("saveMode", saveMode); }; diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationHazelcastTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationHazelcastTests.java index da92f174cc..d21ad5c84b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationHazelcastTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationHazelcastTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -21,6 +21,7 @@ import com.hazelcast.map.IMap; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.WebApplicationContextRunner; @@ -63,8 +64,21 @@ class SessionAutoConfigurationHazelcastTests extends AbstractSessionAutoConfigur .run(this::validateDefaultConfig); } + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner.withPropertyValues("spring.session.store-type=hazelcast", "spring.session.timeout=1m") + .run((context) -> { + Hazelcast4IndexedSessionRepository repository = validateSessionRepository(context, + Hazelcast4IndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", 60); + }); + } + private void validateDefaultConfig(AssertableWebApplicationContext context) { - validateSessionRepository(context, Hazelcast4IndexedSessionRepository.class); + Hazelcast4IndexedSessionRepository repository = validateSessionRepository(context, + Hazelcast4IndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + (int) new ServerProperties().getServlet().getSession().getTimeout().getSeconds()); HazelcastInstance hazelcastInstance = context.getBean(HazelcastInstance.class); verify(hazelcastInstance, times(1)).getMap("spring:session:sessions"); } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java index fd8470c321..b9a073d4cf 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationJdbcTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2019 the original author or authors. + * Copyright 2012-2020 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. @@ -23,6 +23,7 @@ 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.autoconfigure.web.ServerProperties; import org.springframework.boot.jdbc.DataSourceInitializationMode; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; @@ -70,6 +71,8 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration private void validateDefaultConfig(AssertableWebApplicationContext context) { JdbcIndexedSessionRepository repository = validateSessionRepository(context, JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + (int) new ServerProperties().getServlet().getSession().getTimeout().getSeconds()); assertThat(repository).hasFieldOrPropertyWithValue("tableName", "SPRING_SESSION"); assertThat(context.getBean(JdbcSessionProperties.class).getInitializeSchema()) .isEqualTo(DataSourceInitializationMode.EMBEDDED); @@ -104,6 +107,16 @@ class SessionAutoConfigurationJdbcTests extends AbstractSessionAutoConfiguration }); } + @Test + void customTimeout() { + this.contextRunner.withPropertyValues("spring.session.store-type=jdbc", "spring.session.timeout=1m") + .run((context) -> { + JdbcIndexedSessionRepository repository = validateSessionRepository(context, + JdbcIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", 60); + }); + } + @Test void customTableName() { this.contextRunner diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationMongoTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationMongoTests.java index 919a83cae2..5ffbb1c963 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationMongoTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationMongoTests.java @@ -26,6 +26,7 @@ import org.testcontainers.junit.jupiter.Testcontainers; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration; import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration; +import org.springframework.boot.autoconfigure.web.ServerProperties; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.ContextConsumer; @@ -68,6 +69,12 @@ class SessionAutoConfigurationMongoTests extends AbstractSessionAutoConfiguratio .run(validateSpringSessionUsesMongo("sessions")); } + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner.withPropertyValues("spring.session.store-type=mongodb", "spring.session.timeout=1m") + .run(validateSpringSessionUsesMongo("sessions", Duration.ofMinutes(1))); + } + @Test void mongoSessionStoreWithCustomizations() { this.contextRunner @@ -76,10 +83,18 @@ class SessionAutoConfigurationMongoTests extends AbstractSessionAutoConfiguratio } private ContextConsumer validateSpringSessionUsesMongo(String collectionName) { + return validateSpringSessionUsesMongo(collectionName, + new ServerProperties().getServlet().getSession().getTimeout()); + } + + private ContextConsumer validateSpringSessionUsesMongo(String collectionName, + Duration timeout) { return (context) -> { MongoIndexedSessionRepository repository = validateSessionRepository(context, MongoIndexedSessionRepository.class); assertThat(repository).hasFieldOrPropertyWithValue("collectionName", collectionName); + assertThat(repository).hasFieldOrPropertyWithValue("maxInactiveIntervalInSeconds", + (int) timeout.getSeconds()); }; } diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java index 0c2820108e..418fd7f88b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationRedisTests.java @@ -26,6 +26,7 @@ import org.testcontainers.junit.jupiter.Testcontainers; 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.autoconfigure.web.ServerProperties; import org.springframework.boot.test.context.FilteredClassLoader; import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext; import org.springframework.boot.test.context.runner.ContextConsumer; @@ -83,6 +84,18 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio SaveMode.ON_SET_ATTRIBUTE, "0 * * * * *")); } + @Test + void defaultConfigWithCustomTimeout() { + this.contextRunner + .withPropertyValues("spring.session.store-type=redis", "spring.redis.host=" + redis.getHost(), + "spring.redis.port=" + redis.getFirstMappedPort(), "spring.session.timeout=1m") + .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)).run((context) -> { + RedisIndexedSessionRepository repository = validateSessionRepository(context, + RedisIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", 60); + }); + } + @Test void redisSessionStoreWithCustomizations() { this.contextRunner.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) @@ -126,6 +139,8 @@ class SessionAutoConfigurationRedisTests extends AbstractSessionAutoConfiguratio return (context) -> { RedisIndexedSessionRepository repository = validateSessionRepository(context, RedisIndexedSessionRepository.class); + assertThat(repository).hasFieldOrPropertyWithValue("defaultMaxInactiveInterval", + (int) new ServerProperties().getServlet().getSession().getTimeout().getSeconds()); assertThat(repository.getSessionCreatedChannelPrefix()).isEqualTo(sessionCreatedChannelPrefix); assertThat(repository).hasFieldOrPropertyWithValue("flushMode", flushMode); SpringBootRedisHttpSessionConfiguration configuration = context diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java index f187e328e5..3d05130a7b 100644 --- a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionAutoConfigurationTests.java @@ -95,22 +95,6 @@ class SessionAutoConfigurationTests extends AbstractSessionAutoConfigurationTest }); } - @Test - void autoConfigWhenSpringSessionTimeoutIsSetShouldUseThat() { - this.contextRunner - .withUserConfiguration(ServerPropertiesConfiguration.class, SessionRepositoryConfiguration.class) - .withPropertyValues("server.servlet.session.timeout=1", "spring.session.timeout=3") - .run((context) -> assertThat(context.getBean(SessionProperties.class).getTimeout()).hasSeconds(3)); - } - - @Test - void autoConfigWhenSpringSessionTimeoutIsNotSetShouldUseServerSessionTimeout() { - this.contextRunner - .withUserConfiguration(ServerPropertiesConfiguration.class, SessionRepositoryConfiguration.class) - .withPropertyValues("server.servlet.session.timeout=3") - .run((context) -> assertThat(context.getBean(SessionProperties.class).getTimeout()).hasSeconds(3)); - } - @Test void filterIsRegisteredWithAsyncErrorAndRequestDispatcherTypes() { this.contextRunner.withUserConfiguration(SessionRepositoryConfiguration.class).run((context) -> { diff --git a/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionPropertiesTests.java b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionPropertiesTests.java new file mode 100644 index 0000000000..7d7286b1c3 --- /dev/null +++ b/spring-boot-project/spring-boot-autoconfigure/src/test/java/org/springframework/boot/autoconfigure/session/SessionPropertiesTests.java @@ -0,0 +1,53 @@ +/* + * Copyright 2012-2020 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 + * + * https://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.boot.autoconfigure.session; + +import java.time.Duration; +import java.util.function.Supplier; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verifyNoInteractions; + +/** + * Tests for {@link SessionProperties}. + * + * @author Stephane Nicoll + */ +class SessionPropertiesTests { + + @Test + @SuppressWarnings("unchecked") + void determineTimeoutWithTimeoutIgnoreFallback() { + SessionProperties properties = new SessionProperties(); + properties.setTimeout(Duration.ofMinutes(1)); + Supplier fallback = mock(Supplier.class); + assertThat(properties.determineTimeout(fallback)).isEqualTo(Duration.ofMinutes(1)); + verifyNoInteractions(fallback); + } + + @Test + void determineTimeoutWithNoTimeoutUseFallback() { + SessionProperties properties = new SessionProperties(); + properties.setTimeout(null); + Duration fallback = Duration.ofMinutes(2); + assertThat(properties.determineTimeout(() -> fallback)).isSameAs(fallback); + } + +} diff --git a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc index a2433e21cd..2ba625e446 100644 --- a/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc +++ b/spring-boot-project/spring-boot-docs/src/docs/asciidoc/spring-boot-features.adoc @@ -6736,7 +6736,7 @@ For instance, it is possible to customize the name of the table for the JDBC sto ---- For setting the timeout of the session you can use the configprop:spring.session.timeout[] property. -If that property is not set, the auto-configuration falls back to the value of configprop:server.servlet.session.timeout[]. +If that property is not set with a Servlet web appplication, the auto-configuration falls back to the value of configprop:server.servlet.session.timeout[].