Add auto-configuration for separate Spring Session Data MongoDB module

Closes gh-9552
pull/9635/head
Andy Wilkinson 7 years ago
parent c3bc32db02
commit c00a42f437

@ -527,6 +527,11 @@
<artifactId>spring-session-core</artifactId> <artifactId>spring-session-core</artifactId>
<optional>true</optional> <optional>true</optional>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.session</groupId> <groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId> <artifactId>spring-session-data-redis</artifactId>

@ -0,0 +1,58 @@
/*
* Copyright 2012-2017 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.boot.autoconfigure.session;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.session.SessionRepository;
import org.springframework.session.data.mongo.config.annotation.web.http.MongoHttpSessionConfiguration;
/**
* Mongo-backed session configuration.
*
* @author Eddú Meléndez
* @author Stephane Nicoll
*/
@Configuration
@ConditionalOnMissingBean(SessionRepository.class)
@ConditionalOnBean(MongoOperations.class)
@Conditional(SessionCondition.class)
@EnableConfigurationProperties(MongoSessionProperties.class)
class MongoSessionConfiguration {
@Configuration
public static class SpringBootMongoHttpSessionConfiguration
extends MongoHttpSessionConfiguration {
@Autowired
public void customize(SessionProperties sessionProperties,
MongoSessionProperties mongoSessionProperties) {
Integer timeout = sessionProperties.getTimeout();
if (timeout != null) {
setMaxInactiveIntervalInSeconds(timeout);
}
setCollectionName(mongoSessionProperties.getCollectionName());
}
}
}

@ -0,0 +1,43 @@
/*
* Copyright 2012-2017 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.boot.autoconfigure.session;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* Configuration properties for Mongo-backed Spring Session.
*
* @author Andy Wilkinson
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "spring.session.mongo")
public class MongoSessionProperties {
/**
* Collection name used to store sessions.
*/
private String collectionName = "sessions";
public String getCollectionName() {
return this.collectionName;
}
public void setCollectionName(String collectionName) {
this.collectionName = collectionName;
}
}

@ -32,6 +32,7 @@ import org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration;
import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration; import org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration;
import org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration;
import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration.SessionRepositoryConfiguration; import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration.SessionRepositoryConfiguration;
import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration.SessionRepositoryValidator; import org.springframework.boot.autoconfigure.session.SessionAutoConfiguration.SessionRepositoryValidator;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
@ -58,7 +59,8 @@ import org.springframework.session.SessionRepository;
@ConditionalOnWebApplication(type = Type.SERVLET) @ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(SessionProperties.class) @EnableConfigurationProperties(SessionProperties.class)
@AutoConfigureAfter({ DataSourceAutoConfiguration.class, HazelcastAutoConfiguration.class, @AutoConfigureAfter({ DataSourceAutoConfiguration.class, HazelcastAutoConfiguration.class,
JdbcTemplateAutoConfiguration.class, RedisAutoConfiguration.class }) JdbcTemplateAutoConfiguration.class, MongoAutoConfiguration.class,
RedisAutoConfiguration.class })
@Import({ SessionRepositoryConfiguration.class, SessionRepositoryValidator.class, @Import({ SessionRepositoryConfiguration.class, SessionRepositoryValidator.class,
SessionRepositoryFilterConfiguration.class }) SessionRepositoryFilterConfiguration.class })
public class SessionAutoConfiguration { public class SessionAutoConfiguration {

@ -35,6 +35,7 @@ final class SessionStoreMappings {
static { static {
Map<StoreType, Class<?>> mappings = new HashMap<>(); Map<StoreType, Class<?>> mappings = new HashMap<>();
mappings.put(StoreType.REDIS, RedisSessionConfiguration.class); mappings.put(StoreType.REDIS, RedisSessionConfiguration.class);
mappings.put(StoreType.MONGO, MongoSessionConfiguration.class);
mappings.put(StoreType.JDBC, JdbcSessionConfiguration.class); mappings.put(StoreType.JDBC, JdbcSessionConfiguration.class);
mappings.put(StoreType.HAZELCAST, HazelcastSessionConfiguration.class); mappings.put(StoreType.HAZELCAST, HazelcastSessionConfiguration.class);
mappings.put(StoreType.NONE, NoOpSessionConfiguration.class); mappings.put(StoreType.NONE, NoOpSessionConfiguration.class);

@ -31,6 +31,11 @@ public enum StoreType {
*/ */
REDIS, REDIS,
/**
* Mongo backed sessions.
*/
MONGO,
/** /**
* JDBC backed sessions. * JDBC backed sessions.
*/ */

@ -32,6 +32,7 @@ import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.jdbc.BadSqlGrammarException; import org.springframework.jdbc.BadSqlGrammarException;
import org.springframework.jdbc.core.JdbcOperations; import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
import org.springframework.session.data.redis.RedisOperationsSessionRepository; import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.hazelcast.HazelcastSessionRepository; import org.springframework.session.hazelcast.HazelcastSessionRepository;
import org.springframework.session.jdbc.JdbcOperationsSessionRepository; import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
@ -69,6 +70,7 @@ public class SessionAutoConfigurationJdbcTests
this.contextRunner this.contextRunner
.withClassLoader( .withClassLoader(
new HideClassesClassLoader(HazelcastSessionRepository.class, new HideClassesClassLoader(HazelcastSessionRepository.class,
MongoOperationsSessionRepository.class,
RedisOperationsSessionRepository.class)) RedisOperationsSessionRepository.class))
.withConfiguration( .withConfiguration(
AutoConfigurations.of(JdbcTemplateAutoConfiguration.class)) AutoConfigurations.of(JdbcTemplateAutoConfiguration.class))

@ -0,0 +1,91 @@
/*
* Copyright 2012-2017 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.boot.autoconfigure.session;
import org.junit.Test;
import org.springframework.beans.DirectFieldAccessor;
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.mongo.embedded.EmbeddedMongoAutoConfiguration;
import org.springframework.boot.test.context.HideClassesClassLoader;
import org.springframework.boot.test.context.assertj.AssertableWebApplicationContext;
import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.hazelcast.HazelcastSessionRepository;
import org.springframework.session.jdbc.JdbcOperationsSessionRepository;
import static org.assertj.core.api.Assertions.assertThat;
/**
* Mongo-specific tests for {@link SessionAutoConfiguration}.
*
* @author Andy Wilkinson
*/
public class SessionAutoConfigurationMongoTests
extends AbstractSessionAutoConfigurationTests {
private final WebApplicationContextRunner contextRunner = new WebApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(SessionAutoConfiguration.class));
@Test
public void defaultConfig() {
this.contextRunner.withPropertyValues("spring.session.store-type=mongo")
.withConfiguration(AutoConfigurations.of(
EmbeddedMongoAutoConfiguration.class,
MongoAutoConfiguration.class, MongoDataAutoConfiguration.class))
.run(validateSpringSessionUsesMongo("sessions"));
}
@Test
public void defaultConfigWithUniqueStoreImplementation() {
this.contextRunner
.withClassLoader(
new HideClassesClassLoader(HazelcastSessionRepository.class,
JdbcOperationsSessionRepository.class,
RedisOperationsSessionRepository.class))
.withConfiguration(AutoConfigurations.of(
EmbeddedMongoAutoConfiguration.class,
MongoAutoConfiguration.class, MongoDataAutoConfiguration.class))
.run(validateSpringSessionUsesMongo("sessions"));
}
@Test
public void mongoSessionStoreWithCustomizations() {
this.contextRunner
.withConfiguration(AutoConfigurations.of(
EmbeddedMongoAutoConfiguration.class,
MongoAutoConfiguration.class, MongoDataAutoConfiguration.class))
.withPropertyValues("spring.session.store-type=mongo",
"spring.session.mongo.collection-name=foo")
.run(validateSpringSessionUsesMongo("foo"));
}
private ContextConsumer<AssertableWebApplicationContext> validateSpringSessionUsesMongo(
String collectionName) {
return (context) -> {
MongoOperationsSessionRepository repository = validateSessionRepository(
context, MongoOperationsSessionRepository.class);
assertThat(new DirectFieldAccessor(repository)
.getPropertyValue("collectionName")).isEqualTo(collectionName);
};
}
}

@ -27,6 +27,7 @@ import org.springframework.boot.test.context.assertj.AssertableWebApplicationCon
import org.springframework.boot.test.context.runner.ContextConsumer; import org.springframework.boot.test.context.runner.ContextConsumer;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner; import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.boot.testsupport.rule.RedisTestServer; import org.springframework.boot.testsupport.rule.RedisTestServer;
import org.springframework.session.data.mongo.MongoOperationsSessionRepository;
import org.springframework.session.data.redis.RedisFlushMode; import org.springframework.session.data.redis.RedisFlushMode;
import org.springframework.session.data.redis.RedisOperationsSessionRepository; import org.springframework.session.data.redis.RedisOperationsSessionRepository;
import org.springframework.session.hazelcast.HazelcastSessionRepository; import org.springframework.session.hazelcast.HazelcastSessionRepository;
@ -61,7 +62,8 @@ public class SessionAutoConfigurationRedisTests
this.contextRunner this.contextRunner
.withClassLoader( .withClassLoader(
new HideClassesClassLoader(HazelcastSessionRepository.class, new HideClassesClassLoader(HazelcastSessionRepository.class,
JdbcOperationsSessionRepository.class)) JdbcOperationsSessionRepository.class,
MongoOperationsSessionRepository.class))
.withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class)) .withConfiguration(AutoConfigurations.of(RedisAutoConfiguration.class))
.run(validateSpringSessionUsesRedis("spring:session:event:created:", .run(validateSpringSessionUsesRedis("spring:session:event:created:",
RedisFlushMode.ON_SAVE)); RedisFlushMode.ON_SAVE));

@ -174,6 +174,7 @@
<spring-retry.version>1.2.1.RELEASE</spring-retry.version> <spring-retry.version>1.2.1.RELEASE</spring-retry.version>
<spring-security.version>5.0.0.M4</spring-security.version> <spring-security.version>5.0.0.M4</spring-security.version>
<spring-session.version>2.0.0.M4</spring-session.version> <spring-session.version>2.0.0.M4</spring-session.version>
<spring-session-data-mongodb.version>2.0.0.M3</spring-session-data-mongodb.version>
<spring-social.version>2.0.0.M4</spring-social.version> <spring-social.version>2.0.0.M4</spring-social.version>
<spring-social-facebook.version>3.0.0.M3</spring-social-facebook.version> <spring-social-facebook.version>3.0.0.M3</spring-social-facebook.version>
<spring-social-linkedin.version>2.0.0.M3</spring-social-linkedin.version> <spring-social-linkedin.version>2.0.0.M3</spring-social-linkedin.version>
@ -2402,6 +2403,11 @@
<artifactId>spring-session-data-redis</artifactId> <artifactId>spring-session-data-redis</artifactId>
<version>${spring-session.version}</version> <version>${spring-session.version}</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongodb</artifactId>
<version>${spring-session-data-mongodb.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.session</groupId> <groupId>org.springframework.session</groupId>
<artifactId>spring-session-hazelcast</artifactId> <artifactId>spring-session-hazelcast</artifactId>

@ -427,6 +427,9 @@ content into your application; rather pick only the properties that you need.
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.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. spring.session.jdbc.table-name=SPRING_SESSION # Name of database table used to store sessions.
# SPRING SESSION MONGO ({sc-spring-boot-autoconfigure}/session/MonogoSessionProperties.{sc-ext}[MongoSessionProperties])
spring.session.mongo.collection-name=sessions # Collection name used to store sessions.
# SPRING SESSION REDIS ({sc-spring-boot-autoconfigure}/session/RedisSessionProperties.{sc-ext}[RedisSessionProperties]) # SPRING SESSION REDIS ({sc-spring-boot-autoconfigure}/session/RedisSessionProperties.{sc-ext}[RedisSessionProperties])
spring.session.redis.flush-mode=on-save # Sessions flush mode. spring.session.redis.flush-mode=on-save # Sessions flush mode.
spring.session.redis.namespace= # Namespace for keys used to store sessions. spring.session.redis.namespace= # Namespace for keys used to store sessions.

@ -5364,6 +5364,7 @@ classes for more details.
Spring Boot provides Spring Session auto-configuration for a wide range of stores: Spring Boot provides Spring Session auto-configuration for a wide range of stores:
* JDBC * JDBC
* MongoDB
* Redis * Redis
* Hazelcast * Hazelcast

Loading…
Cancel
Save