Compare commits

...

82 Commits

Author SHA1 Message Date
Eleftheria Stein
76279cd9ba Release 2.4.6 2021-10-19 15:26:44 +02:00
Eleftheria Stein
de1f2fc60e Upgrade test dependencies 2021-10-19 14:04:34 +02:00
Eleftheria Stein
f96e05dc47 Upgrade samples to Spring Boot 2.4.11
Closes gh-1938
2021-10-19 13:30:21 +02:00
Eleftheria Stein
519413d5ae Upgrade Spring Security to 5.4.9
Closes gh-1937
2021-10-19 13:28:52 +02:00
Eleftheria Stein
2ea90c5aff Upgrade Spring Data to 2020.0.14
Closes gh-1936
2021-10-19 13:27:40 +02:00
Eleftheria Stein
2eb236208a Upgrade Spring Framework to 5.3.11
Closes gh-1935
2021-10-19 13:25:57 +02:00
Eleftheria Stein
106dd9f772 Upgrade Reactor to 2020.0.12
Closes gh-1934
2021-10-19 13:25:22 +02:00
Vedran Pavic
86e584e1c5 Make Hazelcast session repository bean factory return type more specific
The declared return type of Hazelcast session repository bean factory method (i.e. HazelcastHttpSessionConfiguration#sessionRepository) was changed to SessionRepository<?> when support for Hazelcast 4 was added. This breaks Spring Boot's ability to auto-configure sessions endpoint, which is @ConditionalOnBean(FindByIndexNameSessionRepository.class), as the current return type is not specific enough to satisfy this condition.

This commit changes the return type of Hazelcast session repository bean factory method to FindByIndexNameSessionRepository<?>.

Closes: gh-1906
2021-09-28 09:34:40 +02:00
Vedran Pavic
c707c17bea Fix Spring Boot based Hazelcast samples
This commit removes unused Hazelcast client dependencies and test support from Spring Boot based Hazelcast samples.

Closes: gh-1904
2021-09-27 16:37:16 +02:00
Eleftheria Stein
7f1a777767 Next development version 2021-08-17 19:15:22 +02:00
Eleftheria Stein
24fc8d94c4 Release 2.4.5 2021-08-17 18:50:46 +02:00
Eleftheria Stein
b6b99e9ffd Upgrade test dependencies 2021-08-17 17:26:33 +02:00
Eleftheria Stein
b1b10614ea Upgrade Spring Security to 5.4.8
Closes gh-1896
2021-08-17 17:17:17 +02:00
Eleftheria Stein
5f7b4266d8 Upgrade Spring Data to 2020.0.12
Closes gh-1895
2021-08-17 17:16:26 +02:00
Eleftheria Stein
8e71132a15 Upgrade Spring Framework to 5.3.9
Closes gh-1894
2021-08-17 17:15:49 +02:00
Eleftheria Stein
c37237ae98 Upgrade Reactor to 2020.0.10
Closes gh-1893
2021-08-17 17:15:10 +02:00
John Blum
12ab0029f5 Next development version 2021-06-22 12:43:47 -07:00
Eleftheria Stein
1b4fb13d4d Release 2.4.4 2021-06-22 17:52:36 +02:00
Eleftheria Stein
21be7aac9c Update JDBC test images
Closes gh-1877
2021-06-22 17:37:00 +02:00
Eleftheria Stein
67f4850024 Revert "Release 2.4.4"
This reverts commit a92abcb26f.
2021-06-22 14:11:26 +02:00
Eleftheria Stein
a92abcb26f Release 2.4.4 2021-06-22 13:15:55 +02:00
Eleftheria Stein
041fb222f9 Revert "Use GPG_PRIVATE_KEY directly in build"
This reverts commit eed2ff195a.
2021-06-22 13:15:25 +02:00
Eleftheria Stein
dc951435d4 Upgrade test dependencies 2021-06-22 11:48:32 +02:00
Eleftheria Stein
e9243ceb59 Upgrade samples to Spring Boot 2.4.7
Closes gh-1876
2021-06-22 11:37:43 +02:00
Eleftheria Stein
8fb54ac1e0 Upgrade Spring Data to 2020.0.9
Closes gh-1875
2021-06-22 11:33:00 +02:00
Eleftheria Stein
b0558c1fd2 Upgrade Spring Framework to 5.3.8
Closes gh-1874
2021-06-22 11:31:44 +02:00
Eleftheria Stein
f570c2065b Upgrade Reactor to 2020.0.7
Closes gh-1873
2021-06-22 11:30:32 +02:00
Eleftheria Stein
eed2ff195a Use GPG_PRIVATE_KEY directly in build
Closes gh-1861
2021-05-31 16:47:34 +03:00
Eleftheria Stein
c467a7d656 Next development version 2021-04-13 13:39:30 +02:00
Eleftheria Stein
b9618fe6b3 Release 2.4.3 2021-04-13 13:21:46 +02:00
Eleftheria Stein
625833f1fe Upgrade test dependencies 2021-04-13 13:20:28 +02:00
Eleftheria Stein
f1eee1e7a4 Upgrade Spring Security to 5.4.6
Closes gh-1828
2021-04-13 13:19:39 +02:00
Eleftheria Stein
a2ee77c62e Upgrade Spring Data to 2020.0.7
Closes gh-1827
2021-04-13 13:18:11 +02:00
Eleftheria Stein
3c77d76cee Upgrade Spring Framework to 5.3.5
Closes gh-1826
2021-04-13 13:16:24 +02:00
Eleftheria Stein
6a8d2f4d88 Upgrade Reactor to 2020.0.6
Closes gh-1825
2021-04-13 13:15:39 +02:00
Eleftheria Stein
4c63faece1 Upgrade Hazelcast to 3.12.12
Closes gh-1824
2021-04-13 13:14:36 +02:00
Eleftheria Stein
e2a7e71ae3 Upgrade samples to Spring Boot 2.4.4
Closes gh-1823
2021-04-13 13:13:53 +02:00
Eleftheria Stein
66f81daa20 Throw exception if session created after response
Closes gh-1798
2021-03-25 12:01:53 +02:00
Eleftheria Stein
829b62bd19 Differentiate 2.4.x CI from master CI
- rename CI workflow file
- rename CI workflow identifier
- change daily build time
- ensure checkout is always run on 2.4.x

Issue: gh-1794
2021-02-22 11:19:13 +01:00
Eleftheria Stein
b7209f8330 Make Hazelcast tests independent of ordering
Closes gh-1787
2021-02-02 15:58:02 +01:00
Eleftheria Stein
645e525b84 Upgrade samples to Spring Boot 2.4.2
Closes gh-1782
2021-01-29 17:26:15 +01:00
Eleftheria Stein
ba4bb6fcf6 Use spring-build-conventions:0.0.37 2021-01-27 12:27:27 +01:00
Eleftheria Stein
f224d571f0 Next development version 2021-01-19 18:33:23 +01:00
Eleftheria Stein
3ba76d0375 Add manual trigger to CI workflow
Closes gh-1777
2021-01-19 17:41:19 +01:00
Eleftheria Stein
eb29949996 Release 2.4.2 2021-01-19 14:25:32 +01:00
Eleftheria Stein
02a990d00e Upgrade test dependencies 2021-01-18 13:21:12 +01:00
Eleftheria Stein
56809eacb2 Upgrade Hazelcast to 3.12.11
Closes gh-1766
2021-01-18 13:19:56 +01:00
Eleftheria Stein
4ff8f73b84 Upgrade Spring Data to 2020.0.3
Closes gh-1765
2021-01-18 13:17:38 +01:00
Eleftheria Stein
0ad389633e Upgrade Spring Security to 5.4.2
Closes gh-1764
2021-01-18 13:16:00 +01:00
Eleftheria Stein
5a9046e391 Upgrade Spring Framework to 5.3.3
Closes gh-1763
2021-01-18 13:15:21 +01:00
Eleftheria Stein
690f734307 Upgrade Reactor to 2020.0.3
Closes gh-1762
2021-01-18 13:14:06 +01:00
Eleftheria Stein
823e323f68 Add artifactory credentials to build 2020-11-18 14:39:48 +01:00
Eleftheria Stein
444b5ad85a Rename workflow name to match master 2020-11-10 13:40:22 +01:00
Eleftheria Stein
b4a8c7e516 Create GitHub Actions CI for 2.4.x 2020-11-10 11:52:45 +01:00
Eleftheria Stein
34876397a0 Next development version 2020-11-09 16:49:29 +01:00
Eleftheria Stein
faee8f1bdb Release 2.4.1 2020-11-09 15:40:43 +01:00
Eleftheria Stein
859784fe9e Use secrets from GitHub Actions workflow 2020-11-09 15:39:54 +01:00
Eleftheria Stein
4dd2db32d2 Revert "Release 2.4.1"
This reverts commit ae86831821.
2020-11-09 15:39:20 +01:00
Eleftheria Stein
ae86831821 Release 2.4.1 2020-11-04 17:36:47 +01:00
Eleftheria Stein
b722b12327 Fix formatting
Issue gh-1654
2020-10-30 14:34:37 +01:00
Kohei Tamura
29ff2e47fb Add try-with-resources to methods to insert BLOB 2020-10-30 08:45:52 -04:00
Eleftheria Stein
dc9da1d5bf Use OSSRH token credentials in workflow
Closes gh-1725
2020-10-30 13:42:36 +01:00
Eleftheria Stein
5a52df37ba Next development version 2020-10-28 23:36:40 +01:00
Eleftheria Stein
6d161575d5 Release 2.4.0wq 2020-10-28 22:48:46 +01:00
Eleftheria Stein
1cd8849eb9 Revert "Delete Jenkinsfile"
This reverts commit 68f867b60b.
2020-10-28 22:42:47 +01:00
Eleftheria Stein
cb3894614a Revert "Release 2.4.0"
This reverts commit 82e71d834b.
2020-10-28 22:42:06 +01:00
Eleftheria Stein
82e71d834b Release 2.4.0 2020-10-28 18:40:09 +01:00
Eleftheria Stein
81a9e71a5b Upgrade test and sample dependencies
This is needed in order for them to work with Spring Data 2020.0.0
2020-10-28 18:18:45 +01:00
Eleftheria Stein
298f0d59a0 Upgrade Spring Data to 2020.0.0
Closes gh-1721
2020-10-28 18:18:15 +01:00
Eleftheria Stein
c354284616 Upgrade samples to Spring Boot 2.4.0-M4
Closes gh-1722
2020-10-28 18:17:54 +01:00
Eleftheria Stein
4086044c2f Upgrade Spring Framework to 5.3.0
Closes gh-1720
2020-10-28 09:51:48 +01:00
Eleftheria Stein
e663401ecb Upgrade Hazelcast to 3.12.10
Closes gh-1718
2020-10-27 15:50:35 +01:00
Eleftheria Stein
60151c9e7d Upgrade Spring Security to 5.4.1
Closes gh-1717
2020-10-27 15:50:16 +01:00
Eleftheria Stein
18052460c6 Upgrade Reactor to 2020.0.0
Closes gh-1716
2020-10-27 15:49:49 +01:00
Eleftheria Stein
5092e86306 Upgrade samples to Spring Boot 2.3.4.RELEASE
Closes gh-1719
2020-10-27 15:49:19 +01:00
Eleftheria Stein
6de6df6dab Upgrade test dependencies 2020-10-27 15:15:30 +01:00
Vedran Pavic
301e65c2b9 Remove unnecessary Redis commands in RedisIndexedSessionRepository#save
See: #1331
2020-10-12 10:13:38 -04:00
Vedran Pavic
090a10fb10 Improve RedisSessionRepository-based sample configuration 2020-10-12 03:23:21 -04:00
Eleftheria Stein
235801487e Hazelcast4SessionUpdateEntryProcessor does not implement Offloadable
Closes gh-1707
2020-09-25 10:31:54 +02:00
Eleftheria Stein
e6e02de210 Upgrade Hazelcast 4 to 4.0.3
Closes gh-1706
2020-09-22 11:12:58 +02:00
Eleftheria Stein
b3b46fd8eb Upgrade Hazelcast to 3.12.9
Closes gh-1705
2020-09-22 10:46:15 +02:00
Eleftheria Stein
e46610f53a Next development version 2020-09-16 18:39:21 +02:00
43 changed files with 267 additions and 229 deletions

View File

@@ -1,16 +1,19 @@
name: CI
name: 2.4.x CI
on:
push:
branches:
- master
- 2.4.x
schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC
- cron: '4 10 * * *' # Once per day at 10:04am UTC
workflow_dispatch: # Manual trigger
env:
GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }}
GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
jobs:
build:
@@ -22,6 +25,8 @@ jobs:
fail-fast: false
steps:
- uses: actions/checkout@v2
with:
ref: '2.4.x'
- name: Set up JDK ${{ matrix.jdk }}
uses: actions/setup-java@v1
with:
@@ -37,13 +42,15 @@ jobs:
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
./gradlew clean build --no-daemon --stacktrace
./gradlew clean build -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --no-daemon --stacktrace
artifacts:
name: Deploy Artifacts
needs: [build]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: '2.4.x'
- name: Set up JDK
uses: actions/setup-java@v1
with:
@@ -56,13 +63,13 @@ jobs:
export VERSION_HEADER=$'Version: GnuPG v2\n\n'
export ORG_GRADLE_PROJECT_signingKey=${GPG_PRIVATE_KEY#"$VERSION_HEADER"}
export ORG_GRADLE_PROJECT_signingPassword="$GPG_PASSPHRASE"
./gradlew deployArtifacts -PossrhUsername="$OSSRH_USERNAME" -PossrhPassword="$OSSRH_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
./gradlew finalizeDeployArtifacts -PossrhUsername="$OSSRH_USERNAME" -PossrhPassword="$OSSRH_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
./gradlew deployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
./gradlew finalizeDeployArtifacts -PossrhUsername="$OSSRH_TOKEN_USERNAME" -PossrhPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
env:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_TOKEN_USERNAME }}
OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_TOKEN_PASSWORD }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
docs:
@@ -71,6 +78,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
ref: '2.4.x'
- name: Set up JDK
uses: actions/setup-java@v1
with:

View File

@@ -4,7 +4,7 @@ buildscript {
snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild)
springBootVersion = '2.3.3.RELEASE'
springBootVersion = '2.4.11'
}
repositories {
@@ -14,7 +14,7 @@ buildscript {
}
dependencies {
classpath 'io.spring.gradle:spring-build-conventions:0.0.34.RELEASE'
classpath 'io.spring.gradle:spring-build-conventions:0.0.37'
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
}

View File

@@ -1,3 +1,3 @@
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
version=2.4.0-RC1
version=2.4.6

View File

@@ -1,36 +1,36 @@
dependencyManagement {
imports {
mavenBom 'io.projectreactor:reactor-bom:2020.0.0-RC1'
mavenBom 'org.junit:junit-bom:5.7.0'
mavenBom 'org.springframework:spring-framework-bom:5.3.0-RC1'
mavenBom 'org.springframework.data:spring-data-bom:2020.0.0-RC1'
mavenBom 'org.springframework.security:spring-security-bom:5.4.0'
mavenBom 'org.testcontainers:testcontainers-bom:1.14.3'
mavenBom 'io.projectreactor:reactor-bom:2020.0.12'
mavenBom 'org.junit:junit-bom:5.7.2'
mavenBom 'org.springframework:spring-framework-bom:5.3.11'
mavenBom 'org.springframework.data:spring-data-bom:2020.0.14'
mavenBom 'org.springframework.security:spring-security-bom:5.4.9'
mavenBom 'org.testcontainers:testcontainers-bom:1.15.3'
}
dependencies {
dependencySet(group: 'com.hazelcast', version: '3.12.7') {
dependencySet(group: 'com.hazelcast', version: '3.12.12') {
entry 'hazelcast'
entry 'hazelcast-client'
}
dependency 'org.aspectj:aspectjweaver:1.9.6'
dependency 'org.aspectj:aspectjweaver:1.9.7'
dependency 'com.h2database:h2:1.4.200'
dependency 'com.ibm.db2:jcc:11.5.0.0'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre8'
dependency 'com.oracle.database.jdbc:ojdbc8:19.6.0.0'
dependency 'com.oracle.database.jdbc:ojdbc8:19.8.0.0'
dependency 'com.zaxxer:HikariCP:3.4.5'
dependency 'edu.umd.cs.mtc:multithreadedtc:1.01'
dependency 'io.lettuce:lettuce-core:5.3.3.RELEASE'
dependency 'io.lettuce:lettuce-core:6.0.8.RELEASE'
dependency 'javax.annotation:javax.annotation-api:1.3.2'
dependency 'javax.servlet:javax.servlet-api:4.0.1'
dependency 'junit:junit:4.13'
dependency 'mysql:mysql-connector-java:8.0.21'
dependency 'junit:junit:4.13.2'
dependency 'mysql:mysql-connector-java:8.0.25'
dependency 'org.apache.derby:derby:10.14.2.0'
dependency 'org.assertj:assertj-core:3.17.2'
dependency 'org.assertj:assertj-core:3.18.0'
dependency 'org.hsqldb:hsqldb:2.5.1'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.6.2'
dependency 'org.mockito:mockito-core:3.5.10'
dependency 'org.postgresql:postgresql:42.2.16'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.7.3'
dependency 'org.mockito:mockito-core:3.5.15'
dependency 'org.postgresql:postgresql:42.2.24'
}
}

View File

@@ -309,6 +309,10 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
if (!create) {
return null;
}
if (SessionRepositoryFilter.this.httpSessionIdResolver instanceof CookieHttpSessionIdResolver
&& this.response.isCommitted()) {
throw new IllegalStateException("Cannot create a session after the response has been committed");
}
if (SESSION_LOGGER.isDebugEnabled()) {
SESSION_LOGGER.debug(
"A new session was created. To help you troubleshoot where the session was created we provided a StackTrace (this is not an error). You can prevent this from appearing by disabling DEBUG logging for "

View File

@@ -62,6 +62,7 @@ import org.springframework.test.util.ReflectionTestUtils;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
import static org.assertj.core.api.Assertions.fail;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
@@ -423,6 +424,18 @@ class SessionRepositoryFilterTests {
assertThat(this.response.getCookie("SESSION")).isNotNull();
}
@Test
void doFilterGetSessionNewWhenResponseCommittedThenException() {
assertThatIllegalStateException().isThrownBy(() -> doFilter(new DoInFilter() {
@Override
public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse)
throws IOException {
wrappedResponse.getWriter().flush();
wrappedRequest.getSession();
}
}));
}
@Test
void doFilterGetSessionNew() throws Exception {
doFilter(new DoInFilter() {

View File

@@ -29,7 +29,7 @@ import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactor
*/
public abstract class AbstractRedisITests {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
protected static class BaseConfig {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,6 @@ package org.springframework.session.data.redis;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.junit.jupiter.api.BeforeEach;
@@ -135,22 +134,6 @@ class RedisIndexedSessionRepositoryITests extends AbstractRedisITests {
.isEqualTo(expectedAttributeValue);
}
@Test
void removeAttributeRemovedAttributeKey() {
RedisSession toSave = this.repository.createSession();
toSave.setAttribute("a", "b");
this.repository.save(toSave);
toSave.removeAttribute("a");
this.repository.save(toSave);
String id = toSave.getId();
String key = "RedisIndexedSessionRepositoryITests:sessions:" + id;
Set<Map.Entry<Object, Object>> entries = this.redis.boundHashOps(key).entries().entrySet();
assertThat(entries).extracting(Map.Entry::getKey).doesNotContain("sessionAttr:a");
}
@Test
void putAllOnSingleAttrDoesNotRemoveOld() {
RedisSession toSave = this.repository.createSession();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -792,8 +792,7 @@ public class RedisIndexedSessionRepository
return;
}
String sessionId = getId();
BoundHashOperations<Object, Object, Object> boundHashOperations = getSessionBoundHashOperations(sessionId);
boundHashOperations.putAll(this.delta);
getSessionBoundHashOperations(sessionId).putAll(this.delta);
String principalSessionKey = getSessionAttrNameKey(
FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
String securityPrincipalSessionKey = getSessionAttrNameKey(SPRING_SECURITY_CONTEXT);
@@ -812,11 +811,6 @@ public class RedisIndexedSessionRepository
.add(sessionId);
}
}
for (final Map.Entry<String, Object> attribute : this.delta.entrySet()) {
if (attribute.getValue() == null) {
boundHashOperations.delete(attribute.getKey());
}
}
this.delta = new HashMap<>(this.delta.size());

View File

@@ -31,7 +31,7 @@ artifacts {
dependencies {
compile project(':spring-session-core')
optional "com.hazelcast:hazelcast:4.0.2"
optional "com.hazelcast:hazelcast:4.0.3"
compile "org.springframework:spring-context"
compile "javax.annotation:javax.annotation-api"
@@ -42,7 +42,7 @@ dependencies {
testRuntime "org.junit.jupiter:junit-jupiter-engine"
integrationTestCompile "org.testcontainers:testcontainers"
integrationTestCompile "com.hazelcast:hazelcast:4.0.2"
integrationTestCompile "com.hazelcast:hazelcast:4.0.3"
integrationTestCompile project(":spring-session-hazelcast")
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2021 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,16 +54,13 @@ abstract class AbstractHazelcast4IndexedSessionRepositoryITests {
IMap<String, MapSession> hazelcastMap = this.hazelcastInstance
.getMap(Hazelcast4IndexedSessionRepository.DEFAULT_SESSION_MAP_NAME);
assertThat(hazelcastMap.size()).isEqualTo(0);
this.repository.save(sessionToSave);
assertThat(hazelcastMap.size()).isEqualTo(1);
assertThat(hazelcastMap.get(sessionId)).isEqualTo(sessionToSave);
this.repository.deleteById(sessionId);
assertThat(hazelcastMap.size()).isEqualTo(0);
assertThat(hazelcastMap.get(sessionId)).isNull();
}
@Test
@@ -179,6 +176,8 @@ abstract class AbstractHazelcast4IndexedSessionRepositoryITests {
this.repository.save(session);
assertThat(this.repository.findById(sessionId)).isNotNull();
this.repository.deleteById(sessionId);
}
@Test
@@ -195,6 +194,8 @@ abstract class AbstractHazelcast4IndexedSessionRepositoryITests {
this.repository.save(session);
assertThat(this.repository.findById(sessionId)).isNotNull();
this.repository.deleteById(sessionId);
}
}

View File

@@ -21,7 +21,6 @@ import java.time.Instant;
import com.hazelcast.core.HazelcastInstance;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
@@ -179,7 +178,6 @@ class SessionEventHazelcast4IndexedSessionRepositoryTests<S extends Session> {
}
@Test // gh-1300
@Disabled("See https://github.com/hazelcast/hazelcast/issues/16987")
void updateMaxInactiveIntervalTest() throws InterruptedException {
S sessionToSave = this.repository.createSession();
sessionToSave.setMaxInactiveInterval(Duration.ofMinutes(30));

View File

@@ -19,9 +19,10 @@ package org.springframework.session.hazelcast;
import java.time.Duration;
import java.time.Instant;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import com.hazelcast.core.Offloadable;
import com.hazelcast.map.EntryProcessor;
import com.hazelcast.map.ExtendedMapEntry;
import org.springframework.session.MapSession;
@@ -32,7 +33,7 @@ import org.springframework.session.MapSession;
* @author Eleftheria Stein
* @since 2.4.0
*/
public class Hazelcast4SessionUpdateEntryProcessor implements EntryProcessor<String, MapSession, Object>, Offloadable {
public class Hazelcast4SessionUpdateEntryProcessor implements EntryProcessor<String, MapSession, Object> {
private Instant lastAccessedTime;
@@ -62,15 +63,16 @@ public class Hazelcast4SessionUpdateEntryProcessor implements EntryProcessor<Str
}
}
}
entry.setValue(value);
if (this.maxInactiveInterval != null) {
((ExtendedMapEntry<String, MapSession>) entry).setValue(value, this.maxInactiveInterval.getSeconds(),
TimeUnit.SECONDS);
}
else {
entry.setValue(value);
}
return Boolean.TRUE;
}
@Override
public String getExecutorName() {
return OFFLOADABLE_EXECUTOR;
}
void setLastAccessedTime(Instant lastAccessedTime) {
this.lastAccessedTime = lastAccessedTime;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2021 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.
@@ -58,16 +58,13 @@ abstract class AbstractHazelcastIndexedSessionRepositoryITests {
IMap<String, MapSession> hazelcastMap = this.hazelcastInstance
.getMap(HazelcastIndexedSessionRepository.DEFAULT_SESSION_MAP_NAME);
assertThat(hazelcastMap.size()).isEqualTo(0);
this.repository.save(sessionToSave);
assertThat(hazelcastMap.size()).isEqualTo(1);
assertThat(hazelcastMap.get(sessionId)).isEqualTo(sessionToSave);
this.repository.deleteById(sessionId);
assertThat(hazelcastMap.size()).isEqualTo(0);
assertThat(hazelcastMap.get(sessionId)).isNull();
}
@Test
@@ -183,6 +180,8 @@ abstract class AbstractHazelcastIndexedSessionRepositoryITests {
this.repository.save(session);
assertThat(this.repository.findById(sessionId)).isNotNull();
this.repository.deleteById(sessionId);
}
@Test
@@ -199,6 +198,8 @@ abstract class AbstractHazelcastIndexedSessionRepositoryITests {
this.repository.save(session);
assertThat(this.repository.findById(sessionId)).isNotNull();
this.repository.deleteById(sessionId);
}
@Test
@@ -220,6 +221,8 @@ abstract class AbstractHazelcastIndexedSessionRepositoryITests {
assertThat(this.repository
.findByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, username))
.hasSize(1);
this.repository.deleteById(session.getId());
}
}

View File

@@ -46,7 +46,7 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
class ClientServerHazelcastIndexedSessionRepositoryITests extends AbstractHazelcastIndexedSessionRepositoryITests {
private static GenericContainer container = new GenericContainer<>("hazelcast/hazelcast:3.12.3")
private static GenericContainer container = new GenericContainer<>("hazelcast/hazelcast:3.12.12")
.withExposedPorts(5701).withCopyFileToContainer(MountableFile.forClasspathResource("/hazelcast-server.xml"),
"/opt/hazelcast/hazelcast.xml");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2021 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,12 +30,12 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportAware;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.session.FindByIndexNameSessionRepository;
import org.springframework.session.FlushMode;
import org.springframework.session.IndexResolver;
import org.springframework.session.MapSession;
import org.springframework.session.SaveMode;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.session.config.SessionRepositoryCustomizer;
import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration;
import org.springframework.session.hazelcast.Hazelcast4IndexedSessionRepository;
@@ -85,7 +85,7 @@ public class HazelcastHttpSessionConfiguration extends SpringHttpSessionConfigur
}
@Bean
public SessionRepository<?> sessionRepository() {
public FindByIndexNameSessionRepository<?> sessionRepository() {
if (hazelcast4) {
return createHazelcast4IndexedSessionRepository();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2021 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.
@@ -118,7 +118,7 @@ final class DatabaseContainers {
private static class MySql5Container extends MySQLContainer<MySql5Container> {
MySql5Container() {
super("mysql:5.7.27");
super("mysql:5.7.34");
}
@Override
@@ -137,7 +137,7 @@ final class DatabaseContainers {
private static class MySql8Container extends MySQLContainer<MySql8Container> {
MySql8Container() {
super("mysql:8.0.17");
super("mysql:8.0.27");
}
@Override
@@ -174,7 +174,7 @@ final class DatabaseContainers {
private static class PostgreSql9Container extends PostgreSQLContainer<PostgreSql9Container> {
PostgreSql9Container() {
super("postgres:9.6.15");
super("postgres:9.6.22");
}
}

View File

@@ -44,6 +44,7 @@ import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.LobCreator;
import org.springframework.jdbc.support.lob.LobHandler;
import org.springframework.session.DelegatingIndexResolver;
import org.springframework.session.FindByIndexNameSessionRepository;
@@ -460,63 +461,65 @@ public class JdbcIndexedSessionRepository
private void insertSessionAttributes(JdbcSession session, List<String> attributeNames) {
Assert.notEmpty(attributeNames, "attributeNames must not be null or empty");
if (attributeNames.size() > 1) {
this.jdbcOperations.batchUpdate(this.createSessionAttributeQuery, new BatchPreparedStatementSetter() {
try (LobCreator lobCreator = this.lobHandler.getLobCreator()) {
if (attributeNames.size() > 1) {
this.jdbcOperations.batchUpdate(this.createSessionAttributeQuery, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
String attributeName = attributeNames.get(i);
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
String attributeName = attributeNames.get(i);
ps.setString(1, attributeName);
lobCreator.setBlobAsBytes(ps, 2, serialize(session.getAttribute(attributeName)));
ps.setString(3, session.getId());
}
@Override
public int getBatchSize() {
return attributeNames.size();
}
});
}
else {
this.jdbcOperations.update(this.createSessionAttributeQuery, (ps) -> {
String attributeName = attributeNames.get(0);
ps.setString(1, attributeName);
getLobHandler().getLobCreator().setBlobAsBytes(ps, 2,
serialize(session.getAttribute(attributeName)));
lobCreator.setBlobAsBytes(ps, 2, serialize(session.getAttribute(attributeName)));
ps.setString(3, session.getId());
}
@Override
public int getBatchSize() {
return attributeNames.size();
}
});
}
else {
this.jdbcOperations.update(this.createSessionAttributeQuery, (ps) -> {
String attributeName = attributeNames.get(0);
ps.setString(1, attributeName);
getLobHandler().getLobCreator().setBlobAsBytes(ps, 2, serialize(session.getAttribute(attributeName)));
ps.setString(3, session.getId());
});
});
}
}
}
private void updateSessionAttributes(JdbcSession session, List<String> attributeNames) {
Assert.notEmpty(attributeNames, "attributeNames must not be null or empty");
if (attributeNames.size() > 1) {
this.jdbcOperations.batchUpdate(this.updateSessionAttributeQuery, new BatchPreparedStatementSetter() {
try (LobCreator lobCreator = this.lobHandler.getLobCreator()) {
if (attributeNames.size() > 1) {
this.jdbcOperations.batchUpdate(this.updateSessionAttributeQuery, new BatchPreparedStatementSetter() {
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
String attributeName = attributeNames.get(i);
getLobHandler().getLobCreator().setBlobAsBytes(ps, 1,
serialize(session.getAttribute(attributeName)));
@Override
public void setValues(PreparedStatement ps, int i) throws SQLException {
String attributeName = attributeNames.get(i);
lobCreator.setBlobAsBytes(ps, 1, serialize(session.getAttribute(attributeName)));
ps.setString(2, session.primaryKey);
ps.setString(3, attributeName);
}
@Override
public int getBatchSize() {
return attributeNames.size();
}
});
}
else {
this.jdbcOperations.update(this.updateSessionAttributeQuery, (ps) -> {
String attributeName = attributeNames.get(0);
lobCreator.setBlobAsBytes(ps, 1, serialize(session.getAttribute(attributeName)));
ps.setString(2, session.primaryKey);
ps.setString(3, attributeName);
}
@Override
public int getBatchSize() {
return attributeNames.size();
}
});
}
else {
this.jdbcOperations.update(this.updateSessionAttributeQuery, (ps) -> {
String attributeName = attributeNames.get(0);
getLobHandler().getLobCreator().setBlobAsBytes(ps, 1, serialize(session.getAttribute(attributeName)));
ps.setString(2, session.primaryKey);
ps.setString(3, attributeName);
});
});
}
}
}

View File

@@ -35,6 +35,8 @@ import org.springframework.jdbc.core.BatchPreparedStatementSetter;
import org.springframework.jdbc.core.JdbcOperations;
import org.springframework.jdbc.core.PreparedStatementSetter;
import org.springframework.jdbc.core.ResultSetExtractor;
import org.springframework.jdbc.support.lob.DefaultLobHandler;
import org.springframework.jdbc.support.lob.TemporaryLobCreator;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.authority.AuthorityUtils;
@@ -53,6 +55,8 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
import static org.mockito.ArgumentMatchers.startsWith;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -710,4 +714,19 @@ class JdbcIndexedSessionRepositoryTests {
verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
void saveAndFreeTemporaryLob() {
DefaultLobHandler lobHandler = mock(DefaultLobHandler.class);
TemporaryLobCreator lobCreator = mock(TemporaryLobCreator.class);
given(lobHandler.getLobCreator()).willReturn(lobCreator);
lobHandler.setCreateTemporaryLob(true);
this.repository.setLobHandler(lobHandler);
JdbcSession session = this.repository.new JdbcSession(new MapSession(), "primaryKey", false);
session.setAttribute("testName", "testValue");
this.repository.save(session);
verify(lobCreator, atLeastOnce()).close();
}
}

View File

@@ -1,23 +1,23 @@
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.11.0'
mavenBom 'com.fasterxml.jackson:jackson-bom:2.11.4'
}
dependencies {
dependency 'ch.qos.logback:logback-classic:1.2.3'
dependency 'com.maxmind.geoip2:geoip2:2.14.0'
dependency 'ch.qos.logback:logback-classic:1.2.6'
dependency 'com.maxmind.geoip2:geoip2:2.15.0'
dependency 'javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.2'
dependency 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.3'
dependency 'org.apache.taglibs:taglibs-standard-jstlel:1.2.5'
dependency 'org.seleniumhq.selenium:htmlunit-driver:2.43.1'
dependency 'org.slf4j:jcl-over-slf4j:1.7.30'
dependency 'org.slf4j:log4j-over-slf4j:1.7.30'
dependency 'org.seleniumhq.selenium:htmlunit-driver:2.44.0'
dependency 'org.slf4j:jcl-over-slf4j:1.7.31'
dependency 'org.slf4j:log4j-over-slf4j:1.7.31'
dependency 'org.webjars:bootstrap:2.3.2'
dependency 'org.webjars:html5shiv:3.7.3'
dependency 'org.webjars:jquery:1.12.4'
dependency 'org.webjars:knockout:2.3.0'
dependency 'org.webjars:sockjs-client:0.3.4'
dependency 'org.webjars:stomp-websocket:2.3.3'
dependency 'org.webjars:stomp-websocket:2.3.4'
dependency 'org.webjars:webjars-taglib:0.3'
}
}

View File

@@ -46,7 +46,7 @@ import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDr
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
class FindByUsernameTests {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Autowired
private MockMvc mockMvc;

View File

@@ -1,19 +1,19 @@
apply plugin: 'io.spring.convention.spring-sample-boot'
dependencies {
compile project(':spring-session-hazelcast')
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
compile "org.springframework.boot:spring-boot-starter-security"
compile "com.hazelcast:hazelcast-client"
compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect"
compile "org.webjars:bootstrap"
compile "org.webjars:html5shiv"
compile "org.webjars:webjars-locator-core"
compile project(':spring-session-hazelcast')
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
compile "org.springframework.boot:spring-boot-starter-security"
compile "com.hazelcast:hazelcast"
compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect"
compile "org.webjars:bootstrap"
compile "org.webjars:html5shiv"
compile "org.webjars:webjars-locator-core"
testCompile "org.springframework.boot:spring-boot-starter-test"
testCompile "org.junit.jupiter:junit-jupiter-api"
testRuntime "org.junit.jupiter:junit-jupiter-engine"
integrationTestCompile seleniumDependencies
integrationTestCompile "org.testcontainers:testcontainers"
testCompile "org.springframework.boot:spring-boot-starter-test"
testCompile "org.junit.jupiter:junit-jupiter-api"
testRuntime "org.junit.jupiter:junit-jupiter-engine"
integrationTestCompile seleniumDependencies
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2021 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.
@@ -19,32 +19,29 @@ package sample;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.openqa.selenium.WebDriver;
import org.testcontainers.containers.GenericContainer;
import sample.pages.HomePage;
import sample.pages.LoginPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.session.SessionsEndpoint;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.context.ApplicationContext;
import org.springframework.session.hazelcast.HazelcastIndexedSessionRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Ellie Bahadori
*/
@ExtendWith(SpringExtension.class)
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
class BootTests {
private static final String DOCKER_IMAGE = "hazelcast/hazelcast:latest";
@Autowired
private MockMvc mockMvc;
@@ -60,6 +57,12 @@ class BootTests {
this.driver.quit();
}
@Test // gh-1905
void contextLoads(ApplicationContext context) {
assertThat(context.getBeansOfType(HazelcastIndexedSessionRepository.class)).hasSize(1);
assertThat(context.getBeansOfType(SessionsEndpoint.class)).hasSize(1);
}
@Test
void home() {
LoginPage login = HomePage.go(this.driver);
@@ -83,16 +86,4 @@ class BootTests {
login.assertAt();
}
@TestConfiguration
static class Config {
@Bean
GenericContainer hazelcastContainer() {
GenericContainer hazelcastContainer = new GenericContainer(DOCKER_IMAGE).withExposedPorts(5701);
hazelcastContainer.start();
return hazelcastContainer;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2021 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.
@@ -34,7 +34,7 @@ import org.springframework.session.hazelcast.PrincipalNameExtractor;
public class SessionConfig {
@Bean
public Config clientConfig() {
public Config hazelcastConfig() {
Config config = new Config();
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(0);

View File

@@ -1 +1,2 @@
management.endpoints.web.exposure.include=sessions
spring.security.user.password=password

View File

@@ -1,20 +1,20 @@
apply plugin: 'io.spring.convention.spring-sample-boot'
dependencies {
compile project(':spring-session-hazelcast')
compile project(':hazelcast4')
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
compile "org.springframework.boot:spring-boot-starter-security"
compile "com.hazelcast:hazelcast:4.0.2"
compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect"
compile "org.webjars:bootstrap"
compile "org.webjars:html5shiv"
compile "org.webjars:webjars-locator-core"
compile project(':spring-session-hazelcast')
compile project(':hazelcast4')
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-thymeleaf"
compile "org.springframework.boot:spring-boot-starter-security"
compile "com.hazelcast:hazelcast:4.0.3"
compile "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect"
compile "org.webjars:bootstrap"
compile "org.webjars:html5shiv"
compile "org.webjars:webjars-locator-core"
testCompile "org.springframework.boot:spring-boot-starter-test"
testCompile "org.junit.jupiter:junit-jupiter-api"
testRuntime "org.junit.jupiter:junit-jupiter-engine"
integrationTestCompile seleniumDependencies
integrationTestCompile "org.testcontainers:testcontainers"
testCompile "org.springframework.boot:spring-boot-starter-test"
testCompile "org.junit.jupiter:junit-jupiter-api"
testRuntime "org.junit.jupiter:junit-jupiter-engine"
integrationTestCompile seleniumDependencies
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2021 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.
@@ -19,29 +19,26 @@ package sample;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.openqa.selenium.WebDriver;
import org.testcontainers.containers.GenericContainer;
import sample.pages.HomePage;
import sample.pages.LoginPage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.session.SessionsEndpoint;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.context.ApplicationContext;
import org.springframework.session.hazelcast.Hazelcast4IndexedSessionRepository;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder;
@ExtendWith(SpringExtension.class)
import static org.assertj.core.api.Assertions.assertThat;
@AutoConfigureMockMvc
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
class BootTests {
private static final String DOCKER_IMAGE = "hazelcast/hazelcast:latest";
@Autowired
private MockMvc mockMvc;
@@ -57,6 +54,12 @@ class BootTests {
this.driver.quit();
}
@Test // gh-1905
void contextLoads(ApplicationContext context) {
assertThat(context.getBeansOfType(Hazelcast4IndexedSessionRepository.class)).hasSize(1);
assertThat(context.getBeansOfType(SessionsEndpoint.class)).hasSize(1);
}
@Test
void home() {
LoginPage login = HomePage.go(this.driver);
@@ -80,16 +83,4 @@ class BootTests {
login.assertAt();
}
@TestConfiguration
static class Config {
@Bean
GenericContainer hazelcastContainer() {
GenericContainer hazelcastContainer = new GenericContainer(DOCKER_IMAGE).withExposedPorts(5701);
hazelcastContainer.start();
return hazelcastContainer;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2020 the original author or authors.
* Copyright 2014-2021 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,7 +35,7 @@ import org.springframework.session.hazelcast.HazelcastSessionSerializer;
public class SessionConfig {
@Bean
public Config clientConfig() {
public Config hazelcastConfig() {
Config config = new Config();
NetworkConfig networkConfig = config.getNetworkConfig();
networkConfig.setPort(0);

View File

@@ -1 +1,2 @@
management.endpoints.web.exposure.include=sessions
spring.security.user.password=password

View File

@@ -50,7 +50,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@AutoConfigureMockMvc
class HttpRedisJsonTest {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Autowired
private MockMvc mockMvc;

View File

@@ -39,7 +39,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest
class RedisSerializerTest {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@SpringSessionRedisOperations
private RedisTemplate<Object, Object> sessionRedisTemplate;

View File

@@ -41,7 +41,7 @@ import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDr
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
class BootTests {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Autowired
private MockMvc mockMvc;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2019 the original author or authors.
* Copyright 2014-2020 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,8 +16,14 @@
package sample.config;
import java.time.Duration;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.session.RedisSessionProperties;
import org.springframework.boot.autoconfigure.session.SessionProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
@@ -25,13 +31,22 @@ import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
import org.springframework.session.data.redis.RedisSessionRepository;
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(RedisSessionProperties.class)
@EnableSpringHttpSession
public class SessionConfig {
private final SessionProperties sessionProperties;
private final RedisSessionProperties redisSessionProperties;
private final RedisConnectionFactory redisConnectionFactory;
public SessionConfig(ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
this.redisConnectionFactory = redisConnectionFactory.getIfAvailable();
public SessionConfig(SessionProperties sessionProperties, RedisSessionProperties redisSessionProperties,
ObjectProvider<RedisConnectionFactory> redisConnectionFactory) {
this.sessionProperties = sessionProperties;
this.redisSessionProperties = redisSessionProperties;
this.redisConnectionFactory = redisConnectionFactory.getObject();
}
@Bean
@@ -45,7 +60,15 @@ public class SessionConfig {
@Bean
public RedisSessionRepository sessionRepository(RedisOperations<String, Object> sessionRedisOperations) {
return new RedisSessionRepository(sessionRedisOperations);
RedisSessionRepository sessionRepository = new RedisSessionRepository(sessionRedisOperations);
Duration timeout = this.sessionProperties.getTimeout();
if (timeout != null) {
sessionRepository.setDefaultMaxInactiveInterval(timeout);
}
sessionRepository.setKeyNamespace(this.redisSessionProperties.getNamespace());
sessionRepository.setFlushMode(this.redisSessionProperties.getFlushMode());
sessionRepository.setSaveMode(this.redisSessionProperties.getSaveMode());
return sessionRepository;
}
}

View File

@@ -45,7 +45,7 @@ import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDr
@SpringBootTest(webEnvironment = WebEnvironment.MOCK)
class BootTests {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Autowired
private MockMvc mockMvc;

View File

@@ -1,5 +1,7 @@
apply plugin: 'io.spring.convention.spring-sample-boot'
ext['spring-data-bom.version'] = '2020.0.0'
dependencies {
compile project(':spring-session-data-redis')
compile "org.springframework.boot:spring-boot-starter-webflux"

View File

@@ -47,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class AttributeTests {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@LocalServerPort
private int port;

View File

@@ -52,7 +52,7 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
class ApplicationTests {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Value("${local.server.port}")
private String port;

View File

@@ -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:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Bean
public GenericContainer redisContainer() {

View File

@@ -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:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Bean
public GenericContainer redisContainer() {

View File

@@ -53,7 +53,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@WebAppConfiguration
class RestMockMvcTests {
private static final String DOCKER_IMAGE = "redis:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Autowired
private SessionRepositoryFilter<? extends Session> sessionRepositoryFilter;

View File

@@ -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:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Bean
public GenericContainer redisContainer() {

View File

@@ -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:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Bean
public GenericContainer redisContainer() {

View File

@@ -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:5.0.6";
private static final String DOCKER_IMAGE = "redis:5.0.10";
@Bean
public GenericContainer redisContainer() {