Compare commits

...

77 Commits

Author SHA1 Message Date
Eleftheria Stein
5d521aa9bc Add End-of-Life Notice 2020-11-18 13:03:12 +01:00
Eleftheria Stein
e14c840354 Remove from CI 2020-11-18 12:59:58 +01:00
Eleftheria Stein
f36713d0ee Next development version 2020-09-16 12:50:09 +02:00
Eleftheria Stein
12721d83ad Release 2.1.13.RELEASE 2020-09-16 11:43:16 +02:00
Eleftheria Stein
92c7302103 Upgrade Spring Data to Lovelace-SR20
Closes gh-1700
2020-09-16 11:16:56 +02:00
Eleftheria Stein
1adb9bb481 Upgrade test dependencies 2020-09-15 15:32:42 +02:00
Eleftheria Stein
8faef3613b Upgrade Spring Framework to 5.1.18.RELEASE
Closes gh-1697
2020-09-15 15:32:10 +02:00
Eleftheria Stein
65702d159e Upgrade Spring Security to 5.1.12.RELEASE
Closes gh-1696
2020-09-15 15:21:34 +02:00
Eleftheria Stein
48f061450c Upgrade Reactor to Californium-SR21
Closes gh-1695
2020-09-15 15:19:44 +02:00
Eleftheria Stein
a77196a851 Upgrade samples to Spring Boot 2.1.16.RELEASE
Closes gh-1694
2020-09-15 15:19:23 +02:00
Eleftheria Stein
4d18ed1826 Next development version 2020-05-13 15:23:01 -04:00
Eleftheria Stein
b20dd33af7 Release 2.1.12.RELEASE 2020-05-13 14:55:31 -04:00
Eleftheria Stein
ad51021e22 Upgrade test dependencies 2020-05-13 11:03:35 -04:00
Eleftheria Stein
41a84efd21 Upgrade samples to Spring Boot 2.1.14
Resolves gh-1639
2020-05-13 11:02:58 -04:00
Eleftheria Stein
6cb1764066 Upgrade Spring Security to 5.1.10.RELEASE
Resolves gh-1638
2020-05-13 10:20:59 -04:00
Eleftheria Stein
07f16ffc6a Upgrade Spring Data to Lovelace-SR17
Resolves gh-1637
2020-05-13 10:19:35 -04:00
Eleftheria Stein
54b428dbeb Upgrade Spring Framework to 5.1.15.RELEASE
Resolves gh-1636
2020-05-13 10:18:11 -04:00
Eleftheria Stein
e789fcc628 Upgrade Reactor to Californium-SR18
Resolves gh-1635
2020-05-13 10:16:20 -04:00
Eleftheria Stein
15d22a9dd4 Next development version 2020-03-04 15:16:21 -05:00
Eleftheria Stein
40cb8de232 Release 2.1.11.RELEASE 2020-03-04 14:18:59 -05:00
Eleftheria Stein
b394f56731 Revert "Upgrade Hazelcast to 3.11.7"
This reverts commit e7fd59ccf9.
2020-03-04 12:44:05 -05:00
Eleftheria Stein
e7fd59ccf9 Upgrade Hazelcast to 3.11.7
Resolves: #1601
2020-03-04 11:51:30 -05:00
Eleftheria Stein
6e5352d48f Upgrade samples to Spring Boot 2.1.13
Resolves #1600
2020-03-04 11:49:37 -05:00
Eleftheria Stein
2507c86cba Upgrade Spring Security to 5.1.8.RELEASE
Resolves $1599
2020-03-04 11:47:25 -05:00
Eleftheria Stein
01f7ff9a51 Upgrade Spring Data to Lovelace-SR16
Resolves #1598
2020-03-04 11:16:33 -05:00
Eleftheria Stein
1ce95f8591 Upgrade Reactor to Californium-SR16
Resolves #1597
2020-03-04 11:14:41 -05:00
Eleftheria Stein
a9d003af4d Upgrade Spring Framework to 5.1.14.RELEASE
Resolves #1532
2020-03-04 11:13:27 -05:00
Eleftheria Stein
797b0a62a8 Next development version 2020-01-29 09:29:18 +01:00
Eleftheria Stein
943abb8eca Release 2.1.10.RELEASE 2020-01-28 12:34:06 +01:00
Eleftheria Stein
9f78688ffa Upgrade Spring Security to 5.1.7.RELEASE
Resolves: #1572
2020-01-28 12:14:14 +01:00
Eleftheria Stein
c391adfea1 Upgrade Spring Data to Lovelace-SR14
Resolves: #1571
2020-01-28 12:13:23 +01:00
Eleftheria Stein
9befe44769 Upgrade Reactor to Californium-SR14
Resolves: #1570
2020-01-28 12:11:56 +01:00
Eleftheria Stein
6aa85236e0 Update note in custom-cookie index page
Resolves: gh-1559
2020-01-13 12:52:43 +01:00
Vedran Pavic
5ebe699d7c Polish DefaultCookieSerializer
See: #1514
2019-10-09 21:06:45 +02:00
Vedran Pavic
f6a670d78e Update Travis CI config 2019-10-08 12:50:52 +02:00
Vedran Pavic
c63761317d Upgrade samples to Spring Boot 2.1.9.RELEASE
Resolves: #1533
2019-10-08 09:37:57 +02:00
Vedran Pavic
f0aed6b8b8 Ensure session cookie's expires directive uses GMT format
Resolves: #1514
2019-10-07 22:51:10 +02:00
Vedran Pavic
4a3f0d5f34 Improve Hazelcast client-server topology integration tests
Resolves: #1527
2019-10-07 22:35:24 +02:00
Rob Winch
5d88b6bf28 Next development version 2019-09-30 22:32:32 -05:00
Rob Winch
b7857db5bb Release 2.1.9.RELEASE 2019-09-30 22:31:35 -05:00
Vedran Pavic
8e97ac9acd Update integration tests 2019-09-30 22:24:26 +02:00
Vedran Pavic
ca943b6717 Upgrade test dependencies 2019-09-30 22:07:08 +02:00
Vedran Pavic
08c3056fb5 Upgrade Spring Data to Lovelace-SR11
Resolves: #1518
2019-09-30 13:23:12 +02:00
Vedran Pavic
ca41542113 Upgrade Spring Framework to 5.1.10.RELEASE
Resolves: #1491
2019-09-29 11:47:55 +02:00
Vedran Pavic
2e4f12e1a7 Upgrade Reactor to Californium-SR12
Resolves: #1500
2019-09-24 21:06:00 +02:00
Vedran Pavic
d582343a7e Upgrade samples to Spring Boot 2.1.8.RELEASE
Resolves: #1492
2019-09-24 21:05:54 +02:00
Vedran Pavic
2505270f5f Upgrade Reactor to Californium-SR11
Resolves: #1500
2019-09-03 22:10:11 +02:00
Vedran Pavic
02e182ab4a Upgrade samples to Spring Boot 2.1.7.RELEASE
Resolves: #1492
2019-08-22 22:49:57 +02:00
Vedran Pavic
8f13a7b356 Fix test visibility
See: #1489
2019-08-21 18:56:38 +02:00
Josh Cummings
51252a55e6 Add OnCommittedResponseWrapper.setContentLengthLong
Add setContentLengthLong tracking to OnCommittedResponseWrapper in
order to detect commits on servlets that use setContentLengthLong to
announce the entity size they are about to write (as used in the
Apache Tomcat's DefaultServlet).

Fixes gh-1489
2019-08-21 18:53:08 +02:00
Vedran Pavic
4487b07bb1 Next development version 2019-08-05 17:07:18 +02:00
Vedran Pavic
84479a0ba0 Release 2.1.8.RELEASE 2019-08-05 17:04:17 +02:00
Vedran Pavic
643f9cfd1a Update integration tests 2019-08-05 13:54:54 +02:00
Vedran Pavic
95e6d710ba Upgrade test dependencies 2019-08-05 13:54:29 +02:00
Vedran Pavic
0cf723c6aa Upgrade Spring Data to Lovelace-SR10
Resolves: #1473
2019-08-05 13:53:48 +02:00
Vedran Pavic
66cc442b5f Update integration tests 2019-08-03 09:27:46 +02:00
Vedran Pavic
23d8c18b22 Upgrade test dependencies 2019-08-03 09:26:52 +02:00
Vedran Pavic
28d1d4fd00 Upgrade Spring Framework to 5.1.9.RELEASE
Resolves: #1464
2019-08-03 09:25:15 +02:00
Vedran Pavic
e82a856d00 Upgrade Reactor to Californium-SR10
Resolves: #1472
2019-08-03 09:24:25 +02:00
Vedran Pavic
e40e55d1e9 Filtering for nested ERROR dispatch
Resolves: #1470
See: spring-projects/spring-framework#23196
2019-07-19 21:06:30 +02:00
Vedran Pavic
a289938c7c Upgrade samples to Spring Boot 2.1.6.RELEASE
Resolves: #1463
2019-06-20 11:43:05 +02:00
Rob Winch
63927aa4da Next Development Version 2019-06-14 16:52:21 -05:00
Rob Winch
88071796a2 Release 2.1.7.RELEASE 2019-06-14 16:49:34 -05:00
Vedran Pavic
76bc9563bb Upgrade Spring Data to Lovelace-SR9
Resolves: #1443
2019-06-14 15:42:41 +02:00
Vedran Pavic
819b341a9f Update integration tests 2019-06-13 18:43:30 +02:00
Vedran Pavic
3b0be07c8e Upgrade test dependencies 2019-06-13 18:43:17 +02:00
Vedran Pavic
6761f2cc68 Upgrade Spring Framework to 5.1.8.RELEASE
Resolves: #1442
2019-06-13 18:42:59 +02:00
Vedran Pavic
c8f266cea2 Upgrade Reactor to Californium-SR9
Resolves: #1446
2019-06-11 11:26:40 +02:00
Vedran Pavic
7d71aa5d00 Separate "filtered" attribute for ERROR dispatch
Resolves: #1451
See: spring-projects/spring-framework#22989
2019-06-11 08:34:04 +02:00
Vedran Pavic
bee9c7c2e2 Polish build
See: spring-projects/spring-security#6200
2019-06-11 08:33:39 +02:00
Vedran Pavic
8788165966 Upgrade samples to Spring Boot 2.1.5.RELEASE
Resolves: #1444
2019-06-03 07:47:28 +02:00
Vedran Pavic
aadc806447 Update integration tests 2019-06-02 19:23:19 +02:00
Vedran Pavic
0fb942f795 Upgrade test dependencies 2019-06-02 19:23:07 +02:00
Vedran Pavic
49ebaa5cb7 Save reactive Redis session on subscribe
This commit ensures ReactiveRedisOperationsSessionRepository#save does work only after subscribe. Without this, multiple invocations of #save over the course of same request can lead to race condition situations.

Resolves: #1440
2019-06-02 19:21:49 +02:00
Vedran Pavic
a48edd5e71 Update Jenkinsfile to use explicit JAVA_HOME 2019-05-27 09:44:33 +02:00
Rob Winch
17ddfc0fa8 Redis save uses then
We need to ensure that the session id is changed before we save the
changes. Otherwise the rename of the session id will override the
changes we just made.

Fixes: gh-1428
2019-05-16 15:49:24 -05:00
Rob Winch
f2f9562a01 Next Development Version 2019-05-13 14:44:42 -05:00
34 changed files with 285 additions and 303 deletions

View File

@@ -1,20 +1,16 @@
language: java
sudo: required
services: docker
jdk: oraclejdk8
language: java
jdk:
- openjdk8
- openjdk11
services:
- docker
before_cache:
- rm -f $HOME/.gradle/caches/modules-2/modules-2.lock
- rm -fr $HOME/.gradle/caches/*/plugin-resolution/
cache:
directories:
- $HOME/.gradle/caches/
- $HOME/.gradle/wrapper/
install: true
script: ./gradlew clean build --refresh-dependencies --no-daemon
script: ./gradlew clean check --no-daemon --refresh-dependencies --stacktrace

149
Jenkinsfile vendored
View File

@@ -1,149 +0,0 @@
properties([
buildDiscarder(logRotator(numToKeepStr: '10')),
pipelineTriggers([
cron('@daily')
]),
])
def SUCCESS = hudson.model.Result.SUCCESS.toString()
currentBuild.result = SUCCESS
try {
parallel check: {
stage('Check') {
timeout(time: 45, unit: 'MINUTES') {
node('ubuntu1804') {
checkout scm
try {
sh './gradlew clean check --no-daemon --refresh-dependencies'
}
catch (e) {
currentBuild.result = 'FAILED: check'
throw e
}
finally {
junit '**/build/test-results/*/*.xml'
}
}
}
}
},
jdk9: {
stage('JDK 9') {
timeout(time: 45, unit: 'MINUTES') {
node {
checkout scm
try {
withEnv(["JAVA_HOME=${tool 'jdk9'}"]) {
sh './gradlew clean test --no-daemon --refresh-dependencies'
}
}
catch (e) {
currentBuild.result = 'FAILED: jdk9'
throw e
}
}
}
}
},
jdk10: {
stage('JDK 10') {
timeout(time: 45, unit: 'MINUTES') {
node {
checkout scm
try {
withEnv(["JAVA_HOME=${tool 'jdk10'}"]) {
sh './gradlew clean test --no-daemon --refresh-dependencies'
}
}
catch (e) {
currentBuild.result = 'FAILED: jdk10'
throw e
}
}
}
}
},
jdk11: {
stage('JDK 11') {
timeout(time: 45, unit: 'MINUTES') {
node('ubuntu1804') {
checkout scm
try {
withEnv(["JAVA_HOME=${tool 'jdk11'}"]) {
sh './gradlew clean test integrationTest --no-daemon --refresh-dependencies'
}
}
catch (e) {
currentBuild.result = 'FAILED: jdk11'
throw e
}
}
}
}
}
if (currentBuild.result == 'SUCCESS') {
parallel artifacts: {
stage('Deploy Artifacts') {
node {
checkout scm
try {
withCredentials([file(credentialsId: 'spring-signing-secring.gpg', variable: 'SIGNING_KEYRING_FILE')]) {
withCredentials([string(credentialsId: 'spring-gpg-passphrase', variable: 'SIGNING_PASSWORD')]) {
withCredentials([usernamePassword(credentialsId: 'oss-token', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USERNAME')]) {
withCredentials([usernamePassword(credentialsId: '02bd1690-b54f-4c9f-819d-a77cb7a9822c', usernameVariable: 'ARTIFACTORY_USERNAME', passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
sh './gradlew deployArtifacts finalizeDeployArtifacts --stacktrace --no-daemon --refresh-dependencies -Psigning.secretKeyRingFile=$SIGNING_KEYRING_FILE -Psigning.keyId=$SPRING_SIGNING_KEYID -Psigning.password=$SIGNING_PASSWORD -PossrhUsername=$OSSRH_USERNAME -PossrhPassword=$OSSRH_PASSWORD -PartifactoryUsername=$ARTIFACTORY_USERNAME -PartifactoryPassword=$ARTIFACTORY_PASSWORD'
}
}
}
}
}
catch (e) {
currentBuild.result = 'FAILED: artifacts'
throw e
}
}
}
},
docs: {
stage('Deploy Docs') {
node {
checkout scm
try {
withCredentials([file(credentialsId: 'docs.spring.io-jenkins_private_ssh_key', variable: 'DEPLOY_SSH_KEY')]) {
sh './gradlew deployDocs --stacktrace --no-daemon --refresh-dependencies -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME'
}
}
catch (e) {
currentBuild.result = 'FAILED: docs'
throw e
}
}
}
}
}
}
finally {
def buildStatus = currentBuild.result
def buildNotSuccess = !SUCCESS.equals(buildStatus)
def lastBuildNotSuccess = !SUCCESS.equals(currentBuild.previousBuild?.result)
if (buildNotSuccess || lastBuildNotSuccess) {
stage('Notify') {
node {
final def RECIPIENTS = [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']]
def subject = "${buildStatus}: Build ${env.JOB_NAME} ${env.BUILD_NUMBER} status is now ${buildStatus}"
def details = "The build status changed to ${buildStatus}. For details see ${env.BUILD_URL}"
emailext(
subject: subject,
body: details,
recipientProviders: RECIPIENTS,
to: "$SPRING_SESSION_TEAM_EMAILS"
)
}
}
}
}

View File

@@ -1,3 +1,9 @@
[NOTE]
======
This branch of Spring Session has reached its https://github.com/spring-projects/spring-boot/wiki/Supported-Versions[End of Life], meaning that there are no further maintenance releases or security patches planned.
Please migrate to a supported branch as soon as possible.
======
= Spring Session
image:https://travis-ci.org/spring-projects/spring-session.svg?branch=master["Build Status", link="https://travis-ci.org/spring-projects/spring-session"] image:https://badges.gitter.im/spring-projects/spring-session.svg[link="https://gitter.im/spring-projects/spring-session?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge"]

View File

@@ -4,7 +4,7 @@ buildscript {
snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild)
springBootVersion = '2.1.4.RELEASE'
springBootVersion = '2.1.16.RELEASE'
}
repositories {
@@ -23,16 +23,8 @@ apply plugin: 'io.spring.convention.root'
group = 'org.springframework.session'
description = 'Spring Session'
gradle.taskGraph.whenReady { graph ->
def jacocoEnabled = graph.allTasks.any { it instanceof JacocoReport }
subprojects {
plugins.withType(JavaPlugin) {
sourceCompatibility = 1.8
}
plugins.withType(JacocoPlugin) {
tasks.withType(Test) {
jacoco.enabled = jacocoEnabled
}
}
subprojects {
plugins.withType(JavaPlugin) {
sourceCompatibility = JavaVersion.VERSION_1_8
}
}

View File

@@ -1 +1 @@
version=2.1.6.RELEASE
version=2.1.14.BUILD-SNAPSHOT

View File

@@ -1,11 +1,10 @@
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.9.6'
mavenBom 'io.projectreactor:reactor-bom:Californium-SR8'
mavenBom 'org.springframework:spring-framework-bom:5.1.7.RELEASE'
mavenBom 'org.springframework.data:spring-data-releasetrain:Lovelace-SR8'
mavenBom 'org.springframework.security:spring-security-bom:5.1.5.RELEASE'
mavenBom 'org.testcontainers:testcontainers-bom:1.11.2'
mavenBom 'io.projectreactor:reactor-bom:Californium-SR21'
mavenBom 'org.springframework:spring-framework-bom:5.1.18.RELEASE'
mavenBom 'org.springframework.data:spring-data-releasetrain:Lovelace-SR20'
mavenBom 'org.springframework.security:spring-security-bom:5.1.12.RELEASE'
mavenBom 'org.testcontainers:testcontainers-bom:1.12.5'
}
dependencies {
@@ -14,20 +13,20 @@ dependencyManagement {
entry 'hazelcast-client'
}
dependency 'com.h2database:h2:1.4.199'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.2.2.jre8'
dependency 'com.zaxxer:HikariCP:3.3.1'
dependency 'com.h2database:h2:1.4.200'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.4.1.jre8'
dependency 'com.zaxxer:HikariCP:3.4.5'
dependency 'edu.umd.cs.mtc:multithreadedtc:1.01'
dependency 'io.lettuce:lettuce-core:5.1.6.RELEASE'
dependency 'io.lettuce:lettuce-core:5.2.0.RELEASE'
dependency 'javax.annotation:javax.annotation-api:1.3.2'
dependency 'javax.servlet:javax.servlet-api:4.0.1'
dependency 'junit:junit:4.12'
dependency 'mysql:mysql-connector-java:8.0.16'
dependency 'mysql:mysql-connector-java:8.0.21'
dependency 'org.apache.derby:derby:10.14.2.0'
dependency 'org.assertj:assertj-core:3.12.2'
dependency 'org.hsqldb:hsqldb:2.4.1'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.4.1'
dependency 'org.mockito:mockito-core:2.27.0'
dependency 'org.postgresql:postgresql:42.2.5'
dependency 'org.assertj:assertj-core:3.13.2'
dependency 'org.hsqldb:hsqldb:2.5.1'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.4.4'
dependency 'org.mockito:mockito-core:3.0.0'
dependency 'org.postgresql:postgresql:42.2.16'
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,19 +1,23 @@
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.10.5'
}
dependencies {
dependency 'ch.qos.logback:logback-classic:1.2.3'
dependency 'com.maxmind.geoip2:geoip2:2.3.1'
dependency 'javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1'
dependency 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b02'
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.32.0'
dependency 'org.slf4j:jcl-over-slf4j:1.7.25'
dependency 'org.slf4j:log4j-over-slf4j:1.7.25'
dependency 'org.seleniumhq.selenium:htmlunit-driver:2.33.0'
dependency 'org.slf4j:jcl-over-slf4j:1.7.30'
dependency 'org.slf4j:log4j-over-slf4j:1.7.30'
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.0'
dependency 'org.webjars:stomp-websocket:2.3.3'
dependency 'org.webjars:webjars-taglib:0.3'
}
}

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

View File

@@ -15,7 +15,7 @@
<body>
<div class="container">
<h1>Description</h1>
<p>This application demonstrates how to use a Redis instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.</p>
<p>This application demonstrates how to customize the session cookie. Notice that the name of the cookie is JSESSIONID.</p>
<h1>Try it</h1>

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

View File

@@ -54,7 +54,7 @@ import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.
@WebAppConfiguration
public class RestMockMvcTests {
private static final String DOCKER_IMAGE = "redis:5.0.4";
private static final String DOCKER_IMAGE = "redis:5.0.6";
@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.4";
private static final String DOCKER_IMAGE = "redis:5.0.6";
@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.4";
private static final String DOCKER_IMAGE = "redis:5.0.6";
@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.4";
private static final String DOCKER_IMAGE = "redis:5.0.6";
@Bean
public GenericContainer redisContainer() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,10 @@
package org.springframework.session.web.http;
import java.time.Clock;
import java.time.Instant;
import java.time.OffsetDateTime;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Base64;
@@ -62,6 +63,8 @@ public class DefaultCookieSerializer implements CookieSerializer {
domainValid.set('-');
}
private Clock clock = Clock.systemUTC();
private String cookieName = "SESSION";
private Boolean useSecureCookie;
@@ -135,9 +138,9 @@ public class DefaultCookieSerializer implements CookieSerializer {
int maxAge = getMaxAge(cookieValue);
if (maxAge > -1) {
sb.append("; Max-Age=").append(cookieValue.getCookieMaxAge());
OffsetDateTime expires = (maxAge != 0)
? OffsetDateTime.now().plusSeconds(maxAge)
: Instant.EPOCH.atOffset(ZoneOffset.UTC);
ZonedDateTime expires = (maxAge != 0)
? ZonedDateTime.now(this.clock).plusSeconds(maxAge)
: Instant.EPOCH.atZone(ZoneOffset.UTC);
sb.append("; Expires=")
.append(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME));
}
@@ -267,6 +270,10 @@ public class DefaultCookieSerializer implements CookieSerializer {
}
}
void setClock(Clock clock) {
this.clock = clock.withZone(ZoneOffset.UTC);
}
/**
* Sets if a Cookie marked as secure should be used. The default is to use the value
* of {@link HttpServletRequest#isSecure()}.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,6 +68,12 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
super.addHeader(name, value);
}
@Override
public void setContentLengthLong(long len) {
setContentLength(len);
super.setContentLengthLong(len);
}
@Override
public void setContentLength(int len) {
setContentLength((long) len);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2016 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,6 +18,7 @@ package org.springframework.session.web.http;
import java.io.IOException;
import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
@@ -66,27 +67,66 @@ abstract class OncePerRequestFilter implements Filter {
}
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
String alreadyFilteredAttributeName = this.alreadyFilteredAttributeName;
boolean hasAlreadyFilteredAttribute = request
.getAttribute(this.alreadyFilteredAttributeName) != null;
.getAttribute(alreadyFilteredAttributeName) != null;
if (hasAlreadyFilteredAttribute) {
if (DispatcherType.ERROR.equals(request.getDispatcherType())) {
doFilterNestedErrorDispatch(httpRequest, httpResponse, filterChain);
return;
}
// Proceed without invoking this filter...
filterChain.doFilter(request, response);
}
else {
// Do invoke this filter...
request.setAttribute(this.alreadyFilteredAttributeName, Boolean.TRUE);
request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE);
try {
doFilterInternal(httpRequest, httpResponse, filterChain);
}
finally {
// Remove the "already filtered" request attribute for this request.
request.removeAttribute(this.alreadyFilteredAttributeName);
request.removeAttribute(alreadyFilteredAttributeName);
}
}
}
/**
* Return the name of the request attribute that identifies that a request is already
* filtered.
* <p>
* The default implementation takes the configured name of the concrete filter
* instance and appends ".FILTERED". If the filter is not fully initialized, it falls
* back to its class name.
* @return the name of request attribute indicating already filtered request
* @see #ALREADY_FILTERED_SUFFIX
*/
protected String getAlreadyFilteredAttributeName() {
return this.alreadyFilteredAttributeName;
}
/**
* Typically an ERROR dispatch happens after the REQUEST dispatch completes, and the
* filter chain starts anew. On some servers however the ERROR dispatch may be nested
* within the REQUEST dispatch, e.g. as a result of calling {@code sendError} on the
* response. In that case we are still in the filter chain, on the same thread, but
* the request and response have been switched to the original, unwrapped ones.
* <p>
* Sub-classes may use this method to filter such nested ERROR dispatches and re-apply
* wrapping on the request or response. {@code ThreadLocal} context, if any, should
* still be active as we are still nested within the filter chain.
* @param request the request
* @param response the response
* @param filterChain the filter chain
* @throws ServletException if request is not HTTP request
* @throws IOException in case of I/O operation exception
*/
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
doFilter(request, response, filterChain);
}
/**
* Same contract as for {@code doFilter}, but guaranteed to be just invoked once per
* request within a single request thread.

View File

@@ -159,6 +159,12 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
this.servletContext = servletContext;
}
@Override
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
doFilterInternal(request, response, filterChain);
}
/**
* Allows ensuring that the session is saved if the response is committed.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,6 +16,9 @@
package org.springframework.session.web.http;
import java.time.Clock;
import java.time.Instant;
import java.time.ZoneOffset;
import java.util.Base64;
import javax.servlet.http.Cookie;
@@ -26,6 +29,7 @@ import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.http.HttpHeaders;
import org.springframework.mock.web.MockCookie;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
@@ -56,7 +60,7 @@ public class DefaultCookieSerializerTests {
private MockHttpServletRequest request;
private MockHttpServletResponse response;
private CookiePreservingMockHttpServletResponse response;
private DefaultCookieSerializer serializer;
@@ -70,7 +74,7 @@ public class DefaultCookieSerializerTests {
public void setup() {
this.cookieName = "SESSION";
this.request = new MockHttpServletRequest();
this.response = new MockHttpServletResponse();
this.response = new CookiePreservingMockHttpServletResponse();
this.sessionId = "sessionId";
this.serializer = new DefaultCookieSerializer();
this.serializer.setUseBase64Encoding(this.useBase64Encoding);
@@ -232,7 +236,7 @@ public class DefaultCookieSerializerTests {
this.serializer.writeCookieValue(cookieValue(this.sessionId));
assertThat(getCookie().getDomain()).isEqualTo("example.com");
this.response = new MockHttpServletResponse();
this.response = new CookiePreservingMockHttpServletResponse();
}
String[] notMatchingDomains = { "example.com", "localhost", "127.0.0.1" };
@@ -241,7 +245,7 @@ public class DefaultCookieSerializerTests {
this.serializer.writeCookieValue(cookieValue(this.sessionId));
assertThat(getCookie().getDomain()).isNull();
this.response = new MockHttpServletResponse();
this.response = new CookiePreservingMockHttpServletResponse();
}
}
@@ -326,34 +330,41 @@ public class DefaultCookieSerializerTests {
this.serializer.writeCookieValue(cookieValue(this.sessionId));
assertThat(getCookie().getMaxAge()).isEqualTo(-1);
assertThat(this.response.rawCookie).doesNotContain("Expires");
}
@Test
public void writeCookieCookieMaxAgeExplicit() {
this.serializer.setClock(Clock.fixed(Instant.parse("2019-10-07T20:10:00Z"), ZoneOffset.UTC));
this.serializer.setCookieMaxAge(100);
this.serializer.writeCookieValue(cookieValue(this.sessionId));
assertThat(getCookie().getMaxAge()).isEqualTo(100);
assertThat(this.response.rawCookie).contains("Expires=Mon, 7 Oct 2019 20:11:40 GMT");
}
@Test
public void writeCookieCookieMaxAgeExplicitEmptyCookie() {
this.serializer.setClock(Clock.fixed(Instant.parse("2019-10-07T20:10:00Z"), ZoneOffset.UTC));
this.serializer.setCookieMaxAge(100);
this.serializer.writeCookieValue(cookieValue(""));
assertThat(getCookie().getMaxAge()).isEqualTo(0);
assertThat(this.response.rawCookie).contains("Expires=Thu, 1 Jan 1970 00:00:00 GMT");
}
@Test
public void writeCookieCookieMaxAgeExplicitCookieValue() {
this.serializer.setClock(Clock.fixed(Instant.parse("2019-10-07T20:10:00Z"), ZoneOffset.UTC));
CookieValue cookieValue = cookieValue(this.sessionId);
cookieValue.setCookieMaxAge(100);
this.serializer.writeCookieValue(cookieValue);
assertThat(getCookie().getMaxAge()).isEqualTo(100);
assertThat(this.response.rawCookie).contains("Expires=Mon, 7 Oct 2019 20:11:40 GMT");
}
// --- secure ---
@@ -531,4 +542,18 @@ public class DefaultCookieSerializerTests {
return new CookieValue(this.request, this.response, cookieValue);
}
private static class CookiePreservingMockHttpServletResponse extends MockHttpServletResponse {
private String rawCookie;
@Override
public void addHeader(String name, String value) {
if (HttpHeaders.SET_COOKIE.equals(name)) {
this.rawCookie = value;
}
super.addHeader(name, value);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -1102,6 +1102,17 @@ public class OnCommittedResponseWrapperTests {
assertThat(this.committed).isTrue();
}
// gh-7261
@Test
public void contentLengthLongOutputStreamWriteStringCommits() throws IOException {
String body = "something";
this.response.setContentLengthLong(body.length());
this.response.getOutputStream().print(body);
assertThat(this.committed).isTrue();
}
@Test
public void bufferSizeCommitsOnce() throws Exception {
String expected = "1234567890";

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2017 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
@@ -32,6 +33,7 @@ import org.junit.Test;
import org.springframework.mock.web.MockFilterChain;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.web.util.WebUtils;
import static org.assertj.core.api.Assertions.assertThat;
@@ -95,4 +97,36 @@ public class OncePerRequestFilterTests {
assertThat(this.invocations).containsOnly(this.filter, filter2);
}
@Test // gh-1470
public void filterNestedErrorDispatch() throws ServletException, IOException {
TestOncePerRequestFilter filter = new TestOncePerRequestFilter();
this.request.setAttribute(filter.getAlreadyFilteredAttributeName(), Boolean.TRUE);
this.request.setDispatcherType(DispatcherType.ERROR);
this.request.setAttribute(WebUtils.ERROR_REQUEST_URI_ATTRIBUTE, "/error");
filter.doFilter(this.request, new MockHttpServletResponse(), this.chain);
assertThat(filter.didFilter).isFalse();
assertThat(filter.didFilterNestedErrorDispatch).isTrue();
}
private static class TestOncePerRequestFilter extends OncePerRequestFilter {
private boolean didFilter;
private boolean didFilterNestedErrorDispatch;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) {
this.didFilter = true;
}
@Override
protected void doFilterNestedErrorDispatch(HttpServletRequest request, HttpServletResponse response,
FilterChain filterChain) {
this.didFilterNestedErrorDispatch = true;
}
}
}

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

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ import java.time.Instant;
import org.junit.Test;
import org.junit.runner.RunWith;
import reactor.core.publisher.Mono;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@@ -68,6 +69,17 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
assertThat(this.repository.findById(toSave.getId()).block()).isNull();
}
@Test // gh-1399
public void saveMultipleTimes() {
ReactiveRedisOperationsSessionRepository.RedisSession session = this.repository
.createSession().block();
session.setAttribute("attribute1", "value1");
Mono<Void> save1 = this.repository.save(session);
session.setAttribute("attribute2", "value2");
Mono<Void> save2 = this.repository.save(session);
Mono.zip(save1, save2).block();
}
@Test
public void putAllOnSingleAttrDoesNotRemoveOld() {
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -143,23 +143,15 @@ public class ReactiveRedisOperationsSessionRepository implements
@Override
public Mono<Void> save(RedisSession session) {
Mono<Void> result = session.saveChangeSessionId().and(session.saveDelta())
.and((s) -> {
session.isNew = false;
s.onComplete();
});
if (session.isNew) {
return result;
}
else {
String sessionKey = getSessionKey(
session.hasChangedSessionId() ? session.originalSessionId
: session.getId());
return this.sessionRedisOperations.hasKey(sessionKey)
.flatMap((exists) -> exists ? result
: Mono.error(new IllegalStateException(
"Session was invalidated")));
return session.save();
}
String sessionKey = getSessionKey(
session.hasChangedSessionId() ? session.originalSessionId
: session.getId());
return this.sessionRedisOperations.hasKey(sessionKey).flatMap((exists) -> exists
? session.save()
: Mono.error(new IllegalStateException("Session was invalidated")));
}
@Override
@@ -305,7 +297,7 @@ public class ReactiveRedisOperationsSessionRepository implements
private void flushImmediateIfNecessary() {
if (ReactiveRedisOperationsSessionRepository.this.redisFlushMode == RedisFlushMode.IMMEDIATE) {
saveDelta();
save();
}
}
@@ -314,6 +306,11 @@ public class ReactiveRedisOperationsSessionRepository implements
flushImmediateIfNecessary();
}
private Mono<Void> save() {
return Mono.defer(() -> saveChangeSessionId().then(saveDelta())
.doOnSuccess((aVoid) -> this.isNew = false));
}
private Mono<Void> saveDelta() {
if (this.delta.isEmpty()) {
return Mono.empty();
@@ -321,7 +318,7 @@ public class ReactiveRedisOperationsSessionRepository implements
String sessionKey = getSessionKey(getId());
Mono<Boolean> update = ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations
.opsForHash().putAll(sessionKey, this.delta);
.opsForHash().putAll(sessionKey, new HashMap<>(this.delta));
Mono<Boolean> setTtl = ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations
.expire(sessionKey, getMaxInactiveInterval());

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2018 the original author or authors.
* Copyright 2014-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -132,9 +132,10 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
@Test
public void createSessionDefaultMaxInactiveInterval() {
StepVerifier.create(this.repository.createSession()).consumeNextWith(
(session) -> assertThat(session.getMaxInactiveInterval()).isEqualTo(Duration
.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)))
StepVerifier.create(this.repository.createSession())
.consumeNextWith((session) -> assertThat(session.getMaxInactiveInterval())
.isEqualTo(Duration.ofSeconds(
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)))
.verifyComplete();
}
@@ -155,30 +156,26 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
given(this.redisOperations.expire(anyString(), any()))
.willReturn(Mono.just(true));
StepVerifier
.create(this.repository.createSession().doOnNext(this.repository::save))
.consumeNextWith((session) -> {
verify(this.redisOperations).opsForHash();
verify(this.hashOperations).putAll(anyString(), this.delta.capture());
verify(this.redisOperations).expire(anyString(), any());
verifyZeroInteractions(this.redisOperations);
verifyZeroInteractions(this.hashOperations);
RedisSession newSession = this.repository.new RedisSession();
StepVerifier.create(this.repository.save(newSession)).verifyComplete();
Map<String, Object> delta = this.delta.getAllValues().get(0);
assertThat(delta.size()).isEqualTo(3);
assertThat(delta.get(
ReactiveRedisOperationsSessionRepository.CREATION_TIME_KEY))
.isEqualTo(session.getCreationTime().toEpochMilli());
assertThat(delta.get(
ReactiveRedisOperationsSessionRepository.MAX_INACTIVE_INTERVAL_KEY))
.isEqualTo((int) Duration.ofSeconds(
MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS)
.getSeconds());
assertThat(delta.get(
ReactiveRedisOperationsSessionRepository.LAST_ACCESSED_TIME_KEY))
.isEqualTo(
session.getLastAccessedTime().toEpochMilli());
}).verifyComplete();
verify(this.redisOperations).opsForHash();
verify(this.hashOperations).putAll(anyString(), this.delta.capture());
verify(this.redisOperations).expire(anyString(), any());
verifyZeroInteractions(this.redisOperations);
verifyZeroInteractions(this.hashOperations);
Map<String, Object> delta = this.delta.getAllValues().get(0);
assertThat(delta.size()).isEqualTo(3);
assertThat(delta.get(ReactiveRedisOperationsSessionRepository.CREATION_TIME_KEY))
.isEqualTo(newSession.getCreationTime().toEpochMilli());
assertThat(delta
.get(ReactiveRedisOperationsSessionRepository.MAX_INACTIVE_INTERVAL_KEY))
.isEqualTo(
(int) newSession.getMaxInactiveInterval().getSeconds());
assertThat(delta
.get(ReactiveRedisOperationsSessionRepository.LAST_ACCESSED_TIME_KEY))
.isEqualTo(newSession.getLastAccessedTime().toEpochMilli());
}
@Test
@@ -207,7 +204,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
RedisSession session = this.repository.new RedisSession(this.cached);
session.setLastAccessedTime(Instant.ofEpochMilli(12345678L));
Mono.just(session).subscribe(this.repository::save);
StepVerifier.create(this.repository.save(session)).verifyComplete();
verify(this.redisOperations).hasKey(anyString());
verify(this.redisOperations).opsForHash();
@@ -232,7 +229,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
String attrName = "attrName";
RedisSession session = this.repository.new RedisSession(this.cached);
session.setAttribute(attrName, "attrValue");
Mono.just(session).subscribe(this.repository::save);
StepVerifier.create(this.repository.save(session)).verifyComplete();
verify(this.redisOperations).hasKey(anyString());
verify(this.redisOperations).opsForHash();
@@ -257,7 +254,7 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
String attrName = "attrName";
RedisSession session = this.repository.new RedisSession(new MapSession());
session.removeAttribute(attrName);
Mono.just(session).subscribe(this.repository::save);
StepVerifier.create(this.repository.save(session)).verifyComplete();
verify(this.redisOperations).hasKey(anyString());
verify(this.redisOperations).opsForHash();
@@ -333,24 +330,25 @@ public class ReactiveRedisOperationsSessionRepositoryTests {
given(this.hashOperations.entries(anyString()))
.willReturn(Flux.fromIterable(map.entrySet()));
StepVerifier.create(this.repository.findById("test")).consumeNextWith((session) -> {
verify(this.redisOperations).opsForHash();
verify(this.hashOperations).entries(anyString());
verifyZeroInteractions(this.redisOperations);
verifyZeroInteractions(this.hashOperations);
StepVerifier.create(this.repository.findById("test"))
.consumeNextWith((session) -> {
verify(this.redisOperations).opsForHash();
verify(this.hashOperations).entries(anyString());
verifyZeroInteractions(this.redisOperations);
verifyZeroInteractions(this.hashOperations);
assertThat(session.getId()).isEqualTo(expected.getId());
assertThat(session.getAttributeNames())
.isEqualTo(expected.getAttributeNames());
assertThat(session.<String>getAttribute(attribute1))
.isEqualTo(expected.getAttribute(attribute1));
assertThat(session.<String>getAttribute(attribute2))
.isEqualTo(expected.getAttribute(attribute2));
assertThat(session.getId()).isEqualTo(expected.getId());
assertThat(session.getAttributeNames())
.isEqualTo(expected.getAttributeNames());
assertThat(session.<String>getAttribute(attribute1))
.isEqualTo(expected.getAttribute(attribute1));
assertThat(session.<String>getAttribute(attribute2))
.isEqualTo(expected.getAttribute(attribute2));
assertThat(session.getCreationTime().truncatedTo(ChronoUnit.MILLIS))
.isEqualTo(expected.getCreationTime()
.truncatedTo(ChronoUnit.MILLIS));
assertThat(session.getMaxInactiveInterval())
.isEqualTo(expected.getMaxInactiveInterval());
.isEqualTo(expected.getMaxInactiveInterval());
assertThat(
session.getLastAccessedTime().truncatedTo(ChronoUnit.MILLIS))
.isEqualTo(expected.getLastAccessedTime()

View File

@@ -22,8 +22,8 @@ import com.hazelcast.core.HazelcastInstance;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.runner.RunWith;
import org.testcontainers.containers.BindMode;
import org.testcontainers.containers.GenericContainer;
import org.testcontainers.utility.MountableFile;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -50,11 +50,9 @@ public class HazelcastClientRepositoryITests extends AbstractHazelcastRepository
private static GenericContainer container = new GenericContainer<>(
"hazelcast/hazelcast:3.11.4")
.withExposedPorts(5701)
.withEnv("JAVA_OPTS",
"-Dhazelcast.config=/opt/hazelcast/config_ext/hazelcast.xml")
.withClasspathResourceMapping("/hazelcast-server.xml",
"/opt/hazelcast/config_ext/hazelcast.xml",
BindMode.READ_ONLY);
.withCopyFileToContainer(
MountableFile.forClasspathResource("/hazelcast-server.xml"),
"/opt/hazelcast/hazelcast.xml");
@BeforeClass
public static void setUpClass() {

View File

@@ -88,7 +88,7 @@ final class DatabaseContainers {
private static class MariaDb10Container extends MariaDBContainer<MariaDb10Container> {
MariaDb10Container() {
super("mariadb:10.3.14");
super("mariadb:10.4.8");
}
@Override
@@ -103,7 +103,7 @@ final class DatabaseContainers {
private static class MySql5Container extends MySQLContainer<MySql5Container> {
MySql5Container() {
super("mysql:5.7.26");
super("mysql:5.7.27");
}
@Override
@@ -123,7 +123,7 @@ final class DatabaseContainers {
private static class MySql8Container extends MySQLContainer<MySql8Container> {
MySql8Container() {
super("mysql:8.0.16");
super("mysql:8.0.17");
}
@Override
@@ -143,7 +143,7 @@ final class DatabaseContainers {
extends PostgreSQLContainer<PostgreSql9Container> {
PostgreSql9Container() {
super("postgres:9.6.13");
super("postgres:9.6.15");
}
}
@@ -152,7 +152,7 @@ final class DatabaseContainers {
extends PostgreSQLContainer<PostgreSql10Container> {
PostgreSql10Container() {
super("postgres:10.8");
super("postgres:10.10");
}
}
@@ -161,7 +161,7 @@ final class DatabaseContainers {
extends PostgreSQLContainer<PostgreSql11Container> {
PostgreSql11Container() {
super("postgres:11.3");
super("postgres:11.5");
}
}
@@ -170,7 +170,7 @@ final class DatabaseContainers {
extends MSSQLServerContainer<SqlServer2017Container> {
SqlServer2017Container() {
super("mcr.microsoft.com/mssql/server:2017-CU14");
super("mcr.microsoft.com/mssql/server:2017-CU16");
}
}

View File

@@ -1 +1 @@
mcr.microsoft.com/mssql/server:2017-CU14
mcr.microsoft.com/mssql/server:2017-CU16