Compare commits

...

67 Commits
main ... 2.5.6

Author SHA1 Message Date
Eleftheria Stein
2c5e5b4fe2 Release 2.5.6 2022-04-19 14:55:24 +02:00
Eleftheria Stein
a29c12f9ad Upgrade Spring Data to 2021.0.11
Closes gh-2057
2022-04-19 14:29:50 +02:00
Eleftheria Stein
0a8238be94 Upgrade test dependencies 2022-04-19 11:50:53 +02:00
Eleftheria Stein
f8d5ed0dd1 Upgrade Spring Framework to 5.3.19
Closes gh-2061
2022-04-19 11:49:25 +02:00
Eleftheria Stein
59a94ac6fc Upgrade Spring Security to 5.5.6
Closes gh-2062
2022-04-19 11:48:28 +02:00
Eleftheria Stein
74cf6262b0 Upgrade Reactor to 2020.0.18
Closes gh-2060
2022-04-19 11:47:22 +02:00
Eleftheria Stein
e5bff98619 Upgrade samples to Spring Boot 2.5.12
Closes gh-2056
2022-04-19 11:46:33 +02:00
Felix Scheinost
3eaa0b9f43 Fix bug in JDBC SaveMode.ON_GET_ATTRIBUTE 2022-04-08 17:52:35 +02:00
Eleftheria Stein
af1a5d2179 Document release process for 2.5.x
Issue gh-2036
2022-02-23 14:13:55 +01:00
Eleftheria Stein
4a3dc3febb Next development version 2022-02-22 09:21:00 +01:00
Eleftheria Stein
8ae6ca9ce1 Release 2.5.5 2022-02-22 09:20:06 +01:00
Eleftheria Stein
756d29b93a Upgrade test dependencies 2022-02-21 18:37:48 +01:00
Eleftheria Stein
0ea706a970 Upgrade Hazelcast 4 to 4.2.4
Closes gh-2022
2022-02-21 18:37:04 +01:00
Eleftheria Stein
2d8f2c6f97 Upgrade Spring Framework to 5.3.16
Closes gh-2023
2022-02-21 18:36:38 +01:00
Eleftheria Stein
ef28b6363e Upgrade Spring Data to 2021.0.9
Closes gh-2026
2022-02-21 18:36:05 +01:00
Eleftheria Stein
e8442eaf2e Upgrade Spring Security to 5.5.5
Closes gh-2024
2022-02-21 18:35:36 +01:00
Eleftheria Stein
236f5985cb Upgrade Reactor to 2020.0.16
Closes gh-2025
2022-02-21 18:34:19 +01:00
Eleftheria Stein
dbdad05a30 Upgrade samples to Spring Boot 2.5.9
Closes gh-2027
2022-02-21 18:33:47 +01:00
Eleftheria Stein
1e3c65ff9d Update to jakarta.servlet-api dependency
Closes gh-1960
2022-01-25 13:18:36 +01:00
Eleftheria Stein
10ebde5725 Update to jakarta.annotation-api dependency
Closes gh-1956
2022-01-25 12:52:47 +01:00
Ruslan Molchanov
e154197492 Fix memory leak with null principal in Redis
Closes gh-1987
2022-01-20 10:16:14 +01:00
Eleftheria Stein
e7f1d5ae44 Next development version 2021-12-21 14:03:43 +02:00
Eleftheria Stein
19db5fdf31 Release 2.5.4 2021-12-21 13:39:43 +02:00
Eleftheria Stein
8cea4152a0 Make gretty samples compatible with logback 1.2.9
Explicitly reference the logback.xml file to prevent gretty from configuring the defaults using groovy.
2021-12-21 13:30:52 +02:00
Eleftheria Stein
36b85be918 Upgrade test dependencies 2021-12-21 13:23:02 +02:00
Eleftheria Stein
e90fdaef5e Upgrade samples to Spring Boot 2.5.7
Closes gh-1986
2021-12-21 13:20:19 +02:00
Eleftheria Stein
e6e10494cb Upgrade Hazelcast 4 to 4.2.3
Closes gh-1985
2021-12-21 12:36:29 +02:00
Eleftheria Stein
f8662b433c Upgrade Spring Security to 5.5.4
Closes gh-1984
2021-12-21 12:31:44 +02:00
Eleftheria Stein
9154ec5cb0 Upgrade Spring Data to 2021.0.7
Closes gh-1983
2021-12-21 12:30:40 +02:00
Eleftheria Stein
4db0d3fac2 Upgrade Spring Framework to 5.3.14
Closes gh-1982
2021-12-21 12:24:14 +02:00
Eleftheria Stein
e8f1ebac23 Upgrade Reactor to 2020.0.14
Closes gh-1981
2021-12-21 12:23:19 +02:00
Eleftheria Stein
6f6e6c352d GitHub Actions uses spring-builds+github user
This is more clear than spring-builds user
2021-12-07 16:08:29 +01:00
Eleftheria Stein
7bb9b105e0 Update to use s01.oss.sonatype.org
Closes gh-1943
2021-12-06 15:59:36 +01:00
Eleftheria Stein
d78ac36d15 Update to spring-build-conventions 0.0.38 2021-12-06 15:58:34 +01:00
Eleftheria Stein
e4dfabdb01 Update principal index on session ID change
Closes gh-1791
2021-12-02 15:14:04 +01:00
Eleftheria Stein
f0e9fef2b2 Next development version 2021-10-19 15:28:01 +02:00
Eleftheria Stein
e80ad02120 Next development version 2021-10-19 13:10:04 +02:00
Eleftheria Stein
029e7c8158 Release 2.5.3 2021-10-19 12:51:56 +02:00
Eleftheria Stein
d489709886 Upgrade test dependencies 2021-10-19 12:50:44 +02:00
Eleftheria Stein
e31280846f Upgrade Spring Data to 2021.0.6
Closes gh-1933
2021-10-19 12:37:24 +02:00
Eleftheria Stein
6cec3098ef Upgrade Spring Framework to 5.3.11
Closes gh-1930
2021-10-19 12:35:25 +02:00
Eleftheria Stein
8084e0bab9 Upgrade Reactor to 2020.0.12
Closes gh-1931
2021-10-19 12:35:05 +02:00
Eleftheria Stein
b3b5dd4533 Upgrade Spring Security to 5.5.3
Closes gh-1932
2021-10-19 12:34:33 +02:00
Vedran Pavic
aca350a86e 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-1907
2021-09-28 09:27:21 +02:00
Eleftheria Stein
d8af71927f Increase session timeout in Hazelcast tests
It's possible that the session is expiring before the assertions can be made in the tests, causing them to fail.

Issue gh-1912
2021-09-27 17:03:55 +02:00
Vedran Pavic
d0429dc1e9 Fix Spring Boot based Hazelcast samples
This commit removes unused Hazelcast client dependencies and test support from Spring Boot based Hazelcast samples.

Closes: gh-1903
2021-09-27 16:02:07 +02:00
Andreas Kasparek
4e884cdaf2 Always set time-to-live within entry processor
Closes gh-1899
2021-09-03 10:52:01 +02:00
Eleftheria Stein
f0450fa2aa Next development version 2021-08-17 17:28:09 +02:00
Eleftheria Stein
a6cb9340a1 Release 2.5.2 2021-08-17 17:10:18 +02:00
Eleftheria Stein
cde82afa9e Upgrade test dependencies 2021-08-17 17:08:42 +02:00
Eleftheria Stein
d42caa2dbb Upgrade Hazelcast 4 to 4.2.2
Closes gh-1890
2021-08-17 16:23:10 +02:00
Eleftheria Stein
a9e9f8c46d Upgrade Spring Security to 5.5.2
Closes gh-1892
2021-08-17 16:22:32 +02:00
Eleftheria Stein
30e9dc0a17 Upgrade Spring Data to 2021.0.4
Closes gh-1891
2021-08-17 16:21:55 +02:00
Eleftheria Stein
c92808fa32 Upgrade Spring Framework to 5.3.9
Closes gh-1889
2021-08-17 16:21:15 +02:00
Eleftheria Stein
bdc3a51409 Upgrade Reactor to 2020.0.10
Closes gh-1888
2021-08-17 16:20:24 +02:00
Eleftheria Stein
e80021f334 Next development version 2021-06-22 13:20:18 +02:00
Eleftheria Stein
a739b0794c Release 2.5.1 2021-06-22 12:41:56 +02:00
Eleftheria Stein
384633f8b4 Revert "Use GPG_PRIVATE_KEY directly in build"
This reverts commit c800c7af40.
2021-06-22 12:41:00 +02:00
Eleftheria Stein
30f17f96f5 Revert "Release 2.5.1"
This reverts commit ac9077b9d6.
2021-06-22 12:40:09 +02:00
Eleftheria Stein
ac9077b9d6 Release 2.5.1 2021-06-22 11:26:33 +02:00
Eleftheria Stein
c4c7d8e233 Upgrade test dependencies 2021-06-22 11:07:31 +02:00
Eleftheria Stein
1ce7640fc5 Upgrade samples to Spring Boot 2.4.7
Closes gh-1871
2021-06-22 10:09:36 +02:00
Eleftheria Stein
a50a2fe3c9 Upgrade Spring Security to 5.5.1
Closes gh-1870
2021-06-22 09:48:36 +02:00
Eleftheria Stein
74a21dd876 Upgrade Spring Framework to 5.3.8
Closes gh-1869
2021-06-22 09:47:31 +02:00
Eleftheria Stein
c800c7af40 Use GPG_PRIVATE_KEY directly in build
Closes gh-1861
2021-05-31 16:56:03 +03:00
Eleftheria Stein
0033adf74e Update workflows for 2.5.x 2021-05-19 09:23:42 +02:00
Eleftheria Stein
0f63b0c4c8 Next development version 2021-05-19 00:39:23 +02:00
61 changed files with 569 additions and 180 deletions

View File

@@ -1,9 +1,9 @@
name: CI
name: 2.5.x CI
on:
push:
branches:
- main
- 2.5.x
schedule:
- cron: '0 10 * * *' # Once per day at 10am UTC
workflow_dispatch: # Manual trigger
@@ -32,7 +32,7 @@ jobs:
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle
echo 'systemProp.user.name=spring-builds' >> ~/.gradle/gradle.properties
echo 'systemProp.user.name=spring-builds+github' >> ~/.gradle/gradle.properties
- name: Cache Gradle packages
uses: actions/cache@v2
with:
@@ -57,7 +57,7 @@ jobs:
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle
echo 'systemProp.user.name=spring-builds' >> ~/.gradle/gradle.properties
echo 'systemProp.user.name=spring-builds+github' >> ~/.gradle/gradle.properties
- name: Deploy artifacts
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
@@ -66,13 +66,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_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
./gradlew deployArtifacts -PossrhTokenUsername="$OSSRH_TOKEN_USERNAME" -PossrhTokenPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
./gradlew finalizeDeployArtifacts -PossrhTokenUsername="$OSSRH_TOKEN_USERNAME" -PossrhTokenPassword="$OSSRH_TOKEN_PASSWORD" -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --stacktrace --no-parallel
env:
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY_NO_HEADER }}
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_TOKEN_USERNAME }}
OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_TOKEN_PASSWORD }}
OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_S01_TOKEN_USERNAME }}
OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_S01_TOKEN_PASSWORD }}
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
docs:
@@ -88,7 +88,7 @@ jobs:
- name: Setup gradle user name
run: |
mkdir -p ~/.gradle
echo 'systemProp.user.name=spring-builds' >> ~/.gradle/gradle.properties
echo 'systemProp.user.name=spring-builds+github' >> ~/.gradle/gradle.properties
- name: Deploy Docs
run: |
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"

View File

@@ -1,6 +1,9 @@
name: PR Build
name: 2.5.x PR Build
on: pull_request
on:
pull_request:
branches:
- 2.5.x
jobs:
build:

97
RELEASE.adoc Normal file
View File

@@ -0,0 +1,97 @@
== 1. Update Dependencies
Dependencies are declared in `gradle/dependency-management.gradle`.
Update Spring Framework, Spring Security and Spring Data at a minimum.
Run all the checks:
[source,bash]
----
$ ./gradlew check
----
Create separate issues for each dependency update, aside from test dependencies which can be combined into a single commit.
== 2. Check All Issues are Closed
You can manually check at https://github.com/spring-projects/spring-session/milestones
== 3. Update Release Version
Update the version number in `gradle.properties` for the release, for example `2.5.0-M1`, `2.5.0-RC1`, `2.5.5`
== 4. Build Locally
Run the build using
[source,bash]
----
$ ./gradlew check
----
== 5. Push the Release Commit
Push the commit and GitHub actions will build and deploy the artifacts.
Wait for the artifact to appear in https://repo1.maven.org/maven2/org/springframework/session/spring-session-core/
== 6. Tag the release
Tag the release and then push the tag
....
git tag 2.5.6
git push origin 2.5.6
....
== 7. Update to Next Development Version
Update `gradle.properties` version to next `+SNAPSHOT+` version and then push
== 8. Update version on project pages
Update the versions on https://spring.io/projects for Spring Session Core, Spring Session Data Redis, Spring Session JDBC, and Spring Session Hazelcast.
== 9. Update Release Notes on GitHub
Download
https://github.com/spring-io/github-changelog-generator/releases/latest[the
GitHub release notes generator]
* Generate the release notes
....
java -jar github-changelog-generator.jar \
--changelog.repository=spring-projects/spring-session \
$MILESTONE release-notes
....
Note 1: `+$MILESTONE+` is something like `+2.5.1+` or `+2.5.0-M1+`. +
Note 2: This will create a file on your filesystem
called `+release-notes+`.
* Copy the release notes to your clipboard (your mileage may vary with
the following command)
....
cat release-notes | xclip -selection clipboard
....
* Create the
https://github.com/spring-projects/spring-session/releases[release on
GitHub], associate it with the tag, and paste the generated notes.
== 10. Close / Create Milestone
* In
https://github.com/spring-projects/spring-session/milestones[GitHub
Milestones], create a new milestone for the next release version
* Move any open issues from the existing milestone you just released to
the new milestone.
* Close the milestone for the release.
== 11. Announce the release
* Announce via Slack on https://pivotal.slack.com/messages/spring-session[#spring-session], and tag any downstream Spring Session projects (e.g Spring Session for Apache Geode).
Note: Do not post on #spring-release or create a blog post. Those steps happen after the Spring Session BOM is released.

View File

@@ -4,7 +4,7 @@ buildscript {
snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild)
springBootVersion = '2.4.5'
springBootVersion = '2.5.12'
}
repositories {
@@ -22,7 +22,7 @@ buildscript {
}
dependencies {
classpath 'io.spring.gradle:spring-build-conventions:0.0.37'
classpath 'io.spring.gradle:spring-build-conventions:0.0.38'
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.5.0
version=2.5.6

View File

@@ -1,10 +1,10 @@
dependencyManagement {
imports {
mavenBom 'io.projectreactor:reactor-bom:2020.0.7'
mavenBom 'io.projectreactor:reactor-bom:2020.0.18'
mavenBom 'org.junit:junit-bom:5.7.2'
mavenBom 'org.springframework:spring-framework-bom:5.3.7'
mavenBom 'org.springframework.data:spring-data-bom:2021.0.1'
mavenBom 'org.springframework.security:spring-security-bom:5.5.0'
mavenBom 'org.springframework:spring-framework-bom:5.3.19'
mavenBom 'org.springframework.data:spring-data-bom:2021.0.11'
mavenBom 'org.springframework.security:spring-security-bom:5.5.6'
mavenBom 'org.testcontainers:testcontainers-bom:1.15.3'
}
@@ -14,23 +14,23 @@ dependencyManagement {
entry 'hazelcast-client'
}
dependency 'org.aspectj:aspectjweaver:1.9.6'
dependency 'org.aspectj:aspectjweaver:1.9.9.1'
dependency 'com.h2database:h2:1.4.200'
dependency 'com.ibm.db2:jcc:11.5.5.0'
dependency 'com.ibm.db2:jcc:11.5.7.0'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre8'
dependency 'com.oracle.database.jdbc:ojdbc8:19.10.0.0'
dependency 'com.zaxxer:HikariCP:3.4.5'
dependency 'edu.umd.cs.mtc:multithreadedtc:1.01'
dependency 'io.lettuce:lettuce-core:6.1.2.RELEASE'
dependency 'javax.annotation:javax.annotation-api:1.3.2'
dependency 'javax.servlet:javax.servlet-api:4.0.1'
dependency 'io.lettuce:lettuce-core:6.1.8.RELEASE'
dependency 'jakarta.annotation:jakarta.annotation-api:1.3.5'
dependency 'jakarta.servlet:jakarta.servlet-api:4.0.4'
dependency 'junit:junit:4.13.2'
dependency 'mysql:mysql-connector-java:8.0.25'
dependency 'mysql:mysql-connector-java:8.0.28'
dependency 'org.apache.derby:derby:10.14.2.0'
dependency 'org.assertj:assertj-core:3.19.0'
dependency 'org.hsqldb:hsqldb:2.5.1'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.7.3'
dependency 'org.hsqldb:hsqldb:2.5.2'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.7.5'
dependency 'org.mockito:mockito-core:3.10.0'
dependency 'org.postgresql:postgresql:42.2.20'
dependency 'org.postgresql:postgresql:42.2.25'
}
}

View File

@@ -6,8 +6,8 @@ dependencies {
compile "org.springframework:spring-jcl"
optional "io.projectreactor:reactor-core"
optional "javax.annotation:javax.annotation-api"
optional "javax.servlet:javax.servlet-api"
optional "jakarta.annotation:jakarta.annotation-api"
optional "jakarta.servlet:jakarta.servlet-api"
optional "org.springframework:spring-context"
optional "org.springframework:spring-jdbc"
optional "org.springframework:spring-messaging"

View File

@@ -12,7 +12,7 @@ dependencies {
optional "org.springframework:spring-web"
testCompile "io.projectreactor:reactor-test"
testCompile "javax.servlet:javax.servlet-api"
testCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.springframework:spring-web"
testCompile "org.springframework.security:spring-security-core"
testCompile "org.junit.jupiter:junit-jupiter-api"

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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
protected static class BaseConfig {

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.
@@ -473,6 +473,84 @@ class RedisIndexedSessionRepositoryITests extends AbstractRedisITests {
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
}
@Test // gh-1791
void changeSessionIdWhenSessionExpiresThenRemovesAllPrincipalIndexIds() {
RedisSession toSave = this.repository.createSession();
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
this.repository.save(toSave);
String usernameSessionKey = "RedisIndexedSessionRepositoryITests:index:" + INDEX_NAME + ":" + getSecurityName();
RedisSession findById = this.repository.findById(toSave.getId());
String originalFindById = findById.getId();
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).contains(originalFindById);
String changeSessionId = findById.changeSessionId();
findById.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
this.repository.save(findById);
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).contains(changeSessionId);
String body = "RedisIndexedSessionRepositoryITests:sessions:expires:" + changeSessionId;
String channel = "__keyevent@0__:expired";
DefaultMessage message = new DefaultMessage(channel.getBytes(StandardCharsets.UTF_8),
body.getBytes(StandardCharsets.UTF_8));
byte[] pattern = new byte[] {};
this.repository.onMessage(message, pattern);
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).isEmpty();
}
@Test
void changeSessionIdWhenPrincipalNameChangesThenNewPrincipalMapsToNewSessionId() {
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
RedisSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
this.repository.save(toSave);
RedisSession findById = this.repository.findById(toSave.getId());
String changeSessionId = findById.changeSessionId();
findById.setAttribute(INDEX_NAME, principalNameChanged);
this.repository.save(findById);
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(changeSessionId);
}
@Test // gh-1987
void changeSessionIdWhenPrincipalNameChangesFromNullThenIndexShouldNotBeCreated() {
String principalName = null;
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
RedisSession toSave = this.repository.createSession();
toSave.setAttribute(INDEX_NAME, principalName);
this.repository.save(toSave);
RedisSession findById = this.repository.findById(toSave.getId());
String changeSessionId = findById.changeSessionId();
findById.setAttribute(INDEX_NAME, principalNameChanged);
this.repository.save(findById);
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
principalName);
assertThat(findByPrincipalName).isEmpty();
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
assertThat(findByPrincipalName).hasSize(1);
assertThat(findByPrincipalName.keySet()).containsOnly(changeSessionId);
}
@Test
void changeSessionIdWhenOnlyChangeId() {
String attrName = "changeSessionId";

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.
@@ -858,6 +858,13 @@ public class RedisIndexedSessionRepository
catch (NonTransientDataAccessException ex) {
handleErrNoSuchKeyError(ex);
}
if (this.originalPrincipalName != null) {
String originalPrincipalRedisKey = getPrincipalKey(this.originalPrincipalName);
RedisIndexedSessionRepository.this.sessionRedisOperations.boundSetOps(originalPrincipalRedisKey)
.remove(this.originalSessionId);
RedisIndexedSessionRepository.this.sessionRedisOperations.boundSetOps(originalPrincipalRedisKey)
.add(sessionId);
}
}
this.originalSessionId = sessionId;
}

View File

@@ -18,7 +18,7 @@ dependencies {
testCompile 'org.assertj:assertj-core'
testCompile 'com.hazelcast:hazelcast'
testCompile 'io.lettuce:lettuce-core'
testCompile 'javax.servlet:javax.servlet-api'
testCompile 'jakarta.servlet:jakarta.servlet-api'
testCompile 'org.junit.jupiter:junit-jupiter-api'
testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine'
}

View File

@@ -31,18 +31,18 @@ artifacts {
dependencies {
compile project(':spring-session-core')
optional "com.hazelcast:hazelcast:4.2"
optional "com.hazelcast:hazelcast:4.2.4"
compile "org.springframework:spring-context"
compile "javax.annotation:javax.annotation-api"
compile "jakarta.annotation:jakarta.annotation-api"
testCompile "javax.servlet:javax.servlet-api"
testCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.springframework:spring-web"
testCompile "org.junit.jupiter:junit-jupiter-api"
testCompile "org.springframework.security:spring-security-core"
testRuntime "org.junit.jupiter:junit-jupiter-engine"
integrationTestCompile "org.testcontainers:testcontainers"
integrationTestCompile "com.hazelcast:hazelcast:4.2"
integrationTestCompile "com.hazelcast:hazelcast:4.2.4"
integrationTestCompile project(":spring-session-hazelcast")
}

View File

@@ -16,6 +16,9 @@
package org.springframework.session.hazelcast;
import java.time.Duration;
import java.time.Instant;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import org.junit.jupiter.api.Test;
@@ -198,4 +201,51 @@ abstract class AbstractHazelcast4IndexedSessionRepositoryITests {
this.repository.deleteById(sessionId);
}
@Test
void createAndUpdateSessionWhileKeepingOriginalTimeToLiveConfiguredOnRepository() {
final Duration defaultSessionTimeout = Duration.ofSeconds(1800);
final IMap<String, MapSession> hazelcastMap = this.hazelcastInstance
.getMap(Hazelcast4IndexedSessionRepository.DEFAULT_SESSION_MAP_NAME);
HazelcastSession session = this.repository.createSession();
String sessionId = session.getId();
this.repository.save(session);
assertThat(session.getMaxInactiveInterval()).isEqualTo(defaultSessionTimeout);
assertThat(hazelcastMap.getEntryView(sessionId).getTtl()).isEqualTo(defaultSessionTimeout.toMillis());
session = this.repository.findById(sessionId);
session.setLastAccessedTime(Instant.now());
this.repository.save(session);
session = this.repository.findById(sessionId);
assertThat(session.getMaxInactiveInterval()).isEqualTo(defaultSessionTimeout);
assertThat(hazelcastMap.getEntryView(sessionId).getTtl()).isEqualTo(defaultSessionTimeout.toMillis());
}
@Test
void createAndUpdateSessionWhileKeepingTimeToLiveSetOnSession() {
final Duration individualSessionTimeout = Duration.ofSeconds(23);
final IMap<String, MapSession> hazelcastMap = this.hazelcastInstance
.getMap(Hazelcast4IndexedSessionRepository.DEFAULT_SESSION_MAP_NAME);
HazelcastSession session = this.repository.createSession();
session.setMaxInactiveInterval(individualSessionTimeout);
String sessionId = session.getId();
this.repository.save(session);
assertThat(session.getMaxInactiveInterval()).isEqualTo(individualSessionTimeout);
assertThat(hazelcastMap.getEntryView(sessionId).getTtl()).isEqualTo(individualSessionTimeout.toMillis());
session = this.repository.findById(sessionId);
session.setAttribute("attribute", "value");
this.repository.save(session);
session = this.repository.findById(sessionId);
assertThat(session.getMaxInactiveInterval()).isEqualTo(individualSessionTimeout);
assertThat(hazelcastMap.getEntryView(sessionId).getTtl()).isEqualTo(individualSessionTimeout.toMillis());
}
}

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.
@@ -45,8 +45,8 @@ import org.springframework.test.context.web.WebAppConfiguration;
@WebAppConfiguration
class ClientServerHazelcast4IndexedSessionRepositoryITests extends AbstractHazelcast4IndexedSessionRepositoryITests {
private static GenericContainer container = new GenericContainer<>("hazelcast/hazelcast:4.2").withExposedPorts(5701)
.withCopyFileToContainer(MountableFile.forClasspathResource("/hazelcast-server.xml"),
private static GenericContainer container = new GenericContainer<>("hazelcast/hazelcast:4.2.2")
.withExposedPorts(5701).withCopyFileToContainer(MountableFile.forClasspathResource("/hazelcast-server.xml"),
"/opt/hazelcast/hazelcast.xml");
@BeforeAll

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.
@@ -57,7 +57,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@WebAppConfiguration
class SessionEventHazelcast4IndexedSessionRepositoryTests<S extends Session> {
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 2;
@Autowired
private SessionRepository<S> repository;
@@ -199,6 +199,29 @@ class SessionEventHazelcast4IndexedSessionRepositoryTests<S extends Session> {
assertThat(this.repository.findById(sessionToUpdate.getId())).isNull();
}
@Test // gh-1899
void updateSessionAndExpireAfterOriginalTimeToLiveTest() throws InterruptedException {
S sessionToSave = this.repository.createSession();
this.repository.save(sessionToSave);
assertThat(this.registry.receivedEvent(sessionToSave.getId())).isTrue();
assertThat(this.registry.<SessionCreatedEvent>getEvent(sessionToSave.getId()))
.isInstanceOf(SessionCreatedEvent.class);
this.registry.clear();
S sessionToUpdate = this.repository.findById(sessionToSave.getId());
sessionToUpdate.setLastAccessedTime(Instant.now());
this.repository.save(sessionToUpdate);
assertThat(this.registry.receivedEvent(sessionToUpdate.getId())).isTrue();
assertThat(this.registry.<SessionExpiredEvent>getEvent(sessionToUpdate.getId()))
.isInstanceOf(SessionExpiredEvent.class);
// Assert this after the expired event was received because it would otherwise do
// its own expiration check and explicitly delete the session from Hazelcast
// regardless of the TTL of the IMap entry.
assertThat(this.repository.findById(sessionToUpdate.getId())).isNull();
}
@Configuration
@EnableHazelcastHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS)
static class HazelcastSessionConfig {

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 https://www.hazelcast.com/schema/config/hazelcast-config-4.1.xsd">
xsi:schemaLocation="http://www.hazelcast.com/schema/config https://www.hazelcast.com/schema/config/hazelcast-config-4.2.xsd">
<network>
<join>

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,7 +54,6 @@ import org.springframework.session.events.SessionCreatedEvent;
import org.springframework.session.events.SessionDeletedEvent;
import org.springframework.session.events.SessionExpiredEvent;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
/**
* A {@link org.springframework.session.SessionRepository} implementation using Hazelcast
@@ -128,8 +127,6 @@ public class Hazelcast4IndexedSessionRepository
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
private static final boolean SUPPORTS_SET_TTL = ClassUtils.hasAtLeastOneMethodWithName(IMap.class, "setTtl");
private static final Log logger = LogFactory.getLog(Hazelcast4IndexedSessionRepository.class);
private final HazelcastInstance hazelcastInstance;
@@ -262,9 +259,6 @@ public class Hazelcast4IndexedSessionRepository
entryProcessor.setLastAccessedTime(session.getLastAccessedTime());
}
if (session.maxInactiveIntervalChanged) {
if (SUPPORTS_SET_TTL) {
updateTtl(session);
}
entryProcessor.setMaxInactiveInterval(session.getMaxInactiveInterval());
}
if (!session.delta.isEmpty()) {
@@ -275,10 +269,6 @@ public class Hazelcast4IndexedSessionRepository
session.clearChangeFlags();
}
private void updateTtl(HazelcastSession session) {
this.sessions.setTtl(session.getId(), session.getMaxInactiveInterval().getSeconds(), TimeUnit.SECONDS);
}
@Override
public HazelcastSession findById(String id) {
MapSession saved = this.sessions.get(id);
@@ -416,6 +406,7 @@ public class Hazelcast4IndexedSessionRepository
@Override
public void setMaxInactiveInterval(Duration interval) {
Assert.notNull(interval, "interval must not be null");
this.delegate.setMaxInactiveInterval(interval);
this.maxInactiveIntervalChanged = true;
flushImmediateIfNecessary();

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.
@@ -63,13 +63,8 @@ public class Hazelcast4SessionUpdateEntryProcessor implements EntryProcessor<Str
}
}
}
if (this.maxInactiveInterval != null) {
((ExtendedMapEntry<String, MapSession>) entry).setValue(value, this.maxInactiveInterval.getSeconds(),
TimeUnit.SECONDS);
}
else {
entry.setValue(value);
}
((ExtendedMapEntry<String, MapSession>) entry).setValue(value, value.getMaxInactiveInterval().getSeconds(),
TimeUnit.SECONDS);
return Boolean.TRUE;
}

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.
@@ -46,7 +46,6 @@ import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyLong;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
@@ -254,7 +253,6 @@ class Hazelcast4IndexedSessionRepositoryTests {
session.setMaxInactiveInterval(Duration.ofSeconds(1));
verify(this.sessions, times(1)).set(eq(sessionId), eq(session.getDelegate()), isA(Long.class),
eq(TimeUnit.SECONDS));
verify(this.sessions).setTtl(eq(sessionId), anyLong(), any());
verify(this.sessions, times(1)).executeOnKey(eq(sessionId), any(EntryProcessor.class));
this.repository.save(session);

View File

@@ -0,0 +1,126 @@
/*
* 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.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.session.hazelcast;
import java.time.Duration;
import java.time.Instant;
import java.util.HashMap;
import java.util.concurrent.TimeUnit;
import com.hazelcast.map.ExtendedMapEntry;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.session.MapSession;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
class Hazelcast4SessionUpdateEntryProcessorTest {
private Hazelcast4SessionUpdateEntryProcessor processor;
@BeforeEach
void setUp() {
this.processor = new Hazelcast4SessionUpdateEntryProcessor();
}
@Test
void shouldReturnFalseIfNoSessionExistsInHazelcastMapEntry() {
@SuppressWarnings("unchecked")
ExtendedMapEntry<String, MapSession> mapEntry = mock(ExtendedMapEntry.class);
Object result = this.processor.process(mapEntry);
assertThat(result).isEqualTo(Boolean.FALSE);
}
@Test
void shouldUpdateMaxInactiveIntervalOnSessionAndSetMapEntryValueWithNewTimeToLive() {
Duration newMaxInactiveInterval = Duration.ofSeconds(123L);
MapSession mapSession = new MapSession();
@SuppressWarnings("unchecked")
ExtendedMapEntry<String, MapSession> mapEntry = mock(ExtendedMapEntry.class);
given(mapEntry.getValue()).willReturn(mapSession);
this.processor.setMaxInactiveInterval(newMaxInactiveInterval);
Object result = this.processor.process(mapEntry);
assertThat(result).isEqualTo(Boolean.TRUE);
assertThat(mapSession.getMaxInactiveInterval()).isEqualTo(newMaxInactiveInterval);
verify(mapEntry).setValue(mapSession, newMaxInactiveInterval.getSeconds(), TimeUnit.SECONDS);
}
@Test
void shouldSetMapEntryValueWithOldTimeToLiveIfNoChangeToMaxInactiveIntervalIsRegistered() {
Duration maxInactiveInterval = Duration.ofSeconds(123L);
MapSession mapSession = new MapSession();
mapSession.setMaxInactiveInterval(maxInactiveInterval);
@SuppressWarnings("unchecked")
ExtendedMapEntry<String, MapSession> mapEntry = mock(ExtendedMapEntry.class);
given(mapEntry.getValue()).willReturn(mapSession);
Object result = this.processor.process(mapEntry);
assertThat(result).isEqualTo(Boolean.TRUE);
assertThat(mapSession.getMaxInactiveInterval()).isEqualTo(maxInactiveInterval);
verify(mapEntry).setValue(mapSession, maxInactiveInterval.getSeconds(), TimeUnit.SECONDS);
}
@Test
void shouldUpdateLastAccessTimeOnSessionAndSetMapEntryValueWithOldTimeToLive() {
Instant lastAccessTime = Instant.ofEpochSecond(1234L);
MapSession mapSession = new MapSession();
@SuppressWarnings("unchecked")
ExtendedMapEntry<String, MapSession> mapEntry = mock(ExtendedMapEntry.class);
given(mapEntry.getValue()).willReturn(mapSession);
this.processor.setLastAccessedTime(lastAccessTime);
Object result = this.processor.process(mapEntry);
assertThat(result).isEqualTo(Boolean.TRUE);
assertThat(mapSession.getLastAccessedTime()).isEqualTo(lastAccessTime);
verify(mapEntry).setValue(mapSession, mapSession.getMaxInactiveInterval().getSeconds(), TimeUnit.SECONDS);
}
@Test
void shouldUpdateSessionAttributesFromDeltaAndSetMapEntryValueWithOldTimeToLive() {
MapSession mapSession = new MapSession();
mapSession.setAttribute("changed", "oldValue");
mapSession.setAttribute("removed", "existingValue");
@SuppressWarnings("unchecked")
ExtendedMapEntry<String, MapSession> mapEntry = mock(ExtendedMapEntry.class);
given(mapEntry.getValue()).willReturn(mapSession);
HashMap<String, Object> delta = new HashMap<>();
delta.put("added", "addedValue");
delta.put("changed", "newValue");
delta.put("removed", null);
this.processor.setDelta(delta);
Object result = this.processor.process(mapEntry);
assertThat(result).isEqualTo(Boolean.TRUE);
assertThat((String) mapSession.getAttribute("added")).isEqualTo("addedValue");
assertThat((String) mapSession.getAttribute("changed")).isEqualTo("newValue");
assertThat((String) mapSession.getAttribute("removed")).isNull();
verify(mapEntry).setValue(mapSession, mapSession.getMaxInactiveInterval().getSeconds(), TimeUnit.SECONDS);
}
}

View File

@@ -7,13 +7,13 @@ configurations {
dependencies {
compile project(':spring-session-core')
compile "com.hazelcast:hazelcast"
compile "javax.annotation:javax.annotation-api"
compile "jakarta.annotation:jakarta.annotation-api"
compile "org.springframework:spring-context"
hazelcast4(project(path: ":hazelcast4", configuration: 'classesOnlyElements'))
compileOnly(project(":hazelcast4"))
testCompile "javax.servlet:javax.servlet-api"
testCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.springframework:spring-web"
testCompile "org.springframework.security:spring-security-core"
testCompile "org.junit.jupiter:junit-jupiter-api"

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,7 +58,7 @@ import static org.assertj.core.api.Assertions.assertThat;
@WebAppConfiguration
class SessionEventHazelcastIndexedSessionRepositoryTests<S extends Session> {
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1;
private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 2;
@Autowired
private SessionRepository<S> repository;

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

@@ -7,7 +7,7 @@ dependencies {
compile "org.springframework:spring-context"
compile "org.springframework:spring-jdbc"
testCompile "javax.servlet:javax.servlet-api"
testCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.springframework:spring-web"
testCompile "org.springframework.security:spring-security-core"
testCompile "org.junit.jupiter:junit-jupiter-api"

View File

@@ -42,11 +42,11 @@ final class DatabaseContainers {
}
static MariaDBContainer<?> mariaDb() {
return new MariaDBContainer<>("mariadb:10.6.0");
return new MariaDBContainer<>("mariadb:10.6.4");
}
static MySQLContainer<?> mySql() {
return new MySQLContainer<>("mysql:8.0.25");
return new MySQLContainer<>("mysql:8.0.28");
}
static OracleContainer oracle() {

View File

@@ -728,7 +728,8 @@ public class JdbcIndexedSessionRepository
T attributeValue = supplier.get();
if (attributeValue != null
&& JdbcIndexedSessionRepository.this.saveMode.equals(SaveMode.ON_GET_ATTRIBUTE)) {
this.delta.put(attributeName, DeltaValue.UPDATED);
this.delta.merge(attributeName, DeltaValue.UPDATED, (oldDeltaValue,
deltaValue) -> (oldDeltaValue == DeltaValue.ADDED) ? oldDeltaValue : deltaValue);
}
return attributeValue;
}

View File

@@ -655,6 +655,20 @@ class JdbcIndexedSessionRepositoryTests {
verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
void saveWithSaveModeOnGetAttributeAndNewAttributeSetAndGet() {
this.repository.setSaveMode(SaveMode.ON_GET_ATTRIBUTE);
MapSession delegate = new MapSession();
delegate.setAttribute("attribute1", (Supplier<String>) () -> "value1");
JdbcSession session = this.repository.new JdbcSession(delegate, UUID.randomUUID().toString(), false);
session.setAttribute("attribute2", "value2");
session.getAttribute("attribute2");
this.repository.save(session);
verify(this.jdbcOperations, times(1)).update(startsWith("INSERT INTO SPRING_SESSION_ATTRIBUTES ("),
isA(PreparedStatementSetter.class));
verifyNoMoreInteractions(this.jdbcOperations);
}
@Test
void saveWithSaveModeAlways() {
this.repository.setSaveMode(SaveMode.ALWAYS);

View File

@@ -1,17 +1,17 @@
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.12.3'
mavenBom 'com.fasterxml.jackson:jackson-bom:2.12.6.20220326'
}
dependencies {
dependency 'ch.qos.logback:logback-classic:1.2.3'
dependency 'ch.qos.logback:logback-classic:1.2.11'
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.49.1'
dependency 'org.slf4j:jcl-over-slf4j:1.7.30'
dependency 'org.slf4j:log4j-over-slf4j:1.7.30'
dependency 'org.slf4j:jcl-over-slf4j:1.7.36'
dependency 'org.slf4j:log4j-over-slf4j:1.7.36'
dependency 'org.webjars:bootstrap:2.3.2'
dependency 'org.webjars:html5shiv:3.7.3-1'
dependency 'org.webjars:jquery:3.6.0'

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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@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.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.2.4"
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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@Autowired
private MockMvc mockMvc;

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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@Autowired
private MockMvc mockMvc;

View File

@@ -45,7 +45,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.9";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@LocalServerPort
private int port;

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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@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.10";
private static final String DOCKER_IMAGE = "redis:5.0.14";
@Value("${local.server.port}")
private String port;

View File

@@ -1,2 +1,3 @@
#server.servlet.session.timeout=1m
spring.h2.console.enabled=true
spring.jpa.defer-datasource-initialization=true

View File

@@ -10,7 +10,7 @@ dependencies {
compile slf4jDependencies
compile "org.testcontainers:testcontainers"
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.assertj:assertj-core"
testCompile "org.junit.jupiter:junit-jupiter-api"
@@ -21,4 +21,5 @@ dependencies {
gretty {
jvmArgs = ['-Dspring.profiles.active=embedded-redis']
logbackConfigFile = "src/main/resources/logback.xml"
}

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

View File

@@ -12,7 +12,7 @@ dependencies {
compile jstlDependencies
compile slf4jDependencies
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
providedCompile "javax.servlet.jsp:javax.servlet.jsp-api"
testCompile "org.assertj:assertj-core"
@@ -21,3 +21,7 @@ dependencies {
integrationTestCompile seleniumDependencies
}
gretty {
logbackConfigFile = "src/main/resources/logback.xml"
}

View File

@@ -9,7 +9,7 @@ dependencies {
compile jstlDependencies
compile slf4jDependencies
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.assertj:assertj-core"
testCompile "org.junit.jupiter:junit-jupiter-api"
@@ -17,3 +17,7 @@ dependencies {
integrationTestCompile seleniumDependencies
}
gretty {
logbackConfigFile = "src/main/resources/logback.xml"
}

View File

@@ -10,7 +10,7 @@ dependencies {
compile slf4jDependencies
compile "org.testcontainers:testcontainers"
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.assertj:assertj-core"
testCompile "org.junit.jupiter:junit-jupiter-api"
@@ -21,4 +21,5 @@ dependencies {
gretty {
jvmArgs = ['-Dspring.profiles.active=embedded-redis']
logbackConfigFile = "src/main/resources/logback.xml"
}

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

View File

@@ -11,7 +11,7 @@ dependencies {
compile slf4jDependencies
compile "org.testcontainers:testcontainers"
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.springframework.security:spring-security-test"
testCompile "org.assertj:assertj-core"
@@ -23,4 +23,5 @@ dependencies {
gretty {
jvmArgs = ['-Dspring.profiles.active=embedded-redis']
servletContainer = 'tomcat9'
logbackConfigFile = "src/main/resources/logback.xml"
}

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

View File

@@ -12,7 +12,7 @@ dependencies {
compile slf4jDependencies
compile "org.testcontainers:testcontainers"
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
providedCompile "javax.servlet.jsp:javax.servlet.jsp-api"
testCompile "org.assertj:assertj-core"
@@ -25,4 +25,5 @@ dependencies {
gretty {
jvmArgs = ['-Dspring.profiles.active=embedded-redis']
logbackConfigFile = "src/main/resources/logback.xml"
}

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

View File

@@ -8,7 +8,7 @@ dependencies {
compile jstlDependencies
compile slf4jDependencies
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.assertj:assertj-core"
testCompile "org.junit.jupiter:junit-jupiter-api"
@@ -16,3 +16,7 @@ dependencies {
integrationTestCompile seleniumDependencies
}
gretty {
logbackConfigFile = "src/main/resources/logback.xml"
}

View File

@@ -9,7 +9,7 @@ dependencies {
compile jstlDependencies
compile slf4jDependencies
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.assertj:assertj-core"
testCompile "org.junit.jupiter:junit-jupiter-api"
@@ -17,3 +17,7 @@ dependencies {
integrationTestCompile seleniumDependencies
}
gretty {
logbackConfigFile = "src/main/resources/logback.xml"
}

View File

@@ -10,7 +10,7 @@ dependencies {
compile slf4jDependencies
compile "org.testcontainers:testcontainers"
providedCompile "javax.servlet:javax.servlet-api"
providedCompile "jakarta.servlet:jakarta.servlet-api"
testCompile "org.assertj:assertj-core"
testCompile "org.junit.jupiter:junit-jupiter-api"
@@ -21,4 +21,5 @@ dependencies {
gretty {
jvmArgs = ['-Dspring.profiles.active=embedded-redis']
logbackConfigFile = "src/main/resources/logback.xml"
}

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