Compare commits

..

59 Commits

Author SHA1 Message Date
Rob Winch
c5fc4b57ad Release 2.1.3.RELEASE 2019-01-10 21:36:09 -06:00
Rob Winch
3b826e51a1 Update to Spring Security 5.1.3.RELEASE
Fixes: gh-1293
2019-01-10 21:34:44 -06:00
Vedran Pavic
67063ec0c6 Upgrade Gradle to 4.10.3 2019-01-10 16:22:39 +01:00
Vedran Pavic
72198e9e80 Update integration tests 2019-01-10 16:19:38 +01:00
Vedran Pavic
b3ee28b972 Upgrade test dependencies 2019-01-10 16:13:41 +01:00
Vedran Pavic
2d498bf69d Upgrade Spring Data to Lovelace-SR4
Resolves: #1292
2019-01-10 14:20:50 +01:00
Vedran Pavic
c365e4d941 Upgrade Spring Framework to 5.1.4.RELEASE
Resolves: #1291
2019-01-09 16:21:37 +01:00
Vedran Pavic
f7f8d4f6c0 Upgrade Reactor to Californium-SR4
Resolves: #1298
2019-01-08 17:59:54 +01:00
Vedran Pavic
fd5115fae5 Fix Spring Security integration docs sample 2019-01-08 08:15:08 +01:00
Vedran Pavic
a4c39fde9f Polish 2018-12-26 20:16:32 +01:00
Vedran Pavic
96391ce41a Fix assertion in Hazelcast tests 2018-12-24 20:59:06 +01:00
Vedran Pavic
d48eebea99 Upgrade Hazelcast to 3.11.1
Resolves: #1299
2018-12-20 18:52:27 +01:00
Vedran Pavic
57cd6c367d Upgrade samples to Spring Boot 2.1.1.RELEASE
Resolves: #1294
2018-12-17 21:12:38 +01:00
Roman Beskrovnyi
68f83b00eb Fix SessionRepositoryFilter Javadoc 2018-12-12 13:57:48 -06:00
Jeff
a4a5b529ef Fix RedisOperationsSessionRepository javadoc typos
Resolves: #1273
2018-12-04 16:35:56 +01:00
Vedran Pavic
f5ae38d94c Next development version 2018-11-28 19:43:47 +01:00
Vedran Pavic
b201ed971c Release 2.1.2.RELEASE 2018-11-28 19:38:37 +01:00
Vedran Pavic
70346b0a84 Upgrade test dependencies 2018-11-28 19:14:15 +01:00
Vedran Pavic
d4fd8b97b4 Upgrade Spring Security to 5.1.2.RELEASE
Resolves: #1261
2018-11-28 15:57:45 +01:00
Vedran Pavic
b3d01063d9 Upgrade Spring Data to Lovelace-SR3
Resolves: #1249
2018-11-27 15:20:19 +01:00
Vedran Pavic
124565306b Tweak Hazelcast session event tests
See: #1267
2018-11-27 13:21:16 +01:00
Vedran Pavic
f709a6c787 Upgrade Hazelcast to 3.11
Resolves: #1267
2018-11-27 11:29:48 +01:00
Vedran Pavic
c354927ef3 Upgrade spring-build-conventions to 0.0.22.RELEASE 2018-11-27 11:29:37 +01:00
Vedran Pavic
2db79e2bb8 Upgrade Spring Framework to 5.1.3.RELEASE
Resolves: #1248
2018-11-27 11:29:10 +01:00
Vedran Pavic
3480c65c2b Polish 2018-11-26 18:24:14 +01:00
Vedran Pavic
e0dc0262ef Make SessionUpdateEntryProcessor public
Resolves: #1260
2018-11-26 18:18:18 +01:00
Vedran Pavic
3b7da0c370 Update integration tests 2018-11-26 17:54:57 +01:00
Vedran Pavic
72984f9ca6 Upgrade test dependencies 2018-11-26 17:42:00 +01:00
Vedran Pavic
8a4872b919 Improve exception asserts 2018-11-26 10:02:40 +01:00
Vedran Pavic
6b6c6f27df Upgrade Reactor to Californium-SR3
Resolves: #1262
2018-11-23 19:26:15 +01:00
Vedran Pavic
640bee3fc4 Update Jenkins pipeline
- add JDK 9 stage (only unit tests)
- update JDK 10 stage to only run unit tests
2018-11-22 23:11:31 +01:00
Vedran Pavic
3bfdb9be93 Polish contribution
Resolves: #1243
2018-11-02 22:28:34 +01:00
Josh Cummings
c8f3d1a1ec Commit Session on Include Dispatch
The servlet spec disallows any writing of headers after an include has been issued.

This commit intercepts the include and commits the session, then
allowing the include to proceed.

See: #1243
2018-11-02 22:28:34 +01:00
Vedran Pavic
11ad1db6e7 Update integration tests 2018-11-01 17:50:35 +01:00
Vedran Pavic
7b87128db6 Upgrade test dependencies 2018-11-01 17:28:06 +01:00
Vedran Pavic
bf861933ed Upgrade samples to Spring Boot 2.1.0.RELEASE
Resolves: #1240
2018-11-01 17:24:59 +01:00
Rob Winch
979e91256d Next Development Version 2018-10-29 10:42:02 -05:00
Rob Winch
05986d68b2 Release 2.1.1.RELEASE 2018-10-29 10:08:49 -05:00
Rob Winch
e17b047800 Update to Spring Data Lovelace-SR2
Fixes: gh-1234
2018-10-29 10:07:26 -05:00
Vedran Pavic
5ab2424b14 Upgrade Spring Framework to 5.1.2.RELEASE
Resolves: #1233
2018-10-29 13:04:47 +01:00
Vedran Pavic
196919efbb Upgrade Reactor to Californium-SR2
Resolves: #1235
2018-10-29 07:37:17 +01:00
Vedran Pavic
717e16cb71 Ensure HttpServletRequest#getRequestedSessionId API is respected
HttpSessionIdResolver supports resolving multiple requested session ids associated with the request - as a consequence, we need to validate the existence of requested session before returning the id. However, if no presented session ids do validate the null is returned, which violates the HttpServletRequest#getRequestedSessionId API.

This commit ensures that if no presented session ids are valid, we respect the HttpServletRequest#getRequestedSessionId API by returning first requested session id.

Resolves: #1229
2018-10-26 19:55:37 +02:00
Rob Winch
5f1b7d6722 Next Development Version 2018-10-15 20:05:12 -05:00
Rob Winch
4d3a01919c Release 2.1.0.RELEASE 2018-10-15 20:04:27 -05:00
Rob Winch
e408d7f557 Update to Spring Security 5.1.1.RELEASE
Fixes: gh-1222
2018-10-15 20:04:04 -05:00
Vedran Pavic
f34acebf84 Upgrade integration tests 2018-10-15 18:42:12 +02:00
Vedran Pavic
1aab3e8285 Upgrade test dependencies 2018-10-15 18:35:18 +02:00
Vedran Pavic
c3528996d2 Upgrade Hazelcast to 3.10.6
Resolves: #1223
2018-10-15 18:34:44 +02:00
Vedran Pavic
3ccc3eb6e1 Upgrade Reactor to Californium-SR1
Resolves: #1221
2018-10-15 18:34:10 +02:00
Vedran Pavic
de76be95ac Upgrade Spring Data to Lovelace-SR1
Resolves: #1220
2018-10-15 18:33:25 +02:00
Vedran Pavic
bc127ab3fc Upgrade Spring Framework to 5.1.1.RELEASE
Resolves: #1219
2018-10-15 18:32:47 +02:00
Vedran Pavic
3e9f6a35c4 Fix root project name 2018-10-01 22:46:10 +02:00
Vedran Pavic
49daa3a9c7 Polish 2018-09-26 14:16:02 +02:00
Vedran Pavic
a67bd634d9 Disable network join in Hazelcast samples 2018-09-26 14:16:00 +02:00
Vedran Pavic
2762f001bf Add Oracle integration tests 2018-09-25 19:10:15 +02:00
Vedran Pavic
93aee206fb Configure default LobHandler to use temporary LOBs on Oracle
JdbcOperationsSessionRepository recently introduced validation when inserting new session attributes in order to prevent data integrity violations in highly concurrent environments. This is done by using INSERT INTO ... SELECT statement to verify existence of session record in parent table. Such arrangement causes problems with Oracle if inserted attribute is of size 4 kb or more.

This commit enhances JdbcHttpSessionConfiguration to detect Oracle database is used, and set createTemporaryLob option on default LobHandler to true.

Resolves: #1203
See also: #1031
2018-09-25 18:45:02 +02:00
Vedran Pavic
3df3b30117 Upgrade Testcontainers to 1.9.1 2018-09-25 18:31:52 +02:00
Vedran Pavic
5fb0c4dd35 Improve JDBC integration tests 2018-09-24 06:30:47 +02:00
Vedran Pavic
6fbce6e3e8 Next development version 2018-09-21 21:27:42 +02:00
68 changed files with 961 additions and 676 deletions

22
Jenkinsfile vendored
View File

@@ -28,14 +28,32 @@ try {
}
}
},
jdk9: {
stage('JDK 9') {
timeout(time: 45, unit: 'MINUTES') {
node {
checkout scm
try {
withEnv(["JAVA_HOME=${tool 'jdk9'}"]) {
sh './gradlew clean test --no-daemon --refresh-dependencies'
}
}
catch (e) {
currentBuild.result = 'FAILED: jdk9'
throw e
}
}
}
}
},
jdk10: {
stage('JDK 10') {
timeout(time: 45, unit: 'MINUTES') {
node('ubuntu1804') {
node {
checkout scm
try {
withEnv(["JAVA_HOME=${tool 'jdk10'}"]) {
sh './gradlew clean test integrationTest --no-daemon --refresh-dependencies'
sh './gradlew clean test --no-daemon --refresh-dependencies'
}
}
catch (e) {

View File

@@ -4,7 +4,7 @@ buildscript {
snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild)
springBootVersion = '2.1.0.M3'
springBootVersion = '2.1.1.RELEASE'
}
repositories {
@@ -13,7 +13,7 @@ buildscript {
}
dependencies {
classpath 'io.spring.gradle:spring-build-conventions:0.0.19.RELEASE'
classpath 'io.spring.gradle:spring-build-conventions:0.0.22.RELEASE'
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2019 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.
@@ -30,10 +30,11 @@ import org.springframework.session.security.SpringSessionBackedSessionRegistry;
*/
// tag::class[]
@Configuration
public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
public class SecurityConfiguration<S extends Session>
extends WebSecurityConfigurerAdapter {
@Autowired
private FindByIndexNameSessionRepository<Session> sessionRepository;
private FindByIndexNameSessionRepository<S> sessionRepository;
@Override
protected void configure(HttpSecurity http) throws Exception {
@@ -47,7 +48,7 @@ public class SecurityConfiguration extends WebSecurityConfigurerAdapter {
}
@Bean
SpringSessionBackedSessionRegistry sessionRegistry() {
public SpringSessionBackedSessionRegistry<S> sessionRegistry() {
return new SpringSessionBackedSessionRegistry<>(this.sessionRepository);
}
}

View File

@@ -1 +1 @@
version=2.1.0.RC1
version=2.1.3.RELEASE

View File

@@ -1,32 +1,33 @@
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.9.6'
mavenBom 'io.projectreactor:reactor-bom:Californium-RELEASE'
mavenBom 'org.springframework:spring-framework-bom:5.1.0.RELEASE'
mavenBom 'org.springframework.data:spring-data-releasetrain:Lovelace-RELEASE'
mavenBom 'org.springframework.security:spring-security-bom:5.1.0.RELEASE'
mavenBom 'org.testcontainers:testcontainers-bom:1.9.0-rc2'
mavenBom 'io.projectreactor:reactor-bom:Californium-SR4'
mavenBom 'org.springframework:spring-framework-bom:5.1.4.RELEASE'
mavenBom 'org.springframework.data:spring-data-releasetrain:Lovelace-SR4'
mavenBom 'org.springframework.security:spring-security-bom:5.1.3.RELEASE'
mavenBom 'org.testcontainers:testcontainers-bom:1.10.5'
}
dependencies {
dependencySet(group: 'com.hazelcast', version: '3.10.5') {
dependencySet(group: 'com.hazelcast', version: '3.11.1') {
entry 'hazelcast'
entry 'hazelcast-client'
}
dependency 'com.h2database:h2:1.4.197'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.0.0.jre8'
dependency 'com.zaxxer:HikariCP:3.3.0'
dependency 'edu.umd.cs.mtc:multithreadedtc:1.01'
dependency 'io.lettuce:lettuce-core:5.1.0.RELEASE'
dependency 'io.lettuce:lettuce-core:5.1.3.RELEASE'
dependency 'javax.annotation:javax.annotation-api:1.3.2'
dependency 'javax.servlet:javax.servlet-api:4.0.1'
dependency 'junit:junit:4.12'
dependency 'mysql:mysql-connector-java:8.0.12'
dependency 'mysql:mysql-connector-java:8.0.13'
dependency 'org.apache.derby:derby:10.14.2.0'
dependency 'org.assertj:assertj-core:3.11.1'
dependency 'org.hsqldb:hsqldb:2.4.1'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.3.0'
dependency 'org.mockito:mockito-core:2.22.0'
dependency 'org.mockito:mockito-core:2.23.4'
dependency 'org.postgresql:postgresql:42.2.5'
}
}

Binary file not shown.

View File

@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.3-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -46,7 +46,7 @@ import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDr
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
public class FindByUsernameTests {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Autowired
private MockMvc mockMvc;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -50,7 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@AutoConfigureMockMvc
public class HttpRedisJsonTest {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Autowired
private MockMvc mockMvc;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -39,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
public class RedisSerializerTest {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@SpringSessionRedisOperations
private RedisTemplate<Object, Object> sessionRedisTemplate;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -45,7 +45,7 @@ import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDr
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
public class BootTests {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Autowired
private MockMvc mockMvc;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -47,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class AttributeTests {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@LocalServerPort
private int port;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -42,7 +42,7 @@ import org.springframework.web.socket.sockjs.client.SockJsClient;
import org.springframework.web.socket.sockjs.client.Transport;
import org.springframework.web.socket.sockjs.client.WebSocketTransport;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Rob Winch
@@ -52,7 +52,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class ApplicationTests {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Value("${local.server.port}")
private String port;
@@ -70,8 +70,8 @@ public class ApplicationTests {
ListenableFuture<WebSocketSession> wsSession = sockJsClient.doHandshake(
this.webSocketHandler, "ws://localhost:" + this.port + "/sockjs");
assertThatThrownBy(() -> wsSession.get().sendMessage(new TextMessage("a")))
.isInstanceOf(ExecutionException.class);
assertThatExceptionOfType(ExecutionException.class)
.isThrownBy(() -> wsSession.get().sendMessage(new TextMessage("a")));
}
@TestConfiguration

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -28,7 +28,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
@Profile("embedded-redis")
public class EmbeddedRedisConfig {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Bean
public GenericContainer redisContainer() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2018 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.
@@ -42,7 +42,8 @@ public class SessionConfig {
int port = SocketUtils.findAvailableTcpPort();
config.getNetworkConfig()
.setPort(port);
.setPort(port)
.getJoin().getMulticastConfig().setEnabled(false);
System.out.println("Hazelcast port #: " + port);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -28,7 +28,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
@Profile("embedded-redis")
public class EmbeddedRedisConfig {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Bean
public GenericContainer redisContainer() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -54,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@WebAppConfiguration
public class RestMockMvcTests {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Autowired
private SessionRepositoryFilter<? extends Session> sessionRepositoryFilter;

View File

@@ -32,7 +32,7 @@ import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* @author Pool Dolorier
@@ -57,9 +57,9 @@ public class RestTests {
public void unauthenticatedUserSentToLogInPage() {
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
assertThatThrownBy(() -> getForUser(this.baseUrl + "/", headers, String.class))
.isInstanceOf(HttpClientErrorException.class)
.satisfies((e) -> assertThat(((HttpClientErrorException) e).getStatusCode())
assertThatExceptionOfType(HttpClientErrorException.class)
.isThrownBy(() -> getForUser(this.baseUrl + "/", headers, String.class))
.satisfies((e) -> assertThat(e.getStatusCode())
.isEqualTo(HttpStatus.UNAUTHORIZED));
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -28,7 +28,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
@Profile("embedded-redis")
public class EmbeddedRedisConfig {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Bean
public GenericContainer redisContainer() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -28,7 +28,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
@Profile("embedded-redis")
public class EmbeddedRedisConfig {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Bean
public GenericContainer redisContainer() {

View File

@@ -64,7 +64,9 @@ public class Initializer implements ServletContextListener {
private HazelcastInstance createHazelcastInstance() {
Config config = new Config();
config.getNetworkConfig().setPort(getAvailablePort());
config.getNetworkConfig()
.setPort(getAvailablePort())
.getJoin().getMulticastConfig().setEnabled(false);
config.getMapConfig(SESSION_MAP_NAME)
.setTimeToLiveSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -28,7 +28,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
@Profile("embedded-redis")
public class EmbeddedRedisConfig {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
@Bean
public GenericContainer redisContainer() {

View File

@@ -1,4 +1,4 @@
rootProject.name = 'spring-session'
rootProject.name = 'spring-session-build'
FileTree buildFiles = fileTree(rootDir) {
include '**/*.gradle'

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2018 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.
@@ -28,7 +28,7 @@ import javax.servlet.http.HttpServletResponse;
*
* @author Rob Winch
* @author Vedran Pavic
* @since 1.0
* @since 2.0.0
*/
public interface HttpSessionIdResolver {

View File

@@ -21,8 +21,11 @@ import java.time.Instant;
import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
@@ -46,7 +49,7 @@ import org.springframework.session.SessionRepository;
* {@link org.springframework.session.SessionRepository}.
*
* The {@link SessionRepositoryFilter} uses a {@link HttpSessionIdResolver} (default
* {@link CookieHttpSessionIdResolver} to bridge logic between an
* {@link CookieHttpSessionIdResolver}) to bridge logic between an
* {@link javax.servlet.http.HttpSession} and the
* {@link org.springframework.session.Session} abstraction. Specifically:
*
@@ -71,6 +74,7 @@ import org.springframework.session.SessionRepository;
* @since 1.0
* @author Rob Winch
* @author Vedran Pavic
* @author Josh Cummings
*/
@Order(SessionRepositoryFilter.DEFAULT_ORDER)
public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFilter {
@@ -205,6 +209,8 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
private boolean requestedSessionCached;
private String requestedSessionId;
private Boolean requestedSessionIdValid;
private boolean requestedSessionInvalidated;
@@ -277,7 +283,6 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
}
return isRequestedSessionIdValid(requestedSession);
}
return this.requestedSessionIdValid;
}
@@ -351,8 +356,16 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
@Override
public String getRequestedSessionId() {
S requestedSession = getRequestedSession();
return (requestedSession != null) ? requestedSession.getId() : null;
if (this.requestedSessionId == null) {
getRequestedSession();
}
return this.requestedSessionId;
}
@Override
public RequestDispatcher getRequestDispatcher(String path) {
RequestDispatcher requestDispatcher = super.getRequestDispatcher(path);
return new SessionCommittingRequestDispatcher(requestDispatcher);
}
private S getRequestedSession() {
@@ -360,10 +373,14 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
List<String> sessionIds = SessionRepositoryFilter.this.httpSessionIdResolver
.resolveSessionIds(this);
for (String sessionId : sessionIds) {
if (this.requestedSessionId == null) {
this.requestedSessionId = sessionId;
}
S session = SessionRepositoryFilter.this.sessionRepository
.findById(sessionId);
if (session != null) {
this.requestedSession = session;
this.requestedSessionId = sessionId;
break;
}
}
@@ -375,6 +392,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
private void clearRequestedSessionCache() {
this.requestedSessionCached = false;
this.requestedSession = null;
this.requestedSessionId = null;
}
/**
@@ -399,6 +417,35 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
}
}
/**
* Ensures session is committed before issuing an include.
*
* @since 1.3.4
*/
private final class SessionCommittingRequestDispatcher
implements RequestDispatcher {
private final RequestDispatcher delegate;
SessionCommittingRequestDispatcher(RequestDispatcher delegate) {
this.delegate = delegate;
}
@Override
public void forward(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
this.delegate.forward(request, response);
}
@Override
public void include(ServletRequest request, ServletResponse response)
throws ServletException, IOException {
SessionRepositoryRequestWrapper.this.commitSession();
this.delegate.include(request, response);
}
}
}
}

View File

@@ -24,7 +24,7 @@ import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
public class MapSessionTests {
@@ -38,9 +38,9 @@ public class MapSessionTests {
@Test
public void constructorNullSession() {
assertThatThrownBy(() -> new MapSession((Session) null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("session cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new MapSession((Session) null))
.withMessage("session cannot be null");
}
@Test
@@ -70,9 +70,9 @@ public class MapSessionTests {
@Test
public void getRequiredAttributeWhenNullThenException() {
assertThatThrownBy(() -> this.session.getRequiredAttribute("attrName"))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Required attribute 'attrName' is missing.");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.session.getRequiredAttribute("attrName"))
.withMessage("Required attribute 'attrName' is missing.");
}
@Test

View File

@@ -27,7 +27,7 @@ import org.junit.Before;
import org.junit.Test;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link ReactiveMapSessionRepository}.
@@ -60,9 +60,9 @@ public class ReactiveMapSessionRepositoryTests {
@Test
public void constructorMapWhenNullThenThrowsIllegalArgumentException() {
assertThatThrownBy(() -> new ReactiveMapSessionRepository(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("sessions cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new ReactiveMapSessionRepository(null))
.withMessage("sessions cannot be null");
}
@Test

View File

@@ -38,7 +38,7 @@ import org.springframework.session.web.http.SessionRepositoryFilter;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link SpringHttpSessionConfiguration}.
@@ -63,9 +63,9 @@ public class SpringHttpSessionConfigurationTests {
@Test
public void noSessionRepositoryConfiguration() {
assertThatThrownBy(() -> registerAndRefresh(EmptyConfiguration.class))
.isInstanceOf(UnsatisfiedDependencyException.class)
.hasMessageContaining("org.springframework.session.SessionRepository");
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
.isThrownBy(() -> registerAndRefresh(EmptyConfiguration.class))
.withMessageContaining("org.springframework.session.SessionRepository");
}
@Test

View File

@@ -27,7 +27,7 @@ import org.springframework.security.web.context.HttpSessionSecurityContextReposi
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -68,9 +68,10 @@ public class SpringSessionRememberMeServicesTests {
@Test
public void createWithNullParameter() {
this.rememberMeServices = new SpringSessionRememberMeServices();
assertThatThrownBy(() -> this.rememberMeServices.setRememberMeParameterName(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("rememberMeParameterName cannot be empty or null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(
() -> this.rememberMeServices.setRememberMeParameterName(null))
.withMessage("rememberMeParameterName cannot be empty or null");
}
@Test

View File

@@ -33,7 +33,7 @@ import org.springframework.session.web.http.CookieSerializer.CookieValue;
import org.springframework.util.StringUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link DefaultCookieSerializer}.
@@ -214,9 +214,9 @@ public class DefaultCookieSerializerTests {
@Test
public void setDomainNameAndDomainNamePatternThrows() {
this.serializer.setDomainName("example.com");
assertThatThrownBy(() -> this.serializer.setDomainNamePattern(".*"))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Cannot set both domainName and domainNamePattern");
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> this.serializer.setDomainNamePattern(".*"))
.withMessage("Cannot set both domainName and domainNamePattern");
}
// --- domainNamePattern ---
@@ -248,9 +248,9 @@ public class DefaultCookieSerializerTests {
@Test
public void setDomainNamePatternAndDomainNameThrows() {
this.serializer.setDomainNamePattern(".*");
assertThatThrownBy(() -> this.serializer.setDomainName("example.com"))
.isInstanceOf(IllegalStateException.class)
.hasMessage("Cannot set both domainName and domainNamePattern");
assertThatExceptionOfType(IllegalStateException.class)
.isThrownBy(() -> this.serializer.setDomainName("example.com"))
.withMessage("Cannot set both domainName and domainNamePattern");
}
// --- cookieName ---
@@ -274,9 +274,9 @@ public class DefaultCookieSerializerTests {
@Test
public void setCookieNameNullThrows() {
assertThatThrownBy(() -> this.serializer.setCookieName(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("cookieName cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.serializer.setCookieName(null))
.withMessage("cookieName cannot be null");
}
// --- cookiePath ---

View File

@@ -27,7 +27,7 @@ import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
/**
* Tests for {@link HeaderHttpSessionIdResolver}.
@@ -74,9 +74,9 @@ public class HeaderHttpSessionIdResolverTests {
@Test
public void createResolverWithNullHeaderName() {
assertThatThrownBy(() -> new HeaderHttpSessionIdResolver(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("headerName cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new HeaderHttpSessionIdResolver(null))
.withMessage("headerName cannot be null");
}
@Test

View File

@@ -62,7 +62,7 @@ import org.springframework.session.SessionRepository;
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@@ -1170,6 +1170,23 @@ public class SessionRepositoryFilterTests {
});
}
@Test // gh-1243
public void doFilterInclude() throws Exception {
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest,
HttpServletResponse wrappedResponse)
throws IOException, ServletException {
String id = wrappedRequest.getSession().getId();
wrappedRequest.getRequestDispatcher("/").include(wrappedRequest,
wrappedResponse);
assertThat(
SessionRepositoryFilterTests.this.sessionRepository.findById(id))
.isNotNull();
}
});
}
// --- HttpSessionIdResolver
@Test
@@ -1196,6 +1213,29 @@ public class SessionRepositoryFilterTests {
});
}
@Test // gh-1229
public void doFilterAdapterGetRequestedSessionIdForInvalidSession() throws Exception {
SessionRepository<MapSession> sessionRepository = new MapSessionRepository(
new HashMap<>());
this.filter = new SessionRepositoryFilter<>(sessionRepository);
this.filter.setHttpSessionIdResolver(this.strategy);
final String expectedId = "HttpSessionIdResolver-requested-id1";
final String otherId = "HttpSessionIdResolver-requested-id2";
given(this.strategy.resolveSessionIds(any(HttpServletRequest.class)))
.willReturn(Arrays.asList(expectedId, otherId));
doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest,
HttpServletResponse wrappedResponse) {
assertThat(wrappedRequest.getRequestedSessionId()).isEqualTo(expectedId);
assertThat(wrappedRequest.isRequestedSessionIdValid()).isFalse();
}
});
}
@Test
public void doFilterAdapterOnNewSession() throws Exception {
this.filter.setHttpSessionIdResolver(this.strategy);
@@ -1378,16 +1418,16 @@ public class SessionRepositoryFilterTests {
@Test
@SuppressWarnings("unused")
public void doesNotImplementOrdered() {
assertThatThrownBy(() -> {
assertThatExceptionOfType(ClassCastException.class).isThrownBy(() -> {
Ordered o = (Ordered) this.filter;
}).isInstanceOf(ClassCastException.class);
});
}
@Test
public void setHttpSessionIdResolverNull() {
assertThatThrownBy(() -> this.filter.setHttpSessionIdResolver(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("httpSessionIdResolver cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.filter.setHttpSessionIdResolver(null))
.withMessage("httpSessionIdResolver cannot be null");
}
@Test

View File

@@ -33,7 +33,7 @@ import org.springframework.session.Session;
import org.springframework.web.server.WebSession;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;
@@ -69,9 +69,9 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
@Test
public void constructorWhenNullRepositoryThenThrowsIllegalArgumentException() {
assertThatThrownBy(() -> new SpringSessionWebSessionStore<S>(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("reactiveSessionRepository cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new SpringSessionWebSessionStore<S>(null))
.withMessage("reactiveSessionRepository cannot be null");
}
@Test
@@ -275,9 +275,9 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
@Test
public void setClockWhenNullThenException() {
assertThatThrownBy(() -> this.webSessionStore.setClock(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("clock cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.webSessionStore.setClock(null))
.withMessage("clock cannot be null");
}
@Test // gh-1114

View File

@@ -31,7 +31,7 @@ import org.springframework.web.socket.WebSocketHandler;
import org.springframework.web.socket.WebSocketSession;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.BDDMockito.willThrow;
import static org.mockito.Mockito.any;
import static org.mockito.Mockito.verify;
@@ -56,9 +56,9 @@ public class WebSocketConnectHandlerDecoratorFactoryTests {
@Test
public void constructorNullEventPublisher() {
assertThatThrownBy(() -> new WebSocketConnectHandlerDecoratorFactory(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("eventPublisher cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new WebSocketConnectHandlerDecoratorFactory(null))
.withMessage("eventPublisher cannot be null");
}
@Test

View File

@@ -43,7 +43,7 @@ import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
@@ -82,9 +82,9 @@ public class SessionRepositoryMessageInterceptorTests {
@Test
public void preSendconstructorNullRepository() {
assertThatThrownBy(() -> new SessionRepositoryMessageInterceptor<>(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("sessionRepository cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new SessionRepositoryMessageInterceptor<>(null))
.withMessage("sessionRepository cannot be null");
}
@Test
@@ -134,17 +134,16 @@ public class SessionRepositoryMessageInterceptorTests {
@Test
public void setMatchingMessageTypesNull() {
assertThatThrownBy(() -> this.interceptor.setMatchingMessageTypes(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("matchingMessageTypes cannot be null or empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.interceptor.setMatchingMessageTypes(null))
.withMessage("matchingMessageTypes cannot be null or empty");
}
@Test
public void setMatchingMessageTypesEmpty() {
assertThatThrownBy(
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
() -> this.interceptor.setMatchingMessageTypes(Collections.emptySet()))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("matchingMessageTypes cannot be null or empty");
.withMessage("matchingMessageTypes cannot be null or empty");
}
@Test

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 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.
@@ -29,7 +29,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
*/
public abstract class AbstractRedisITests {
private static final String DOCKER_IMAGE = "redis:4.0.11";
private static final String DOCKER_IMAGE = "redis:5.0.3";
protected static class BaseConfig {

View File

@@ -202,7 +202,7 @@ import org.springframework.util.Assert;
*
* <p>
* One problem with relying on Redis expiration exclusively is that Redis makes no
* guarantee of when the expired event will be fired if they key has not been accessed.
* guarantee of when the expired event will be fired if the key has not been accessed.
* Specifically the background task that Redis uses to clean up expired keys is a low
* priority task and may not trigger the key expiration. For additional details see
* <a href="http://redis.io/topics/notifications">Timing of expired events</a> section in
@@ -213,7 +213,7 @@ import org.springframework.util.Assert;
* To circumvent the fact that expired events are not guaranteed to happen we can ensure
* that each key is accessed when it is expected to expire. This means that if the TTL is
* expired on the key, Redis will remove the key and fire the expired event when we try to
* access they key.
* access the key.
* </p>
*
* <p>

View File

@@ -36,7 +36,7 @@ import org.springframework.session.data.redis.ReactiveRedisOperationsSessionRepo
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
@@ -80,9 +80,9 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
@Test
public void constructorWithNullReactiveRedisOperations() {
assertThatThrownBy(() -> new ReactiveRedisOperationsSessionRepository(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("sessionRedisOperations cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new ReactiveRedisOperationsSessionRepository(null))
.withMessageContaining("sessionRedisOperations cannot be null");
}
@Test
@@ -95,16 +95,16 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
@Test
public void nullRedisKeyNamespace() {
assertThatThrownBy(() -> this.repository.setRedisKeyNamespace(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("namespace cannot be null or empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setRedisKeyNamespace(null))
.withMessage("namespace cannot be null or empty");
}
@Test
public void emptyRedisKeyNamespace() {
assertThatThrownBy(() -> this.repository.setRedisKeyNamespace(""))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("namespace cannot be null or empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setRedisKeyNamespace(""))
.withMessage("namespace cannot be null or empty");
}
@Test
@@ -125,9 +125,9 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
@Test
public void nullRedisFlushMode() {
assertThatThrownBy(() -> this.repository.setRedisFlushMode(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("redisFlushMode cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setRedisFlushMode(null))
.withMessage("redisFlushMode cannot be null");
}
@Test

View File

@@ -59,7 +59,7 @@ import org.springframework.session.data.redis.RedisOperationsSessionRepository.R
import org.springframework.session.events.AbstractSessionEvent;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -115,9 +115,9 @@ public class RedisOperationsSessionRepositoryTests {
@Test
public void setApplicationEventPublisherNull() {
assertThatThrownBy(() -> this.redisRepository.setApplicationEventPublisher(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("applicationEventPublisher cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.redisRepository.setApplicationEventPublisher(null))
.withMessage("applicationEventPublisher cannot be null");
}
@Test
@@ -841,9 +841,9 @@ public class RedisOperationsSessionRepositoryTests {
@Test
public void setRedisFlushModeNull() {
assertThatThrownBy(() -> this.redisRepository.setRedisFlushMode(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("redisFlushMode cannot be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.redisRepository.setRedisFlushMode(null))
.withMessage("redisFlushMode cannot be null");
}
@Test
@@ -868,16 +868,16 @@ public class RedisOperationsSessionRepositoryTests {
@Test
public void setRedisKeyNamespaceNullNamespace() {
assertThatThrownBy(() -> this.redisRepository.setRedisKeyNamespace(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("namespace cannot be null or empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.redisRepository.setRedisKeyNamespace(null))
.withMessage("namespace cannot be null or empty");
}
@Test
public void setRedisKeyNamespaceEmptyNamespace() {
assertThatThrownBy(() -> this.redisRepository.setRedisKeyNamespace(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("namespace cannot be null or empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.redisRepository.setRedisKeyNamespace(" "))
.withMessage("namespace cannot be null or empty");
}
@Test // gh-1120

View File

@@ -37,7 +37,7 @@ import org.springframework.session.data.redis.config.annotation.SpringSessionRed
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -184,10 +184,10 @@ public class RedisHttpSessionConfigurationTests {
@Test
public void multipleConnectionFactoryRedisConfig() {
assertThatThrownBy(() -> registerAndRefresh(RedisConfig.class,
MultipleConnectionFactoryRedisConfig.class))
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("expected single matching bean but found 2");
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(() -> registerAndRefresh(RedisConfig.class,
MultipleConnectionFactoryRedisConfig.class))
.withMessageContaining("expected single matching bean but found 2");
}
private void registerAndRefresh(Class<?>... annotatedClasses) {

View File

@@ -36,7 +36,7 @@ import org.springframework.session.data.redis.config.annotation.SpringSessionRed
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.mock;
/**
@@ -194,10 +194,10 @@ public class RedisWebSessionConfigurationTests {
@Test
public void multipleConnectionFactoryRedisConfig() {
assertThatThrownBy(() -> registerAndRefresh(RedisConfig.class,
MultipleConnectionFactoryRedisConfig.class))
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("expected single matching bean but found 2");
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(() -> registerAndRefresh(RedisConfig.class,
MultipleConnectionFactoryRedisConfig.class))
.withMessageContaining("expected single matching bean but found 2");
}
@Test

View File

@@ -224,7 +224,7 @@ public abstract class AbstractHazelcastRepositoryITests {
assertThat(this.repository.findByIndexNameAndIndexValue(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username))
.isNotNull();
.hasSize(1);
}
}

View File

@@ -48,7 +48,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
public class HazelcastClientRepositoryITests extends AbstractHazelcastRepositoryITests {
private static GenericContainer container = new GenericContainer<>(
"hazelcast/hazelcast:3.10.5")
"hazelcast/hazelcast:3.11.1")
.withExposedPorts(5701)
.withEnv("JAVA_OPTS",
"-Dhazelcast.config=/opt/hazelcast/config_ext/hazelcast.xml")

View File

@@ -122,7 +122,7 @@ public class EnableHazelcastHttpSessionEventsTests<S extends Session> {
assertThat(this.registry.<SessionExpiredEvent>getEvent(sessionToSave.getId()))
.isInstanceOf(SessionExpiredEvent.class);
assertThat(this.repository.<Session>findById(sessionToSave.getId())).isNull();
assertThat(this.repository.findById(sessionToSave.getId())).isNull();
}
@Test
@@ -147,24 +147,18 @@ public class EnableHazelcastHttpSessionEventsTests<S extends Session> {
@Test
public void saveUpdatesTimeToLiveTest() throws InterruptedException {
Object lock = new Object();
S sessionToSave = this.repository.createSession();
sessionToSave.setMaxInactiveInterval(Duration.ofSeconds(3));
this.repository.save(sessionToSave);
synchronized (lock) {
lock.wait(sessionToSave.getMaxInactiveInterval().minusMillis(500).toMillis());
}
Thread.sleep(2000);
// Get and save the session like SessionRepositoryFilter would.
S sessionToUpdate = this.repository.findById(sessionToSave.getId());
sessionToUpdate.setLastAccessedTime(Instant.now());
this.repository.save(sessionToUpdate);
synchronized (lock) {
lock.wait(sessionToUpdate.getMaxInactiveInterval().minusMillis(100).toMillis());
}
Thread.sleep(2000);
assertThat(this.repository.findById(sessionToUpdate.getId())).isNotNull();
}
@@ -200,6 +194,7 @@ public class EnableHazelcastHttpSessionEventsTests<S extends Session> {
public SessionEventRegistry sessionEventRegistry() {
return new SessionEventRegistry();
}
}
}

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.9.xsd">
xsi:schemaLocation="http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.11.xsd">
<user-code-deployment enabled="true">
<class-cache-mode>ETERNAL</class-cache-mode>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.9.xsd">
xsi:schemaLocation="http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.11.xsd">
<group>
<name>spring-session-it-test-idle-time-map-name</name>

View File

@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<hazelcast xmlns="http://www.hazelcast.com/schema/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.hazelcast.com/schema/config hazelcast-config-3.9.xsd">
xsi:schemaLocation="http://www.hazelcast.com/schema/config http://www.hazelcast.com/schema/config/hazelcast-config-3.11.xsd">
<group>
<name>spring-session-it-test-map-name</name>

View File

@@ -30,11 +30,11 @@ import org.springframework.session.MapSession;
* Hazelcast {@link EntryProcessor} responsible for handling updates to session.
*
* @author Vedran Pavic
* @since 2.0.5
* @since 1.3.4
* @see HazelcastSessionRepository#save(HazelcastSessionRepository.HazelcastSession)
*/
class SessionUpdateEntryProcessor extends AbstractEntryProcessor<String, MapSession>
implements Offloadable {
public class SessionUpdateEntryProcessor
extends AbstractEntryProcessor<String, MapSession> implements Offloadable {
private Instant lastAccessedTime;

View File

@@ -39,7 +39,7 @@ import org.springframework.session.MapSession;
import org.springframework.session.hazelcast.HazelcastSessionRepository.HazelcastSession;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
@@ -78,9 +78,9 @@ public class HazelcastSessionRepositoryTests {
@Test
public void constructorNullHazelcastInstance() {
assertThatThrownBy(() -> new HazelcastSessionRepository(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("HazelcastInstance must not be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> new HazelcastSessionRepository(null))
.withMessage("HazelcastInstance must not be null");
}
@Test

View File

@@ -32,7 +32,7 @@ import org.springframework.session.hazelcast.config.annotation.SpringSessionHaze
import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
@@ -62,10 +62,10 @@ public class HazelcastHttpSessionConfigurationTests {
@Test
public void noHazelcastInstanceConfiguration() {
assertThatThrownBy(
() -> registerAndRefresh(NoHazelcastInstanceConfiguration.class))
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("HazelcastInstance");
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(
() -> registerAndRefresh(NoHazelcastInstanceConfiguration.class))
.withMessageContaining("HazelcastInstance");
}
@Test
@@ -206,10 +206,9 @@ public class HazelcastHttpSessionConfigurationTests {
@Test
public void multipleHazelcastInstanceConfiguration() {
assertThatThrownBy(
assertThatExceptionOfType(BeanCreationException.class).isThrownBy(
() -> registerAndRefresh(MultipleHazelcastInstanceConfiguration.class))
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("expected single matching bean but found 2");
.withMessageContaining("expected single matching bean but found 2");
}
private void registerAndRefresh(Class<?>... annotatedClasses) {

View File

@@ -13,6 +13,7 @@ dependencies {
integrationTestCompile "com.h2database:h2"
integrationTestCompile "com.microsoft.sqlserver:mssql-jdbc"
integrationTestCompile "com.zaxxer:HikariCP"
integrationTestCompile "mysql:mysql-connector-java"
integrationTestCompile "org.apache.derby:derby"
integrationTestCompile "org.hsqldb:hsqldb"
@@ -21,5 +22,6 @@ dependencies {
integrationTestCompile "org.testcontainers:mariadb"
integrationTestCompile "org.testcontainers:mssqlserver"
integrationTestCompile "org.testcontainers:mysql"
integrationTestCompile "org.testcontainers:oracle-xe"
integrationTestCompile "org.testcontainers:postgresql"
}

View File

@@ -0,0 +1,59 @@
/*
* Copyright 2014-2018 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;
import javax.sql.DataSource;
import com.zaxxer.hikari.HikariDataSource;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
/**
* Abstract base class for Testcontainers based {@link JdbcOperationsSessionRepository}
* integration tests.
*
* @author Vedran Pavic
*/
public abstract class AbstractContainerJdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
static class BaseContainerConfig extends BaseConfig {
@Bean
public HikariDataSource dataSource(JdbcDatabaseContainer databaseContainer) {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(databaseContainer.getJdbcUrl());
dataSource.setUsername(databaseContainer.getUsername());
dataSource.setPassword(databaseContainer.getPassword());
return dataSource;
}
@Bean
public DataSourceInitializer dataSourceInitializer(DataSource dataSource,
DatabasePopulator databasePopulator) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(databasePopulator);
return initializer;
}
}
}

View File

@@ -49,7 +49,6 @@ import static org.assertj.core.api.Assertions.assertThat;
* Abstract base class for {@link JdbcOperationsSessionRepository} integration tests.
*
* @author Vedran Pavic
* @since 1.2.0
*/
public abstract class AbstractJdbcOperationsSessionRepositoryITests {
@@ -65,7 +64,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
private SecurityContext changedContext;
@Before
public void setup() throws Exception {
public void setUp() {
this.context = SecurityContextHolder.createEmptyContext();
this.context.setAuthentication(
new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(),
@@ -78,12 +77,13 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void saveWhenNoAttributesThenCanBeFound() throws Exception {
public void saveWhenNoAttributesThenCanBeFound() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
this.repository.save(toSave);
JdbcOperationsSessionRepository.JdbcSession session = this.repository.findById(toSave.getId());
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.findById(toSave.getId());
assertThat(session).isNotNull();
assertThat(session.isChanged()).isFalse();
@@ -91,7 +91,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void saves() throws InterruptedException {
public void saves() {
String username = "saves-" + System.currentTimeMillis();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
@@ -108,7 +108,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
this.repository.save(toSave);
JdbcOperationsSessionRepository.JdbcSession session = this.repository.findById(toSave.getId());
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.findById(toSave.getId());
assertThat(session.getId()).isEqualTo(toSave.getId());
assertThat(session.isChanged()).isFalse();
@@ -145,7 +146,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
this.repository.save(toSave);
toSave = this.repository.findById(toSave.getId());
JdbcOperationsSessionRepository.JdbcSession session = this.repository.findById(toSave.getId());
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.findById(toSave.getId());
assertThat(session.isChanged()).isFalse();
assertThat(session.getDelta()).isEmpty();
assertThat(session.getAttributeNames().size()).isEqualTo(2);
@@ -159,8 +161,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
public void updateLastAccessedTime() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setLastAccessedTime(Instant.now().minusSeconds(
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1));
toSave.setLastAccessedTime(Instant.now()
.minusSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1));
this.repository.save(toSave);
@@ -168,7 +170,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
toSave.setLastAccessedTime(lastAccessedTime);
this.repository.save(toSave);
JdbcOperationsSessionRepository.JdbcSession session = this.repository.findById(toSave.getId());
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.findById(toSave.getId());
assertThat(session).isNotNull();
assertThat(session.isChanged()).isFalse();
@@ -179,7 +182,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByPrincipalName() throws Exception {
public void findByPrincipalName() {
String principalName = "findByPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
@@ -203,14 +206,14 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
public void findByPrincipalNameExpireRemovesIndex() {
String principalName = "findByPrincipalNameExpireRemovesIndex"
+ UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
toSave.setLastAccessedTime(Instant.now().minusSeconds(
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1));
toSave.setLastAccessedTime(Instant.now()
.minusSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1));
this.repository.save(toSave);
this.repository.cleanUpExpiredSessions();
@@ -223,7 +226,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
public void findByPrincipalNameNoPrincipalNameChange() {
String principalName = "findByPrincipalNameNoPrincipalNameChange"
+ UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
@@ -247,7 +250,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
public void findByPrincipalNameNoPrincipalNameChangeReload() {
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
+ UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
@@ -273,7 +276,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByDeletedPrincipalName() throws Exception {
public void findByDeletedPrincipalName() {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
@@ -291,7 +294,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByChangedPrincipalName() throws Exception {
public void findByChangedPrincipalName() {
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
@@ -319,7 +322,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByDeletedPrincipalNameReload() throws Exception {
public void findByDeletedPrincipalNameReload() {
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
@@ -339,7 +342,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByChangedPrincipalNameReload() throws Exception {
public void findByChangedPrincipalNameReload() {
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
@@ -370,7 +373,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findBySecurityPrincipalName() throws Exception {
public void findBySecurityPrincipalName() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
@@ -393,12 +396,12 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
public void findBySecurityPrincipalNameExpireRemovesIndex() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
toSave.setLastAccessedTime(Instant.now().minusSeconds(
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1));
toSave.setLastAccessedTime(Instant.now()
.minusSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS + 1));
this.repository.save(toSave);
this.repository.cleanUpExpiredSessions();
@@ -411,7 +414,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
public void findByPrincipalNameNoSecurityPrincipalNameChange() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
@@ -433,8 +436,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
throws Exception {
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
@@ -458,7 +460,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByDeletedSecurityPrincipalName() throws Exception {
public void findByDeletedSecurityPrincipalName() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
@@ -475,7 +477,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByChangedSecurityPrincipalName() throws Exception {
public void findByChangedSecurityPrincipalName() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
@@ -501,7 +503,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
public void findByDeletedSecurityPrincipalNameReload() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
@@ -520,7 +522,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void findByChangedSecurityPrincipalNameReload() throws Exception {
public void findByChangedSecurityPrincipalNameReload() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
@@ -607,15 +609,17 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void changeSessionIdWhenOnlyChangeId() throws Exception {
public void changeSessionIdWhenOnlyChangeId() {
String attrName = "changeSessionId";
String attrValue = "changeSessionId-value";
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
toSave.setAttribute(attrName, attrValue);
this.repository.save(toSave);
JdbcOperationsSessionRepository.JdbcSession findById = this.repository.findById(toSave.getId());
JdbcOperationsSessionRepository.JdbcSession findById = this.repository
.findById(toSave.getId());
assertThat(findById.<String>getAttribute(attrName)).isEqualTo(attrValue);
@@ -626,16 +630,19 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
assertThat(this.repository.findById(originalFindById)).isNull();
JdbcOperationsSessionRepository.JdbcSession findByChangeSessionId = this.repository.findById(changeSessionId);
JdbcOperationsSessionRepository.JdbcSession findByChangeSessionId = this.repository
.findById(changeSessionId);
assertThat(findByChangeSessionId.isChanged()).isFalse();
assertThat(findByChangeSessionId.getDelta()).isEmpty();
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
assertThat(findByChangeSessionId.<String>getAttribute(attrName))
.isEqualTo(attrValue);
}
@Test
public void changeSessionIdWhenChangeTwice() throws Exception {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
public void changeSessionIdWhenChangeTwice() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
this.repository.save(toSave);
@@ -651,15 +658,17 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@Test
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
public void changeSessionIdWhenSetAttributeOnChangedSession() {
String attrName = "changeSessionId";
String attrValue = "changeSessionId-value";
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
this.repository.save(toSave);
JdbcOperationsSessionRepository.JdbcSession findById = this.repository.findById(toSave.getId());
JdbcOperationsSessionRepository.JdbcSession findById = this.repository
.findById(toSave.getId());
findById.setAttribute(attrName, attrValue);
@@ -670,19 +679,19 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
assertThat(this.repository.findById(originalFindById)).isNull();
JdbcOperationsSessionRepository.JdbcSession findByChangeSessionId = this.repository.findById(changeSessionId);
JdbcOperationsSessionRepository.JdbcSession findByChangeSessionId = this.repository
.findById(changeSessionId);
assertThat(findByChangeSessionId.isChanged()).isFalse();
assertThat(findByChangeSessionId.getDelta()).isEmpty();
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
assertThat(findByChangeSessionId.<String>getAttribute(attrName))
.isEqualTo(attrValue);
}
@Test
public void changeSessionIdWhenHasNotSaved() throws Exception {
String attrName = "changeSessionId";
String attrValue = "changeSessionId-value";
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository.createSession();
public void changeSessionIdWhenHasNotSaved() {
JdbcOperationsSessionRepository.JdbcSession toSave = this.repository
.createSession();
String originalId = toSave.getId();
toSave.changeSessionId();
@@ -694,7 +703,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
@Test // gh-1070
public void saveUpdatedAddAndModifyAttribute() {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.createSession();
this.repository.save(session);
session = this.repository.findById(session.getId());
session.setAttribute("testName", "testValue1");
@@ -707,7 +717,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
@Test // gh-1070
public void saveUpdatedAddAndRemoveAttribute() {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.createSession();
this.repository.save(session);
session = this.repository.findById(session.getId());
session.setAttribute("testName", "testValue");
@@ -720,7 +731,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
@Test // gh-1070
public void saveUpdatedModifyAndRemoveAttribute() {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.createSession();
session.setAttribute("testName", "testValue1");
this.repository.save(session);
session = this.repository.findById(session.getId());
@@ -734,7 +746,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
@Test // gh-1070
public void saveUpdatedRemoveAndAddAttribute() {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.createSession();
session.setAttribute("testName", "testValue1");
this.repository.save(session);
session = this.repository.findById(session.getId());
@@ -748,7 +761,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
@Test // gh-1031
public void saveDeleted() {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.createSession();
this.repository.save(session);
session = this.repository.findById(session.getId());
this.repository.deleteById(session.getId());
@@ -760,7 +774,8 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
@Test // gh-1031
public void saveDeletedAddAttribute() {
JdbcOperationsSessionRepository.JdbcSession session = this.repository.createSession();
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.createSession();
this.repository.save(session);
session = this.repository.findById(session.getId());
this.repository.deleteById(session.getId());
@@ -796,6 +811,21 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
.isEqualTo("value2");
}
@Test // gh-1203
public void saveWithLargeAttribute() {
String attributeName = "largeAttribute";
int arraySize = 4000;
JdbcOperationsSessionRepository.JdbcSession session = this.repository
.createSession();
session.setAttribute(attributeName, new byte[arraySize]);
this.repository.save(session);
session = this.repository.findById(session.getId());
assertThat(session).isNotNull();
assertThat((byte[]) session.getAttribute(attributeName)).hasSize(arraySize);
}
private String getSecurityName() {
return this.context.getAuthentication().getName();
}
@@ -805,7 +835,7 @@ public abstract class AbstractJdbcOperationsSessionRepositoryITests {
}
@EnableJdbcHttpSession
protected static class BaseConfig {
static class BaseConfig {
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {

View File

@@ -0,0 +1,178 @@
/*
* Copyright 2014-2019 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;
import org.testcontainers.containers.JdbcDatabaseContainer;
import org.testcontainers.containers.MSSQLServerContainer;
import org.testcontainers.containers.MariaDBContainer;
import org.testcontainers.containers.MySQLContainer;
import org.testcontainers.containers.OracleContainer;
import org.testcontainers.containers.PostgreSQLContainer;
/**
* Factories for various {@link JdbcDatabaseContainer}s.
*
* @author Vedran Pavic
*/
final class DatabaseContainers {
private DatabaseContainers() {
}
static MariaDBContainer mariaDb5() {
return new MariaDb5Container();
}
static MariaDBContainer mariaDb10() {
return new MariaDb10Container();
}
static MySQLContainer mySql5() {
return new MySql5Container();
}
static MySQLContainer mySql8() {
return new MySql8Container();
}
static OracleContainer oracle() {
return new OracleContainer();
}
static PostgreSQLContainer postgreSql9() {
return new PostgreSql9Container();
}
static PostgreSQLContainer postgreSql10() {
return new PostgreSql10Container();
}
static PostgreSQLContainer postgreSql11() {
return new PostgreSql11Container();
}
static MSSQLServerContainer sqlServer2017() {
return new SqlServer2017Container();
}
private static class MariaDb5Container extends MariaDBContainer<MariaDb5Container> {
MariaDb5Container() {
super("mariadb:5.5.62");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci", "--innodb_large_prefix",
"--innodb_file_format=barracuda", "--innodb-file-per-table");
}
}
private static class MariaDb10Container extends MariaDBContainer<MariaDb10Container> {
MariaDb10Container() {
super("mariadb:10.3.12");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci");
}
}
private static class MySql5Container extends MySQLContainer<MySql5Container> {
MySql5Container() {
super("mysql:5.7.24");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci");
}
@Override
public String getDriverClassName() {
return "com.mysql.cj.jdbc.Driver";
}
}
private static class MySql8Container extends MySQLContainer<MySql8Container> {
MySql8Container() {
super("mysql:8.0.13");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--default-authentication-plugin=mysql_native_password");
}
@Override
public String getDriverClassName() {
return "com.mysql.cj.jdbc.Driver";
}
}
private static class PostgreSql9Container
extends PostgreSQLContainer<PostgreSql9Container> {
PostgreSql9Container() {
super("postgres:9.6.11");
}
}
private static class PostgreSql10Container
extends PostgreSQLContainer<PostgreSql10Container> {
PostgreSql10Container() {
super("postgres:10.6");
}
}
private static class PostgreSql11Container
extends PostgreSQLContainer<PostgreSql11Container> {
PostgreSql11Container() {
super("postgres:11.1");
}
}
private static class SqlServer2017Container
extends MSSQLServerContainer<SqlServer2017Container> {
SqlServer2017Container() {
super("mcr.microsoft.com/mssql/server:2017-CU12");
}
}
}

View File

@@ -0,0 +1,53 @@
/*
* Copyright 2014-2018 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;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
/**
* Factories for various {@link DatabasePopulator}s.
*
* @author Vedran Pavic
*/
final class DatabasePopulators {
private DatabasePopulators() {
}
static ResourceDatabasePopulator mySql() {
return new ResourceDatabasePopulator(new ClassPathResource(
"org/springframework/session/jdbc/schema-mysql.sql"));
}
static ResourceDatabasePopulator oracle() {
return new ResourceDatabasePopulator(new ClassPathResource(
"org/springframework/session/jdbc/schema-oracle.sql"));
}
static ResourceDatabasePopulator postgreSql() {
return new ResourceDatabasePopulator(new ClassPathResource(
"org/springframework/session/jdbc/schema-postgresql.sql"));
}
static ResourceDatabasePopulator sqlServer() {
return new ResourceDatabasePopulator(new ClassPathResource(
"org/springframework/session/jdbc/schema-sqlserver.sql"));
}
}

View File

@@ -16,20 +16,11 @@
package org.springframework.session.jdbc;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.mariadb.jdbc.MariaDbDataSource;
import org.testcontainers.containers.MariaDBContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@@ -45,55 +36,21 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@ContextConfiguration
public class MariaDb10JdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
private static MariaDBContainer container = new MariaDb10Container();
@BeforeClass
public static void setUpClass() {
container.start();
}
@AfterClass
public static void tearDownClass() {
container.stop();
}
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseConfig {
static class Config extends BaseContainerConfig {
@Bean
public DataSource dataSource() throws SQLException {
MariaDbDataSource dataSource = new MariaDbDataSource(container.getJdbcUrl());
dataSource.setUserName(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
public MariaDBContainer databaseContainer() {
MariaDBContainer databaseContainer = DatabaseContainers.mariaDb10();
databaseContainer.start();
return databaseContainer;
}
@Bean
public DataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(
new ResourceDatabasePopulator(resourceLoader.getResource(
"classpath:org/springframework/session/jdbc/schema-mysql.sql")));
return initializer;
}
}
private static class MariaDb10Container extends MariaDBContainer<MariaDb10Container> {
MariaDb10Container() {
super("mariadb:10.3.9");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci");
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.mySql();
}
}

View File

@@ -16,20 +16,11 @@
package org.springframework.session.jdbc;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.mariadb.jdbc.MariaDbDataSource;
import org.testcontainers.containers.MariaDBContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@@ -45,56 +36,21 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@ContextConfiguration
public class MariaDb5JdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
private static MariaDBContainer container = new MariaDb5Container();
@BeforeClass
public static void setUpClass() {
container.start();
}
@AfterClass
public static void tearDownClass() {
container.stop();
}
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseConfig {
static class Config extends BaseContainerConfig {
@Bean
public DataSource dataSource() throws SQLException {
MariaDbDataSource dataSource = new MariaDbDataSource(container.getJdbcUrl());
dataSource.setUserName(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
public MariaDBContainer databaseContainer() {
MariaDBContainer databaseContainer = DatabaseContainers.mariaDb5();
databaseContainer.start();
return databaseContainer;
}
@Bean
public DataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(
new ResourceDatabasePopulator(resourceLoader.getResource(
"classpath:org/springframework/session/jdbc/schema-mysql.sql")));
return initializer;
}
}
private static class MariaDb5Container extends MariaDBContainer<MariaDb5Container> {
MariaDb5Container() {
super("mariadb:5.5.61");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci", "--innodb_large_prefix",
"--innodb_file_format=barracuda", "--innodb-file-per-table");
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.mySql();
}
}

View File

@@ -16,19 +16,11 @@
package org.springframework.session.jdbc;
import javax.sql.DataSource;
import com.mysql.cj.jdbc.Driver;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.testcontainers.containers.MySQLContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@@ -43,61 +35,21 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@ContextConfiguration
public class MySql5JdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
private static MySQLContainer container = new MySql5Container();
@BeforeClass
public static void setUpClass() {
container.start();
}
@AfterClass
public static void tearDownClass() {
container.stop();
}
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseConfig {
static class Config extends BaseContainerConfig {
@Bean
public DataSource dataSource() {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUrl(container.getJdbcUrl());
dataSource.setUser(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
public MySQLContainer databaseContainer() {
MySQLContainer databaseContainer = DatabaseContainers.mySql5();
databaseContainer.start();
return databaseContainer;
}
@Bean
public DataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(
new ResourceDatabasePopulator(resourceLoader.getResource(
"classpath:org/springframework/session/jdbc/schema-mysql.sql")));
return initializer;
}
}
private static class MySql5Container extends MySQLContainer<MySql5Container> {
MySql5Container() {
super("mysql:5.7.23");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--character-set-server=utf8mb4",
"--collation-server=utf8mb4_unicode_ci");
}
@Override
public String getDriverClassName() {
return Driver.class.getName();
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.mySql();
}
}

View File

@@ -16,19 +16,11 @@
package org.springframework.session.jdbc;
import javax.sql.DataSource;
import com.mysql.cj.jdbc.Driver;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.testcontainers.containers.MySQLContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@@ -43,60 +35,21 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@ContextConfiguration
public class MySql8JdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
private static MySQLContainer container = new MySql8Container();
@BeforeClass
public static void setUpClass() {
container.start();
}
@AfterClass
public static void tearDownClass() {
container.stop();
}
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseConfig {
static class Config extends BaseContainerConfig {
@Bean
public DataSource dataSource() {
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUrl(container.getJdbcUrl());
dataSource.setUser(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
public MySQLContainer databaseContainer() {
MySQLContainer databaseContainer = DatabaseContainers.mySql8();
databaseContainer.start();
return databaseContainer;
}
@Bean
public DataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(
new ResourceDatabasePopulator(resourceLoader.getResource(
"classpath:org/springframework/session/jdbc/schema-mysql.sql")));
return initializer;
}
}
private static class MySql8Container extends MySQLContainer<MySql8Container> {
MySql8Container() {
super("mysql:8.0.12");
}
@Override
protected void configure() {
super.configure();
setCommand("mysqld", "--default-authentication-plugin=mysql_native_password");
}
@Override
public String getDriverClassName() {
return Driver.class.getName();
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.mySql();
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright 2014-2018 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;
import org.junit.Assume;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.testcontainers.containers.OracleContainer;
import org.testcontainers.utility.TestcontainersConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.util.ClassUtils;
/**
* Integration tests for {@link JdbcOperationsSessionRepository} using Oracle database.
* <p>
* This test is conditional on presence of Oracle JDBC driver on the classpath and
* Testcontainers property {@code oracle.container.image} being set.
*
* @author Vedran Pavic
*/
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class OracleJdbcOperationsSessionRepositoryITests
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@BeforeClass
public static void setUpClass() {
Assume.assumeTrue("Oracle JDBC driver is present on the classpath",
ClassUtils.isPresent("oracle.jdbc.OracleDriver", null));
Assume.assumeTrue("Testcontainers property `oracle.container.image` is set",
TestcontainersConfiguration.getInstance().getProperties()
.getProperty("oracle.container.image") != null);
}
@Configuration
static class Config extends BaseContainerConfig {
@Bean
public OracleContainer databaseContainer() {
OracleContainer databaseContainer = DatabaseContainers.oracle();
databaseContainer.start();
return databaseContainer;
}
@Bean
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.oracle();
}
}
}

View File

@@ -16,18 +16,11 @@
package org.springframework.session.jdbc;
import javax.sql.DataSource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.postgresql.ds.PGSimpleDataSource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@@ -43,50 +36,21 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@ContextConfiguration
public class PostgreSql10JdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
private static PostgreSQLContainer container = new PostgreSql10Container();
@BeforeClass
public static void setUpClass() {
container.start();
}
@AfterClass
public static void tearDownClass() {
container.stop();
}
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseConfig {
static class Config extends BaseContainerConfig {
@Bean
public DataSource dataSource() {
PGSimpleDataSource dataSource = new PGSimpleDataSource();
dataSource.setUrl(container.getJdbcUrl());
dataSource.setUser(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
public PostgreSQLContainer databaseContainer() {
PostgreSQLContainer databaseContainer = DatabaseContainers.postgreSql10();
databaseContainer.start();
return databaseContainer;
}
@Bean
public DataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(
new ResourceDatabasePopulator(resourceLoader.getResource(
"classpath:org/springframework/session/jdbc/schema-postgresql.sql")));
return initializer;
}
}
private static class PostgreSql10Container
extends PostgreSQLContainer<PostgreSql10Container> {
PostgreSql10Container() {
super("postgres:10.5");
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.postgreSql();
}
}

View File

@@ -0,0 +1,58 @@
/*
* Copyright 2014-2018 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;
import org.junit.runner.RunWith;
import org.testcontainers.containers.PostgreSQLContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.context.web.WebAppConfiguration;
/**
* Integration tests for {@link JdbcOperationsSessionRepository} using PostgreSQL 11.x
* database.
*
* @author Vedran Pavic
*/
@RunWith(SpringRunner.class)
@WebAppConfiguration
@ContextConfiguration
public class PostgreSql11JdbcOperationsSessionRepositoryITests
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseContainerConfig {
@Bean
public PostgreSQLContainer databaseContainer() {
PostgreSQLContainer databaseContainer = DatabaseContainers.postgreSql11();
databaseContainer.start();
return databaseContainer;
}
@Bean
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.postgreSql();
}
}
}

View File

@@ -16,18 +16,11 @@
package org.springframework.session.jdbc;
import javax.sql.DataSource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.postgresql.ds.PGSimpleDataSource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@@ -43,50 +36,21 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@ContextConfiguration
public class PostgreSql9JdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
private static PostgreSQLContainer container = new PostgreSql9Container();
@BeforeClass
public static void setUpClass() {
container.start();
}
@AfterClass
public static void tearDownClass() {
container.stop();
}
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseConfig {
static class Config extends BaseContainerConfig {
@Bean
public DataSource dataSource() {
PGSimpleDataSource dataSource = new PGSimpleDataSource();
dataSource.setUrl(container.getJdbcUrl());
dataSource.setUser(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
public PostgreSQLContainer databaseContainer() {
PostgreSQLContainer databaseContainer = DatabaseContainers.postgreSql9();
databaseContainer.start();
return databaseContainer;
}
@Bean
public DataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(
new ResourceDatabasePopulator(resourceLoader.getResource(
"classpath:org/springframework/session/jdbc/schema-postgresql.sql")));
return initializer;
}
}
private static class PostgreSql9Container
extends PostgreSQLContainer<PostgreSql9Container> {
PostgreSql9Container() {
super("postgres:9.6.10");
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.postgreSql();
}
}

View File

@@ -16,18 +16,11 @@
package org.springframework.session.jdbc;
import javax.sql.DataSource;
import com.microsoft.sqlserver.jdbc.SQLServerDataSource;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.testcontainers.containers.MSSQLServerContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ResourceLoader;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringRunner;
@@ -43,52 +36,21 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
@ContextConfiguration
public class SqlServerJdbcOperationsSessionRepositoryITests
extends AbstractJdbcOperationsSessionRepositoryITests {
private static MSSQLServerContainer container = new SqlServer2007Container();
@BeforeClass
public static void setUpClass() {
container.start();
}
@AfterClass
public static void tearDownClass() {
container.stop();
}
extends AbstractContainerJdbcOperationsSessionRepositoryITests {
@Configuration
static class Config extends BaseConfig {
static class Config extends BaseContainerConfig {
@Bean
public DataSource dataSource() {
SQLServerDataSource dataSource = new SQLServerDataSource();
dataSource.setURL(container.getJdbcUrl());
dataSource.setUser(container.getUsername());
dataSource.setPassword(container.getPassword());
return dataSource;
public MSSQLServerContainer databaseContainer() {
MSSQLServerContainer databaseContainer = DatabaseContainers.sqlServer2017();
databaseContainer.start();
return databaseContainer;
}
@Bean
public DataSourceInitializer initializer(DataSource dataSource,
ResourceLoader resourceLoader) {
DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(
new ResourceDatabasePopulator(resourceLoader.getResource(
"classpath:org/springframework/session/jdbc/schema-sqlserver.sql")));
return initializer;
}
}
private static class SqlServer2007Container
extends MSSQLServerContainer<SqlServer2007Container> {
SqlServer2007Container() {
super("microsoft/mssql-server-linux:2017-CU10");
withStartupTimeoutSeconds(240);
withConnectTimeoutSeconds(240);
public ResourceDatabasePopulator databasePopulator() {
return DatabasePopulators.sqlServer();
}
}

View File

@@ -1 +1 @@
microsoft/mssql-server-linux:2017-CU10
mcr.microsoft.com/mssql/server:2017-CU12

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2018 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.
@@ -35,6 +35,9 @@ import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.jdbc.support.MetaDataAccessException;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.SchedulingConfigurer;
@@ -102,6 +105,11 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
if (this.lobHandler != null) {
sessionRepository.setLobHandler(this.lobHandler);
}
else if (requiresTemporaryLob(this.dataSource)) {
DefaultLobHandler lobHandler = new DefaultLobHandler();
lobHandler.setCreateTemporaryLob(true);
sessionRepository.setLobHandler(lobHandler);
}
if (this.springSessionConversionService != null) {
sessionRepository.setConversionService(this.springSessionConversionService);
}
@@ -115,6 +123,17 @@ public class JdbcHttpSessionConfiguration extends SpringHttpSessionConfiguration
return sessionRepository;
}
private static boolean requiresTemporaryLob(DataSource dataSource) {
try {
String productName = JdbcUtils.extractDatabaseMetaData(dataSource,
"getDatabaseProductName");
return "Oracle".equalsIgnoreCase(JdbcUtils.commonDatabaseName(productName));
}
catch (MetaDataAccessException ex) {
return false;
}
}
public void setMaxInactiveIntervalInSeconds(Integer maxInactiveIntervalInSeconds) {
this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds;
}

View File

@@ -41,7 +41,7 @@ import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
@@ -80,173 +80,173 @@ public class JdbcOperationsSessionRepositoryTests {
@Test
public void constructorNullJdbcOperations() {
assertThatThrownBy(
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
() -> new JdbcOperationsSessionRepository(null, this.transactionManager))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("JdbcOperations must not be null");
.withMessage("JdbcOperations must not be null");
}
@Test
public void constructorNullTransactionManager() {
assertThatThrownBy(
assertThatExceptionOfType(IllegalArgumentException.class).isThrownBy(
() -> new JdbcOperationsSessionRepository(this.jdbcOperations, null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("TransactionManager must not be null");
.withMessage("TransactionManager must not be null");
}
@Test
public void setTableNameNull() {
assertThatThrownBy(() -> this.repository.setTableName(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Table name must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setTableName(null))
.withMessage("Table name must not be empty");
}
@Test
public void setTableNameEmpty() {
assertThatThrownBy(() -> this.repository.setTableName(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Table name must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setTableName(" "))
.withMessage("Table name must not be empty");
}
@Test
public void setCreateSessionQueryNull() {
assertThatThrownBy(() -> this.repository.setCreateSessionQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setCreateSessionQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setCreateSessionQueryEmpty() {
assertThatThrownBy(() -> this.repository.setCreateSessionQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setCreateSessionQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setCreateSessionAttributeQueryNull() {
assertThatThrownBy(() -> this.repository.setCreateSessionAttributeQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setCreateSessionAttributeQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setCreateSessionAttributeQueryEmpty() {
assertThatThrownBy(() -> this.repository.setCreateSessionAttributeQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setCreateSessionAttributeQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setGetSessionQueryNull() {
assertThatThrownBy(() -> this.repository.setGetSessionQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setGetSessionQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setGetSessionQueryEmpty() {
assertThatThrownBy(() -> this.repository.setGetSessionQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setGetSessionQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setUpdateSessionQueryNull() {
assertThatThrownBy(() -> this.repository.setUpdateSessionQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setUpdateSessionQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setUpdateSessionQueryEmpty() {
assertThatThrownBy(() -> this.repository.setUpdateSessionQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setUpdateSessionQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setUpdateSessionAttributeQueryNull() {
assertThatThrownBy(() -> this.repository.setUpdateSessionAttributeQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setUpdateSessionAttributeQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setUpdateSessionAttributeQueryEmpty() {
assertThatThrownBy(() -> this.repository.setUpdateSessionAttributeQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setUpdateSessionAttributeQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setDeleteSessionAttributeQueryNull() {
assertThatThrownBy(() -> this.repository.setDeleteSessionAttributeQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setDeleteSessionAttributeQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setDeleteSessionAttributeQueryEmpty() {
assertThatThrownBy(() -> this.repository.setDeleteSessionAttributeQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setDeleteSessionAttributeQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setDeleteSessionQueryNull() {
assertThatThrownBy(() -> this.repository.setDeleteSessionQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setDeleteSessionQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setDeleteSessionQueryEmpty() {
assertThatThrownBy(() -> this.repository.setDeleteSessionQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setDeleteSessionQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setListSessionsByPrincipalNameQueryNull() {
assertThatThrownBy(
() -> this.repository.setListSessionsByPrincipalNameQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(
() -> this.repository.setListSessionsByPrincipalNameQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setListSessionsByPrincipalNameQueryEmpty() {
assertThatThrownBy(() -> this.repository.setListSessionsByPrincipalNameQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(
() -> this.repository.setListSessionsByPrincipalNameQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setDeleteSessionsByLastAccessTimeQueryNull() {
assertThatThrownBy(() -> this.repository.setDeleteSessionsByExpiryTimeQuery(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(
() -> this.repository.setDeleteSessionsByExpiryTimeQuery(null))
.withMessage("Query must not be empty");
}
@Test
public void setDeleteSessionsByLastAccessTimeQueryEmpty() {
assertThatThrownBy(() -> this.repository.setDeleteSessionsByExpiryTimeQuery(" "))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Query must not be empty");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setDeleteSessionsByExpiryTimeQuery(" "))
.withMessage("Query must not be empty");
}
@Test
public void setLobHandlerNull() {
assertThatThrownBy(() -> this.repository.setLobHandler(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("LobHandler must not be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setLobHandler(null))
.withMessage("LobHandler must not be null");
}
@Test
public void setConversionServiceNull() {
assertThatThrownBy(() -> this.repository.setConversionService(null))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("conversionService must not be null");
assertThatExceptionOfType(IllegalArgumentException.class)
.isThrownBy(() -> this.repository.setConversionService(null))
.withMessage("conversionService must not be null");
}
@Test

View File

@@ -37,7 +37,7 @@ import org.springframework.test.util.ReflectionTestUtils;
import org.springframework.transaction.PlatformTransactionManager;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.mock;
/**
@@ -66,8 +66,9 @@ public class JdbcHttpSessionConfigurationTests {
@Test
public void noDataSourceConfiguration() {
assertThatThrownBy(() -> registerAndRefresh(NoDataSourceConfiguration.class))
.isInstanceOf(BeanCreationException.class).hasMessageContaining(
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(() -> registerAndRefresh(NoDataSourceConfiguration.class))
.withMessageContaining(
"expected at least 1 bean which qualifies as autowire candidate");
}
@@ -224,10 +225,10 @@ public class JdbcHttpSessionConfigurationTests {
@Test
public void multipleDataSourceConfiguration() {
assertThatThrownBy(() -> registerAndRefresh(DataSourceConfiguration.class,
MultipleDataSourceConfiguration.class))
.isInstanceOf(BeanCreationException.class)
.hasMessageContaining("expected single matching bean but found 2");
assertThatExceptionOfType(BeanCreationException.class)
.isThrownBy(() -> registerAndRefresh(DataSourceConfiguration.class,
MultipleDataSourceConfiguration.class))
.withMessageContaining("expected single matching bean but found 2");
}
@Test