Compare commits
297 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b1d68c0731 | ||
|
|
7ec5add1bd | ||
|
|
05e103d9c5 | ||
|
|
8190072d3f | ||
|
|
ce16374c15 | ||
|
|
e41ebd8a77 | ||
|
|
8550aeca5c | ||
|
|
5cb8a6b79a | ||
|
|
5b48e7e8e7 | ||
|
|
9e2b729d62 | ||
|
|
524ee0d9bc | ||
|
|
26be3218fb | ||
|
|
8d4fd80add | ||
|
|
6969ea0049 | ||
|
|
ce938fd2fe | ||
|
|
98d7448b40 | ||
|
|
4bb2bd6fda | ||
|
|
0e5dd1863f | ||
|
|
548b58ee55 | ||
|
|
bb28af9934 | ||
|
|
dee8402473 | ||
|
|
7bd0b45f29 | ||
|
|
b42b01af9b | ||
|
|
6744fee3cb | ||
|
|
6811f25565 | ||
|
|
47817c46e1 | ||
|
|
4f7c6406ad | ||
|
|
34cc1d1171 | ||
|
|
9e7d9912e5 | ||
|
|
d2960b570f | ||
|
|
8bd4374909 | ||
|
|
15f29f8adf | ||
|
|
74d53e8bfc | ||
|
|
77deb63373 | ||
|
|
69285f2a9a | ||
|
|
c93513f18f | ||
|
|
27044c8766 | ||
|
|
b198844671 | ||
|
|
0f27bbaff7 | ||
|
|
62ad3e1bab | ||
|
|
7eed8427a5 | ||
|
|
4cbb253c11 | ||
|
|
3fe03c60f3 | ||
|
|
d95652dcb3 | ||
|
|
cfc1a1e7ce | ||
|
|
e17d0cc1d9 | ||
|
|
0a0766e4a8 | ||
|
|
4108c77797 | ||
|
|
c015a69a4a | ||
|
|
293cf3f730 | ||
|
|
6f79e87c8f | ||
|
|
d74c5b1445 | ||
|
|
6075089691 | ||
|
|
e7a0924904 | ||
|
|
319f0a97ad | ||
|
|
95de199aa4 | ||
|
|
db589b7c29 | ||
|
|
2aae51b1a1 | ||
|
|
e721efeb85 | ||
|
|
0111c6e686 | ||
|
|
07058c0cdf | ||
|
|
5f5168814d | ||
|
|
55502f336d | ||
|
|
0e83e3f1e0 | ||
|
|
34876397a0 | ||
|
|
faee8f1bdb | ||
|
|
859784fe9e | ||
|
|
4dd2db32d2 | ||
|
|
ae86831821 | ||
|
|
b722b12327 | ||
|
|
29ff2e47fb | ||
|
|
dc9da1d5bf | ||
|
|
5a52df37ba | ||
|
|
6d161575d5 | ||
|
|
1cd8849eb9 | ||
|
|
cb3894614a | ||
|
|
82e71d834b | ||
|
|
81a9e71a5b | ||
|
|
298f0d59a0 | ||
|
|
c354284616 | ||
|
|
4086044c2f | ||
|
|
e663401ecb | ||
|
|
60151c9e7d | ||
|
|
18052460c6 | ||
|
|
5092e86306 | ||
|
|
6de6df6dab | ||
|
|
301e65c2b9 | ||
|
|
090a10fb10 | ||
|
|
235801487e | ||
|
|
e6e02de210 | ||
|
|
b3b46fd8eb | ||
|
|
e46610f53a | ||
|
|
e8c6b8db7b | ||
|
|
486d00e5da | ||
|
|
0ab781e537 | ||
|
|
849b353cec | ||
|
|
b262c9a3fd | ||
|
|
5d9e7caff0 | ||
|
|
dd348bc7b8 | ||
|
|
9372986f84 | ||
|
|
657c6a63e1 | ||
|
|
a9c2336482 | ||
|
|
068ed8d355 | ||
|
|
2b6489c2bd | ||
|
|
c0c672b9f8 | ||
|
|
46d1205ff9 | ||
|
|
cc85e927cd | ||
|
|
0819988a15 | ||
|
|
0f3ea33b50 | ||
|
|
0205c318d1 | ||
|
|
13bc1a5d24 | ||
|
|
8d2ec1ea44 | ||
|
|
729ce13390 | ||
|
|
b54fb41952 | ||
|
|
cf911322c2 | ||
|
|
6bce5ddf7f | ||
|
|
7384504871 | ||
|
|
c21fff1a00 | ||
|
|
d602880a58 | ||
|
|
2a2c430793 | ||
|
|
6080611d1d | ||
|
|
38adaeca94 | ||
|
|
6a791651e0 | ||
|
|
dfd6a0bc1b | ||
|
|
805820eeea | ||
|
|
68f867b60b | ||
|
|
1044621caf | ||
|
|
13f5cb4bac | ||
|
|
5c05970b86 | ||
|
|
0cd0bfb32f | ||
|
|
b219806d8e | ||
|
|
0f2a331ea3 | ||
|
|
ef8f667e35 | ||
|
|
4599e75c3a | ||
|
|
8a971b9ce1 | ||
|
|
56e9dcfe20 | ||
|
|
59e2cdb74f | ||
|
|
847433562e | ||
|
|
55a6967331 | ||
|
|
2c8ce67ffc | ||
|
|
076ed5cd71 | ||
|
|
f1ea71e55e | ||
|
|
5acb307a54 | ||
|
|
f921c4f527 | ||
|
|
12dc76ec36 | ||
|
|
7be3d30981 | ||
|
|
9c8fe23789 | ||
|
|
3114ef51ec | ||
|
|
9e7736bf7f | ||
|
|
6c5e335568 | ||
|
|
1deedad3b9 | ||
|
|
e4a8a6aa5c | ||
|
|
49375a28fa | ||
|
|
5375f51bca | ||
|
|
29af9d3a4d | ||
|
|
997ff56c63 | ||
|
|
06d8031211 | ||
|
|
904369ac29 | ||
|
|
266854a0be | ||
|
|
8f02c83e06 | ||
|
|
570a7686b1 | ||
|
|
fed318abc7 | ||
|
|
a824edd1c3 | ||
|
|
aa4f783b45 | ||
|
|
11fb68444f | ||
|
|
00026a30f4 | ||
|
|
c007437bd3 | ||
|
|
dda13b5619 | ||
|
|
366f13bd25 | ||
|
|
3535137c47 | ||
|
|
a9bca9088f | ||
|
|
31de86ecef | ||
|
|
d123960f89 | ||
|
|
16d2923efd | ||
|
|
24015d0854 | ||
|
|
d8f160c178 | ||
|
|
0318f6e2c1 | ||
|
|
43dd571345 | ||
|
|
e7fb9fce47 | ||
|
|
f13eb8d73e | ||
|
|
1a07ba5114 | ||
|
|
7125aac567 | ||
|
|
3cbd3a9e25 | ||
|
|
4c914d46c9 | ||
|
|
adf411ecc3 | ||
|
|
95b39a203f | ||
|
|
3d653b3b50 | ||
|
|
938fd3c2e5 | ||
|
|
45bb0f9b0c | ||
|
|
cddd84d564 | ||
|
|
6931d40e6e | ||
|
|
3b672787f3 | ||
|
|
c0ee52b33b | ||
|
|
68f8641233 | ||
|
|
e7b2af47e1 | ||
|
|
1ad6cbd7f8 | ||
|
|
195af52d0b | ||
|
|
bc9d5f1299 | ||
|
|
3a4345eb6a | ||
|
|
6c41dea893 | ||
|
|
ee1d5b3b3c | ||
|
|
89a4255679 | ||
|
|
6d2e51a0b9 | ||
|
|
798d398d9b | ||
|
|
085554f56b | ||
|
|
45b3b35db7 | ||
|
|
2d06e1159c | ||
|
|
927008bdc8 | ||
|
|
30588dc3c8 | ||
|
|
2f79da00dc | ||
|
|
e2abe36fa8 | ||
|
|
456fd3adb4 | ||
|
|
bd0f474b5b | ||
|
|
e5a3933cb6 | ||
|
|
71e5cc857a | ||
|
|
df455ddc89 | ||
|
|
eceeaa665d | ||
|
|
e6c54d8a75 | ||
|
|
c88456a183 | ||
|
|
f5abd55394 | ||
|
|
b9fd3666b5 | ||
|
|
e06ea36ad5 | ||
|
|
0a1701233e | ||
|
|
47a4873199 | ||
|
|
bd36e115a8 | ||
|
|
ec82336477 | ||
|
|
feaf8780a8 | ||
|
|
b357a76ce3 | ||
|
|
2c6f22afb0 | ||
|
|
34306fd3a0 | ||
|
|
a6c1d8eb1d | ||
|
|
e48b46a2d5 | ||
|
|
8cc8fbb7fd | ||
|
|
96715e04f2 | ||
|
|
121a633a40 | ||
|
|
bf31a9b04b | ||
|
|
a209d436d1 | ||
|
|
6c76a1ccdd | ||
|
|
c974eeb188 | ||
|
|
3b5dadb07f | ||
|
|
3e6b3fda0f | ||
|
|
840da7fb5a | ||
|
|
560ee5ff4f | ||
|
|
072348e28f | ||
|
|
99dfdda7b7 | ||
|
|
18b097d9c7 | ||
|
|
702a35fac6 | ||
|
|
df3e4c5bc1 | ||
|
|
f746233255 | ||
|
|
f6c82f1eee | ||
|
|
bcdd05a0bc | ||
|
|
5d26ab4df4 | ||
|
|
e55d86f5e2 | ||
|
|
fe480b338c | ||
|
|
4b13392430 | ||
|
|
e5d9ce6ead | ||
|
|
bc1ef4359a | ||
|
|
98fa5ed52d | ||
|
|
44468134aa | ||
|
|
c14c621da6 | ||
|
|
6ceca18248 | ||
|
|
229ca09f10 | ||
|
|
36b82d52f8 | ||
|
|
dbeb33fd9d | ||
|
|
23bf92a086 | ||
|
|
2e0c347a3a | ||
|
|
972537a3d5 | ||
|
|
99c4f5bc32 | ||
|
|
89f8127763 | ||
|
|
63f1013a07 | ||
|
|
a988b062c3 | ||
|
|
09368243aa | ||
|
|
903fa10861 | ||
|
|
a883e2ee77 | ||
|
|
f68e569bec | ||
|
|
593c126c03 | ||
|
|
033d6eecae | ||
|
|
24b9d24e18 | ||
|
|
46bc4b0957 | ||
|
|
8cb85618c2 | ||
|
|
1ca9daccb4 | ||
|
|
0731e7f2d0 | ||
|
|
8d0d757e46 | ||
|
|
e2f1fe5446 | ||
|
|
07b9433540 | ||
|
|
a6f6042831 | ||
|
|
099be441dd | ||
|
|
17d029d34d | ||
|
|
aab9b39a6b | ||
|
|
090d882f98 | ||
|
|
d91d09567f | ||
|
|
ab5b0e3a32 | ||
|
|
549a2b7f0b | ||
|
|
050ff7538b | ||
|
|
e8e65ac09f | ||
|
|
822db7fbbf | ||
|
|
0eaeb98b0c |
7
.github/ISSUE_TEMPLATE.md
vendored
7
.github/ISSUE_TEMPLATE.md
vendored
@@ -1,7 +0,0 @@
|
||||
<!--
|
||||
For Security Vulnerabilities, please use https://pivotal.io/security#reporting
|
||||
-->
|
||||
|
||||
<!--
|
||||
Thanks for raising a Spring Session issue. Please provide a brief description of your problem along with the version of Spring Session that you are using. If possible, please also consider putting together a sample application that reproduces the issue.
|
||||
-->
|
||||
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
24
.github/ISSUE_TEMPLATE/bug_report.md
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
labels: 'type: bug, status: waiting-for-triage'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior.
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Sample**
|
||||
|
||||
A link to a GitHub repository with a [minimal, reproducible sample](https://stackoverflow.com/help/minimal-reproducible-example).
|
||||
|
||||
Reports that include a sample will take priority over reports that do not.
|
||||
At times, we may require a sample, so it is good to try and include a sample up front.
|
||||
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
5
.github/ISSUE_TEMPLATE/config.yml
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: Community Support
|
||||
url: https://stackoverflow.com/questions/tagged/spring-security
|
||||
about: Please ask and answer questions on StackOverflow with the tag spring-session
|
||||
25
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
25
.github/ISSUE_TEMPLATE/feature_request.md
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
labels: 'status: waiting-for-triage, type: enhancement'
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
**Expected Behavior**
|
||||
|
||||
<!--- Tell us how it should work -->
|
||||
|
||||
**Current Behavior**
|
||||
|
||||
<!--- Explain the difference from current behavior -->
|
||||
|
||||
**Context**
|
||||
|
||||
<!---
|
||||
How has this issue affected you?
|
||||
What are you trying to accomplish?
|
||||
What other alternatives have you considered?
|
||||
Are you aware of any workarounds?
|
||||
-->
|
||||
101
.github/workflows/continuous-integration-workflow.yml
vendored
Normal file
101
.github/workflows/continuous-integration-workflow.yml
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
schedule:
|
||||
- cron: '0 10 * * *' # Once per day at 10am UTC
|
||||
workflow_dispatch: # Manual trigger
|
||||
|
||||
env:
|
||||
GRADLE_ENTERPRISE_CACHE_USER: ${{ secrets.GRADLE_ENTERPRISE_CACHE_USER }}
|
||||
GRADLE_ENTERPRISE_CACHE_PASSWORD: ${{ secrets.GRADLE_ENTERPRISE_CACHE_PASSWORD }}
|
||||
GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }}
|
||||
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [8, 11]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK ${{ matrix.jdk }}
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
- name: Setup gradle user name
|
||||
run: |
|
||||
mkdir -p ~/.gradle
|
||||
echo 'systemProp.user.name=spring-builds' >> ~/.gradle/gradle.properties
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
|
||||
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
|
||||
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
|
||||
./gradlew clean build -PartifactoryUsername="$ARTIFACTORY_USERNAME" -PartifactoryPassword="$ARTIFACTORY_PASSWORD" --no-daemon --stacktrace
|
||||
artifacts:
|
||||
name: Deploy Artifacts
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: '8'
|
||||
- name: Setup gradle user name
|
||||
run: |
|
||||
mkdir -p ~/.gradle
|
||||
echo 'systemProp.user.name=spring-builds' >> ~/.gradle/gradle.properties
|
||||
- name: Deploy artifacts
|
||||
run: |
|
||||
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
|
||||
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
|
||||
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
|
||||
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
|
||||
env:
|
||||
GPG_PRIVATE_KEY: ${{ secrets.GPG_PRIVATE_KEY_NO_HEADER }}
|
||||
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
|
||||
OSSRH_TOKEN_USERNAME: ${{ secrets.OSSRH_TOKEN_USERNAME }}
|
||||
OSSRH_TOKEN_PASSWORD: ${{ secrets.OSSRH_TOKEN_PASSWORD }}
|
||||
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
|
||||
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
|
||||
docs:
|
||||
name: Deploy Docs
|
||||
needs: [build]
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: '8'
|
||||
- name: Setup gradle user name
|
||||
run: |
|
||||
mkdir -p ~/.gradle
|
||||
echo 'systemProp.user.name=spring-builds' >> ~/.gradle/gradle.properties
|
||||
- name: Deploy Docs
|
||||
run: |
|
||||
export GRADLE_ENTERPRISE_CACHE_USERNAME="$GRADLE_ENTERPRISE_CACHE_USER"
|
||||
export GRADLE_ENTERPRISE_CACHE_PASSWORD="$GRADLE_ENTERPRISE_CACHE_PASSWORD"
|
||||
export GRADLE_ENTERPRISE_ACCESS_KEY="$GRADLE_ENTERPRISE_SECRET_ACCESS_KEY"
|
||||
./gradlew deployDocs --no-daemon -PdeployDocsSshKey="$DOCS_SSH_KEY" -PdeployDocsSshUsername="$DOCS_USERNAME" -PdeployDocsHost="$DOCS_HOST" --stacktrace
|
||||
env:
|
||||
DOCS_USERNAME: ${{ secrets.DOCS_USERNAME }}
|
||||
DOCS_SSH_KEY: ${{ secrets.DOCS_SSH_KEY }}
|
||||
DOCS_HOST: ${{ secrets.DOCS_HOST }}
|
||||
25
.github/workflows/pr-build-workflow.yml
vendored
Normal file
25
.github/workflows/pr-build-workflow.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
name: PR Build
|
||||
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
jdk: [8, 11]
|
||||
fail-fast: false
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: Set up JDK ${{ matrix.jdk }}
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: ${{ matrix.jdk }}
|
||||
- name: Cache Gradle packages
|
||||
uses: actions/cache@v2
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle') }}
|
||||
- name: Build with Gradle
|
||||
run: ./gradlew clean build --no-daemon --stacktrace
|
||||
1
.gitignore
vendored
1
.gitignore
vendored
@@ -13,3 +13,4 @@ out
|
||||
.checkstyle
|
||||
!etc/eclipse/.checkstyle
|
||||
!**/src/**/build
|
||||
.DS_Store
|
||||
|
||||
20
.travis.yml
20
.travis.yml
@@ -1,20 +0,0 @@
|
||||
language: java
|
||||
|
||||
sudo: required
|
||||
|
||||
services: docker
|
||||
|
||||
jdk: oraclejdk8
|
||||
|
||||
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
|
||||
@@ -1,44 +0,0 @@
|
||||
= Contributor Code of Conduct
|
||||
|
||||
As contributors and maintainers of this project, and in the interest of fostering an open
|
||||
and welcoming community, we pledge to respect all people who contribute through reporting
|
||||
issues, posting feature requests, updating documentation, submitting pull requests or
|
||||
patches, and other activities.
|
||||
|
||||
We are committed to making participation in this project a harassment-free experience for
|
||||
everyone, regardless of level of experience, gender, gender identity and expression,
|
||||
sexual orientation, disability, personal appearance, body size, race, ethnicity, age,
|
||||
religion, or nationality.
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery
|
||||
* Personal attacks
|
||||
* Trolling or insulting/derogatory comments
|
||||
* Public or private harassment
|
||||
* Publishing other's private information, such as physical or electronic addresses,
|
||||
without explicit permission
|
||||
* Other unethical or unprofessional conduct
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or reject comments,
|
||||
commits, code, wiki edits, issues, and other contributions that are not aligned to this
|
||||
Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors
|
||||
that they deem inappropriate, threatening, offensive, or harmful.
|
||||
|
||||
By adopting this Code of Conduct, project maintainers commit themselves to fairly and
|
||||
consistently applying these principles to every aspect of managing this project. Project
|
||||
maintainers who do not follow or enforce the Code of Conduct may be permanently removed
|
||||
from the project team.
|
||||
|
||||
This Code of Conduct applies both within project spaces and in public spaces when an
|
||||
individual is representing the project or its community.
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by
|
||||
contacting a project maintainer at spring-code-of-conduct@pivotal.io . All complaints will
|
||||
be reviewed and investigated and will result in a response that is deemed necessary and
|
||||
appropriate to the circumstances. Maintainers are obligated to maintain confidentiality
|
||||
with regard to the reporter of an incident.
|
||||
|
||||
This Code of Conduct is adapted from the
|
||||
https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
|
||||
https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]
|
||||
@@ -3,9 +3,16 @@
|
||||
Spring Session is released under the Apache 2.0 license. If you would like to contribute
|
||||
something, or simply want to hack on the code this document should help you get started.
|
||||
|
||||
|
||||
== Code of Conduct
|
||||
This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct].
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
Please see our https://github.com/spring-projects/.github/blob/main/CODE_OF_CONDUCT.md[code of conduct].
|
||||
|
||||
|
||||
== Reporting Security Vulnerabilities
|
||||
|
||||
Please see our https://github.com/spring-projects/spring-session/security/policy[Security policy].
|
||||
|
||||
|
||||
== Using GitHub issues
|
||||
|
||||
@@ -19,7 +26,6 @@ information as possible. Ideally, that would include a small sample project that
|
||||
reproduces the problem.
|
||||
|
||||
|
||||
|
||||
== Sign the Contributor License Agreement
|
||||
If you have not previously done so, please fill out and
|
||||
submit the https://cla.pivotal.io/sign/spring[Contributor License Agreement].
|
||||
|
||||
179
Jenkinsfile
vendored
179
Jenkinsfile
vendored
@@ -1,179 +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('linux') {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${tool 'jdk8'}"]) {
|
||||
sh './gradlew clean check --no-daemon --refresh-dependencies --stacktrace'
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
currentBuild.result = 'FAILED: check'
|
||||
throw e
|
||||
}
|
||||
finally {
|
||||
junit '**/build/test-results/*/*.xml'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
jdk9: {
|
||||
stage('JDK 9') {
|
||||
timeout(time: 45, unit: 'MINUTES') {
|
||||
node('linux') {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${tool 'jdk9'}"]) {
|
||||
sh './gradlew clean test --no-daemon --refresh-dependencies --stacktrace'
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
currentBuild.result = 'FAILED: jdk9'
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
jdk10: {
|
||||
stage('JDK 10') {
|
||||
timeout(time: 45, unit: 'MINUTES') {
|
||||
node('linux') {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${tool 'jdk10'}"]) {
|
||||
sh './gradlew clean test --no-daemon --refresh-dependencies --stacktrace'
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
currentBuild.result = 'FAILED: jdk10'
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
jdk11: {
|
||||
stage('JDK 11') {
|
||||
timeout(time: 45, unit: 'MINUTES') {
|
||||
node('linux') {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${tool 'jdk11'}"]) {
|
||||
sh './gradlew clean test integrationTest --no-daemon --refresh-dependencies --stacktrace'
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
currentBuild.result = 'FAILED: jdk11'
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
jdk12: {
|
||||
stage('JDK 12') {
|
||||
timeout(time: 45, unit: 'MINUTES') {
|
||||
node('linux') {
|
||||
checkout scm
|
||||
try {
|
||||
withEnv(["JAVA_HOME=${tool 'openjdk12'}"]) {
|
||||
sh './gradlew clean test integrationTest --no-daemon --refresh-dependencies --stacktrace'
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
currentBuild.result = 'FAILED: jdk12'
|
||||
throw e
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (currentBuild.result == 'SUCCESS') {
|
||||
parallel artifacts: {
|
||||
stage('Deploy Artifacts') {
|
||||
node('linux') {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
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')]) {
|
||||
withEnv(["JAVA_HOME=${tool 'jdk8'}"]) {
|
||||
sh './gradlew deployArtifacts finalizeDeployArtifacts --no-daemon --refresh-dependencies --stacktrace -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('linux') {
|
||||
checkout scm
|
||||
sh "git clean -dfx"
|
||||
try {
|
||||
withCredentials([file(credentialsId: 'docs.spring.io-jenkins_private_ssh_key', variable: 'DEPLOY_SSH_KEY')]) {
|
||||
withEnv(["JAVA_HOME=${tool 'jdk8'}"]) {
|
||||
sh './gradlew deployDocs --no-daemon --refresh-dependencies --stacktrace -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"
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
58
README.adoc
58
README.adoc
@@ -1,6 +1,8 @@
|
||||
= 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"]
|
||||
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"]
|
||||
|
||||
image:https://github.com/spring-projects/spring-session/workflows/CI/badge.svg?branch=main["Build Status", link="https://github.com/spring-projects/spring-session/actions?query=workflow%3ACI"]
|
||||
|
||||
Spring Session provides an API and implementations for managing a user's session information, while also making it trivial to support clustered sessions without being tied to an application container specific solution.
|
||||
It also provides transparent integration with:
|
||||
@@ -11,21 +13,61 @@ It also provides transparent integration with:
|
||||
|
||||
== Modules
|
||||
|
||||
Spring Session consists of the following modules:
|
||||
This Spring Session repository consists of the following modules:
|
||||
|
||||
* Spring Session Core - provides core Spring Session functionalities and APIs
|
||||
* Spring Session Data Redis - provides `SessionRepository` and `ReactiveSessionRepository` implementation backed by Redis and configuration support
|
||||
* Spring Session JDBC - provides `SessionRepository` implementation backed by a relational database and configuration support
|
||||
* Spring Session Hazelcast - provides `SessionRepository` implementation backed by Hazelcast and configuration support
|
||||
|
||||
Additional Spring Session modules can be found in the https://github.com/spring-projects/spring-session-data-mongodb[spring-session-data-mongodb] repository
|
||||
and https://github.com/spring-projects/spring-session-data-geode[spring-session-data-geode] repository.
|
||||
|
||||
== Getting Started
|
||||
|
||||
We recommend you visit the https://docs.spring.io/spring-session/docs/current/reference/html5/#samples[Spring Session Reference] and look through the "Samples and Guides" section to see which one best suits your needs.
|
||||
|
||||
== Samples
|
||||
|
||||
Spring Session samples are available in the https://github.com/spring-projects/spring-session/tree/main/spring-session-samples[spring-session-samples] directory.
|
||||
|
||||
|
||||
== Contributing
|
||||
|
||||
Please see our https://github.com/spring-projects/spring-session/blob/main/CONTRIBUTING.adoc[Contributing guidelines]
|
||||
for information on how to report issues, enhancements or security vulnerabilities.
|
||||
|
||||
== Building from Source
|
||||
|
||||
Spring Session uses a https://gradle.org[Gradle]-based build system.
|
||||
In the instructions below, `./gradlew` is invoked from the root of the source tree and serves as
|
||||
a cross-platform, self-contained bootstrap mechanism for the build.
|
||||
|
||||
Check out sources
|
||||
----
|
||||
git clone git@github.com:spring-projects/spring-session.git
|
||||
----
|
||||
|
||||
Install all spring-\* jars into your local Maven cache
|
||||
----
|
||||
./gradlew install
|
||||
----
|
||||
|
||||
Compile and test; build all jars, distribution zips, and docs
|
||||
----
|
||||
./gradlew build
|
||||
----
|
||||
|
||||
|
||||
== Documentation
|
||||
|
||||
You can find the documentation, samples, and guides for using Spring Session on the https://projects.spring.io/spring-session/[Spring Session project site].
|
||||
|
||||
For more in depth information, visit the https://docs.spring.io/spring-session/docs/current/reference/html5/[Spring Session Reference].
|
||||
|
||||
== Code of Conduct
|
||||
|
||||
This project adheres to the Contributor Covenant link:CODE_OF_CONDUCT.adoc[code of conduct].
|
||||
By participating, you are expected to uphold this code. Please report unacceptable behavior to spring-code-of-conduct@pivotal.io.
|
||||
|
||||
== Spring Session Project Site
|
||||
|
||||
You can find the documentation, issue management, support, samples, and guides for using Spring Session at https://projects.spring.io/spring-session/
|
||||
Please see our https://github.com/spring-projects/.github/blob/main/CODE_OF_CONDUCT.md[code of conduct].
|
||||
|
||||
== License
|
||||
|
||||
|
||||
27
build.gradle
27
build.gradle
@@ -4,37 +4,42 @@ buildscript {
|
||||
snapshotBuild = version.endsWith('SNAPSHOT')
|
||||
milestoneBuild = !(releaseBuild || snapshotBuild)
|
||||
|
||||
springBootVersion = '2.2.0.M2'
|
||||
springBootVersion = '2.4.5'
|
||||
}
|
||||
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven { url 'https://repo.spring.io/plugins-release/' }
|
||||
maven {
|
||||
url = 'https://repo.spring.io/plugins-snapshot'
|
||||
if (project.hasProperty('artifactoryUsername')) {
|
||||
credentials {
|
||||
username "$artifactoryUsername"
|
||||
password "$artifactoryPassword"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'io.spring.gradle:spring-build-conventions:0.0.25.RELEASE'
|
||||
classpath 'io.spring.gradle:spring-build-conventions:0.0.37'
|
||||
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
|
||||
classpath 'io.spring.nohttp:nohttp-gradle:0.0.2.RELEASE'
|
||||
}
|
||||
}
|
||||
|
||||
apply plugin: 'io.spring.convention.root'
|
||||
apply plugin: 'io.spring.nohttp'
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
group = 'org.springframework.session'
|
||||
description = 'Spring Session'
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'io.spring.javaformat'
|
||||
|
||||
plugins.withType(JavaPlugin) {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
tasks.withType(Test) {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
tasks.withType(Test) {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,8 +5,10 @@
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${config_loc}/suppressions.xml"/>
|
||||
</module>
|
||||
<module name="io.spring.nohttp.checkstyle.check.NoHttpCheck"/>
|
||||
<module name="io.spring.javaformat.checkstyle.SpringChecks"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.TreeWalker">
|
||||
<module name="io.spring.javaformat.checkstyle.check.SpringJUnit5Check"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
|
||||
<property name="regexp" value="true"/>
|
||||
<property name="illegalPkgs"
|
||||
|
||||
@@ -7,5 +7,5 @@
|
||||
<suppress files="[\\/]spring-session-docs[\\/]" checks="InnerTypeLast"/>
|
||||
<suppress files="[\\/]spring-session-samples[\\/]" checks="Javadoc*"/>
|
||||
<suppress files="[\\/]spring-session-samples[\\/].+Application\.java" checks="HideUtilityClassConstructor"/>
|
||||
<suppress files="SessionRepositoryFilterTests\.java" checks="SpringLambda"/>
|
||||
<suppress files="CookieSerializer\.java" checks="SpringMethodVisibility"/>
|
||||
</suppressions>
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<fileset-config file-format-version="1.2.0" simple-config="true" sync-formatter="false">
|
||||
<local-check-config name="Spring Session Checkstyle" location="${configDir}/checkstyle.xml" type="external" description="">
|
||||
<property name="configDir" value="${configDir}"/>
|
||||
<additional-data name="protect-config-file" value="false"/>
|
||||
</local-check-config>
|
||||
<fileset name="all" enabled="true" check-config-name="Spring Session Checkstyle" local="true">
|
||||
<file-match-pattern match-pattern="." include-pattern="true"/>
|
||||
</fileset>
|
||||
</fileset-config>
|
||||
@@ -1,295 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="12">
|
||||
<profile kind="CodeFormatterProfile" name="Spring Session Java Conventions" version="12">
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
@@ -1,391 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.codeComplete.argumentPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.argumentSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.fieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.fieldSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.localPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.localSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=all_standard_tags
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=default
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.processAnnotations=disabled
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=false
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=90
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=4
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=90
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=true
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
org.eclipse.jdt.core.javaFormatter=org.springframework.ide.eclipse.jdt.formatter.javaformatter
|
||||
File diff suppressed because one or more lines are too long
128
etc/idea/codeStyleConfig.xml
Normal file
128
etc/idea/codeStyleConfig.xml
Normal file
@@ -0,0 +1,128 @@
|
||||
<code_scheme name="SpringSession" version="173">
|
||||
<option name="AUTODETECT_INDENTS" value="false"/>
|
||||
<option name="OTHER_INDENT_OPTIONS">
|
||||
<value>
|
||||
<option name="USE_TAB_CHARACTER" value="true"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="50"/>
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="500"/>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="java" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="javax" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="org.springframework" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="true"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="RIGHT_MARGIN" value="90"/>
|
||||
<option name="ENABLE_JAVADOC_FORMATTING" value="false"/>
|
||||
<option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
|
||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
|
||||
<option name="JD_KEEP_EMPTY_LINES" value="false"/>
|
||||
<GroovyCodeStyleSettings>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="500"/>
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="500"/>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<emptyLine/>
|
||||
<package name="javax" withSubpackages="true" static="false"/>
|
||||
<package name="java" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="org.springframework" withSubpackages="true"
|
||||
static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="true"/>
|
||||
</value>
|
||||
</option>
|
||||
</GroovyCodeStyleSettings>
|
||||
<JavaCodeStyleSettings>
|
||||
<option name="CLASS_NAMES_IN_JAVADOC" value="3"/>
|
||||
<option name="INSERT_INNER_CLASS_IMPORTS" value="true"/>
|
||||
<option name="CLASS_COUNT_TO_USE_IMPORT_ON_DEMAND" value="50"/>
|
||||
<option name="NAMES_COUNT_TO_USE_IMPORT_ON_DEMAND" value="500"/>
|
||||
<option name="PACKAGES_TO_USE_IMPORT_ON_DEMAND">
|
||||
<value/>
|
||||
</option>
|
||||
<option name="IMPORT_LAYOUT_TABLE">
|
||||
<value>
|
||||
<package name="java" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="javax" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="org.springframework" withSubpackages="true"
|
||||
static="false"/>
|
||||
<emptyLine/>
|
||||
<package name="" withSubpackages="true" static="true"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="ENABLE_JAVADOC_FORMATTING" value="false"/>
|
||||
<option name="JD_ALIGN_PARAM_COMMENTS" value="false"/>
|
||||
<option name="JD_ALIGN_EXCEPTION_COMMENTS" value="false"/>
|
||||
<option name="JD_KEEP_INVALID_TAGS" value="false"/>
|
||||
<option name="JD_KEEP_EMPTY_LINES" value="false"/>
|
||||
</JavaCodeStyleSettings>
|
||||
<JetCodeStyleSettings>
|
||||
<option name="PACKAGES_TO_USE_STAR_IMPORTS">
|
||||
<value>
|
||||
<package name="java.util" withSubpackages="false" static="false"/>
|
||||
<package name="kotlinx.android.synthetic" withSubpackages="false"
|
||||
static="false"/>
|
||||
</value>
|
||||
</option>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT" value="20"/>
|
||||
<option name="NAME_COUNT_TO_USE_STAR_IMPORT_FOR_MEMBERS" value="20"/>
|
||||
</JetCodeStyleSettings>
|
||||
<XML>
|
||||
<option name="XML_LEGACY_SETTINGS_IMPORTED" value="true"/>
|
||||
</XML>
|
||||
<editorconfig>
|
||||
<option name="ENABLED" value="false"/>
|
||||
</editorconfig>
|
||||
<codeStyleSettings language="Groovy">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JAVA">
|
||||
<option name="KEEP_BLANK_LINES_BEFORE_RBRACE" value="1"/>
|
||||
<option name="BLANK_LINES_AROUND_FIELD" value="1"/>
|
||||
<option name="BLANK_LINES_AROUND_FIELD_IN_INTERFACE" value="1"/>
|
||||
<option name="ELSE_ON_NEW_LINE" value="true"/>
|
||||
<option name="CATCH_ON_NEW_LINE" value="true"/>
|
||||
<option name="FINALLY_ON_NEW_LINE" value="true"/>
|
||||
<option name="ALIGN_MULTILINE_PARAMETERS" value="false"/>
|
||||
<option name="SPACE_WITHIN_ARRAY_INITIALIZER_BRACES" value="true"/>
|
||||
<option name="SPACE_BEFORE_ARRAY_INITIALIZER_LBRACE" value="true"/>
|
||||
<option name="BINARY_OPERATION_SIGN_ON_NEXT_LINE" value="true"/>
|
||||
<option name="KEEP_SIMPLE_CLASSES_IN_ONE_LINE" value="true"/>
|
||||
<option name="KEEP_MULTIPLE_EXPRESSIONS_IN_ONE_LINE" value="true"/>
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="JSON">
|
||||
<indentOptions>
|
||||
<option name="TAB_SIZE" value="2"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="XML">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
<codeStyleSettings language="kotlin">
|
||||
<indentOptions>
|
||||
<option name="USE_TAB_CHARACTER" value="true"/>
|
||||
</indentOptions>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
@@ -1 +1,3 @@
|
||||
version=2.2.0.M2
|
||||
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.parallel=true
|
||||
version=2.5.0
|
||||
|
||||
@@ -1,33 +1,36 @@
|
||||
dependencyManagement {
|
||||
imports {
|
||||
mavenBom 'com.fasterxml.jackson:jackson-bom:2.9.6'
|
||||
mavenBom 'io.projectreactor:reactor-bom:Dysprosium-M2'
|
||||
mavenBom 'org.junit:junit-bom:5.4.2'
|
||||
mavenBom 'org.springframework:spring-framework-bom:5.2.0.M3'
|
||||
mavenBom 'org.springframework.data:spring-data-releasetrain:Moore-RC1'
|
||||
mavenBom 'org.springframework.security:spring-security-bom:5.2.0.M3'
|
||||
mavenBom 'org.testcontainers:testcontainers-bom:1.11.3'
|
||||
mavenBom 'io.projectreactor:reactor-bom:2020.0.7'
|
||||
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.testcontainers:testcontainers-bom:1.15.3'
|
||||
}
|
||||
|
||||
dependencies {
|
||||
dependencySet(group: 'com.hazelcast', version: '3.12.1') {
|
||||
dependencySet(group: 'com.hazelcast', version: '3.12.12') {
|
||||
entry 'hazelcast'
|
||||
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 'org.aspectj:aspectjweaver:1.9.6'
|
||||
dependency 'com.h2database:h2:1.4.200'
|
||||
dependency 'com.ibm.db2:jcc:11.5.5.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:5.1.7.RELEASE'
|
||||
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 'mysql:mysql-connector-java:8.0.16'
|
||||
dependency 'junit:junit:4.13.2'
|
||||
dependency 'mysql:mysql-connector-java:8.0.25'
|
||||
dependency 'org.apache.derby:derby:10.14.2.0'
|
||||
dependency 'org.assertj:assertj-core:3.12.2'
|
||||
dependency 'org.hsqldb:hsqldb:2.5.0'
|
||||
dependency 'org.mariadb.jdbc:mariadb-java-client:2.4.1'
|
||||
dependency 'org.mockito:mockito-core:2.28.2'
|
||||
dependency 'org.postgresql:postgresql:42.2.5'
|
||||
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.mockito:mockito-core:3.10.0'
|
||||
dependency 'org.postgresql:postgresql:42.2.20'
|
||||
}
|
||||
}
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.1-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
35
gradlew
vendored
35
gradlew
vendored
@@ -82,6 +82,7 @@ esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
@@ -125,10 +126,11 @@ if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin ; then
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
@@ -154,19 +156,19 @@ if $cygwin ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +177,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
25
gradlew.bat
vendored
25
gradlew.bat
vendored
@@ -29,6 +29,9 @@ if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@@ -37,7 +40,7 @@ if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto init
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
@@ -51,7 +54,7 @@ goto fail
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto init
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
@@ -61,28 +64,14 @@ echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:init
|
||||
@rem Get command-line arguments, handling Windows variants
|
||||
|
||||
if not "%OS%" == "Windows_NT" goto win9xME_args
|
||||
|
||||
:win9xME_args
|
||||
@rem Slurp the command line arguments.
|
||||
set CMD_LINE_ARGS=
|
||||
set _SKIP=2
|
||||
|
||||
:win9xME_args_slurp
|
||||
if "x%~1" == "x" goto execute
|
||||
|
||||
set CMD_LINE_ARGS=%*
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
|
||||
@@ -1,3 +1,15 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven { url 'https://repo.spring.io/plugins-release' }
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id "com.gradle.enterprise" version "3.5.1"
|
||||
id "io.spring.ge.conventions" version "0.0.7"
|
||||
}
|
||||
|
||||
rootProject.name = 'spring-session-build'
|
||||
|
||||
include 'spring-session-core'
|
||||
@@ -5,6 +17,8 @@ include 'spring-session-data-redis'
|
||||
include 'spring-session-docs'
|
||||
include 'spring-session-hazelcast'
|
||||
include 'spring-session-jdbc'
|
||||
include 'hazelcast4'
|
||||
project(':hazelcast4').projectDir = file('spring-session-hazelcast/hazelcast4')
|
||||
|
||||
file('spring-session-samples').eachDirMatch(~/spring-session-sample-.*/) { dir ->
|
||||
include dir.name
|
||||
|
||||
@@ -25,5 +25,6 @@ dependencies {
|
||||
testCompile "org.springframework.security:spring-security-core"
|
||||
testCompile "org.junit.jupiter:junit-jupiter-api"
|
||||
testCompile "org.junit.jupiter:junit-jupiter-params"
|
||||
testCompile "org.aspectj:aspectjweaver"
|
||||
testRuntime "org.junit.jupiter:junit-jupiter-engine"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* An {@link IndexResolver} that resolves indexes using multiple @{link IndexResolver}
|
||||
* delegates.
|
||||
*
|
||||
* @param <S> the type of Session being handled
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class DelegatingIndexResolver<S extends Session> implements IndexResolver<S> {
|
||||
|
||||
private final List<IndexResolver<S>> delegates;
|
||||
|
||||
public DelegatingIndexResolver(List<IndexResolver<S>> delegates) {
|
||||
this.delegates = Collections.unmodifiableList(delegates);
|
||||
}
|
||||
|
||||
@SafeVarargs
|
||||
public DelegatingIndexResolver(IndexResolver<S>... delegates) {
|
||||
this(Arrays.asList(delegates));
|
||||
}
|
||||
|
||||
public Map<String, String> resolveIndexesFor(S session) {
|
||||
Map<String, String> indexes = new HashMap<>();
|
||||
for (IndexResolver<S> delegate : this.delegates) {
|
||||
indexes.putAll(delegate.resolveIndexesFor(session));
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
@@ -27,8 +27,7 @@ import java.util.Map;
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public interface FindByIndexNameSessionRepository<S extends Session>
|
||||
extends SessionRepository<S> {
|
||||
public interface FindByIndexNameSessionRepository<S extends Session> extends SessionRepository<S> {
|
||||
|
||||
/**
|
||||
* A session index that contains the current principal name (i.e. username).
|
||||
@@ -44,7 +43,6 @@ public interface FindByIndexNameSessionRepository<S extends Session>
|
||||
/**
|
||||
* Find a {@link Map} of the session id to the {@link Session} of all sessions that
|
||||
* contain the specified index name index value.
|
||||
*
|
||||
* @param indexName the name of the index (i.e.
|
||||
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME})
|
||||
* @param indexValue the value of the index to search for.
|
||||
@@ -59,7 +57,6 @@ public interface FindByIndexNameSessionRepository<S extends Session>
|
||||
* contain the index with the name
|
||||
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} and the
|
||||
* specified principal name.
|
||||
*
|
||||
* @param principalName the principal name
|
||||
* @return a {@code Map} (never {@code null}) of the session id to the {@code Session}
|
||||
* of all sessions that contain the specified principal name. If no results are found,
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Supported modes of writing the session to session store.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public enum FlushMode {
|
||||
|
||||
/**
|
||||
* Only writes to session store when {@link SessionRepository#save(Session)} is
|
||||
* invoked. In a web environment this is typically done as soon as the HTTP response
|
||||
* is committed.
|
||||
*/
|
||||
ON_SAVE,
|
||||
|
||||
/**
|
||||
* Writes to session store as soon as possible. For example
|
||||
* {@link SessionRepository#createSession()} will write the session to session store.
|
||||
* Another example is that setting an attribute using
|
||||
* {@link Session#setAttribute(String, Object)} will also write to session store
|
||||
* immediately.
|
||||
*/
|
||||
IMMEDIATE
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Strategy interface for resolving the {@link Session}'s indexes.
|
||||
*
|
||||
* @param <S> the type of Session being handled
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
* @see FindByIndexNameSessionRepository
|
||||
*/
|
||||
public interface IndexResolver<S extends Session> {
|
||||
|
||||
/**
|
||||
* Resolve indexes for the session.
|
||||
* @param session the session
|
||||
* @return a map of resolved indexes, never {@code null}
|
||||
*/
|
||||
Map<String, String> resolveIndexesFor(S session);
|
||||
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2018 the original author or authors.
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -47,15 +47,20 @@ import java.util.UUID;
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class MapSession implements Session, Serializable {
|
||||
|
||||
/**
|
||||
* Default {@link #setMaxInactiveInterval(Duration)} (30 minutes).
|
||||
*/
|
||||
public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800;
|
||||
|
||||
private String id;
|
||||
|
||||
private final String originalId;
|
||||
|
||||
private Map<String, Object> sessionAttrs = new HashMap<>();
|
||||
|
||||
private Instant creationTime = Instant.now();
|
||||
|
||||
private Instant lastAccessedTime = this.creationTime;
|
||||
|
||||
/**
|
||||
@@ -70,12 +75,10 @@ public final class MapSession implements Session, Serializable {
|
||||
this(generateId());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Creates a new instance with the specified id. This is preferred to the default
|
||||
* constructor when the id is known to prevent unnecessary consumption on entropy
|
||||
* which can be slow.
|
||||
*
|
||||
* @param id the identifier to use
|
||||
*/
|
||||
public MapSession(String id) {
|
||||
@@ -85,7 +88,6 @@ public final class MapSession implements Session, Serializable {
|
||||
|
||||
/**
|
||||
* Creates a new instance from the provided {@link Session}.
|
||||
*
|
||||
* @param session the {@link Session} to initialize this {@link Session} with. Cannot
|
||||
* be null.
|
||||
*/
|
||||
@@ -95,8 +97,7 @@ public final class MapSession implements Session, Serializable {
|
||||
}
|
||||
this.id = session.getId();
|
||||
this.originalId = this.id;
|
||||
this.sessionAttrs = new HashMap<>(
|
||||
session.getAttributeNames().size());
|
||||
this.sessionAttrs = new HashMap<>(session.getAttributeNames().size());
|
||||
for (String attrName : session.getAttributeNames()) {
|
||||
Object attrValue = session.getAttribute(attrName);
|
||||
if (attrValue != null) {
|
||||
@@ -205,7 +206,6 @@ public final class MapSession implements Session, Serializable {
|
||||
* Sets the identifier for this {@link Session}. The id should be a secure random
|
||||
* generated value to prevent malicious users from guessing this value. The default is
|
||||
* a secure random generated identifier.
|
||||
*
|
||||
* @param id the identifier for this session.
|
||||
*/
|
||||
public void setId(String id) {
|
||||
@@ -227,4 +227,5 @@ public final class MapSession implements Session, Serializable {
|
||||
}
|
||||
|
||||
private static final long serialVersionUID = 7160779239673823561L;
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -49,7 +49,6 @@ public class MapSessionRepository implements SessionRepository<MapSession> {
|
||||
/**
|
||||
* Creates a new instance backed by the provided {@link java.util.Map}. This allows
|
||||
* injecting a distributed {@link java.util.Map}.
|
||||
*
|
||||
* @param sessions the {@link java.util.Map} to use. Cannot be null.
|
||||
*/
|
||||
public MapSessionRepository(Map<String, Session> sessions) {
|
||||
@@ -99,8 +98,7 @@ public class MapSessionRepository implements SessionRepository<MapSession> {
|
||||
public MapSession createSession() {
|
||||
MapSession result = new MapSession();
|
||||
if (this.defaultMaxInactiveInterval != null) {
|
||||
result.setMaxInactiveInterval(
|
||||
Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
result.setMaxInactiveInterval(Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
import org.springframework.expression.Expression;
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
|
||||
/**
|
||||
* {@link IndexResolver} to resolve the principal name from session attribute named
|
||||
* {@link FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} or Spring Security
|
||||
* context stored in the session under {@code SPRING_SECURITY_CONTEXT} attribute.
|
||||
*
|
||||
* @param <S> the type of Session being handled
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public class PrincipalNameIndexResolver<S extends Session> extends SingleIndexResolver<S> {
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
private static final Expression expression = new SpelExpressionParser().parseExpression("authentication?.name");
|
||||
|
||||
public PrincipalNameIndexResolver() {
|
||||
super(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
}
|
||||
|
||||
public String resolveIndexValueFor(S session) {
|
||||
String principalName = session.getAttribute(getIndexName());
|
||||
if (principalName != null) {
|
||||
return principalName;
|
||||
}
|
||||
Object authentication = session.getAttribute(SPRING_SECURITY_CONTEXT);
|
||||
if (authentication != null) {
|
||||
return expression.getValue(authentication, String.class);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
@@ -51,7 +51,6 @@ public class ReactiveMapSessionRepository implements ReactiveSessionRepository<M
|
||||
/**
|
||||
* Creates a new instance backed by the provided {@link Map}. This allows injecting a
|
||||
* distributed {@link Map}.
|
||||
*
|
||||
* @param sessions the {@link Map} to use. Cannot be null.
|
||||
*/
|
||||
public ReactiveMapSessionRepository(Map<String, Session> sessions) {
|
||||
@@ -101,8 +100,7 @@ public class ReactiveMapSessionRepository implements ReactiveSessionRepository<M
|
||||
return Mono.defer(() -> {
|
||||
MapSession result = new MapSession();
|
||||
if (this.defaultMaxInactiveInterval != null) {
|
||||
result.setMaxInactiveInterval(
|
||||
Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
result.setMaxInactiveInterval(Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
}
|
||||
return Mono.just(result);
|
||||
});
|
||||
|
||||
@@ -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.
|
||||
@@ -36,7 +36,6 @@ public interface ReactiveSessionRepository<S extends Session> {
|
||||
* persisted. For example, the implementation returned might keep track of the changes
|
||||
* ensuring that only the delta needs to be persisted on a save.
|
||||
* </p>
|
||||
*
|
||||
* @return a new {@link Session} that is capable of being persisted by this
|
||||
* {@link ReactiveSessionRepository}
|
||||
*/
|
||||
@@ -51,7 +50,6 @@ public interface ReactiveSessionRepository<S extends Session> {
|
||||
* returning a {@link Session} that immediately persists any changes. In this case,
|
||||
* this method may not actually do anything.
|
||||
* </p>
|
||||
*
|
||||
* @param session the {@link Session} to save
|
||||
* @return indicator of operation completion
|
||||
*/
|
||||
@@ -60,7 +58,6 @@ public interface ReactiveSessionRepository<S extends Session> {
|
||||
/**
|
||||
* Gets the {@link Session} by the {@link Session#getId()} or null if no
|
||||
* {@link Session} is found.
|
||||
*
|
||||
* @param id the {@link Session#getId()} to lookup
|
||||
* @return the {@link Session} by the {@link Session#getId()} or null if no
|
||||
* {@link Session} is found.
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* Supported modes of tracking and saving session changes to session store.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public enum SaveMode {
|
||||
|
||||
/**
|
||||
* Save only changes made to session, for instance using
|
||||
* {@link Session#setAttribute(String, Object)}. In highly concurrent environments,
|
||||
* this mode minimizes the risk of attributes being overwritten during processing of
|
||||
* parallel requests.
|
||||
*/
|
||||
ON_SET_ATTRIBUTE,
|
||||
|
||||
/**
|
||||
* Same as {@link #ON_SET_ATTRIBUTE} with addition of saving attributes that have been
|
||||
* read using {@link Session#getAttribute(String)}.
|
||||
*/
|
||||
ON_GET_ATTRIBUTE,
|
||||
|
||||
/**
|
||||
* Always save all session attributes, regardless of the interaction with the session.
|
||||
* In highly concurrent environments, this mode increases the risk of attributes being
|
||||
* overwritten during processing of parallel requests.
|
||||
*/
|
||||
ALWAYS
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
@@ -32,13 +32,13 @@ public interface Session {
|
||||
|
||||
/**
|
||||
* Gets a unique string that identifies the {@link Session}.
|
||||
*
|
||||
* @return a unique string that identifies the {@link Session}
|
||||
*/
|
||||
String getId();
|
||||
|
||||
/**
|
||||
* Changes the session id. After invoking the {@link #getId()} will return a new identifier.
|
||||
* Changes the session id. After invoking the {@link #getId()} will return a new
|
||||
* identifier.
|
||||
* @return the new session id which {@link #getId()} will now return
|
||||
*/
|
||||
String changeSessionId();
|
||||
@@ -46,7 +46,6 @@ public interface Session {
|
||||
/**
|
||||
* Gets the Object associated with the specified name or null if no Object is
|
||||
* associated to that name.
|
||||
*
|
||||
* @param <T> the return type of the attribute
|
||||
* @param attributeName the name of the attribute to get
|
||||
* @return the Object associated with the specified name or null if no Object is
|
||||
@@ -65,8 +64,7 @@ public interface Session {
|
||||
default <T> T getRequiredAttribute(String name) {
|
||||
T result = getAttribute(name);
|
||||
if (result == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"Required attribute '" + name + "' is missing.");
|
||||
throw new IllegalArgumentException("Required attribute '" + name + "' is missing.");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -88,7 +86,6 @@ public interface Session {
|
||||
* Gets the attribute names that have a value associated with it. Each value can be
|
||||
* passed into {@link org.springframework.session.Session#getAttribute(String)} to
|
||||
* obtain the attribute value.
|
||||
*
|
||||
* @return the attribute names that have a value associated with it.
|
||||
* @see #getAttribute(String)
|
||||
*/
|
||||
@@ -98,7 +95,6 @@ public interface Session {
|
||||
* Sets the attribute value for the provided attribute name. If the attributeValue is
|
||||
* null, it has the same result as removing the attribute with
|
||||
* {@link org.springframework.session.Session#removeAttribute(String)} .
|
||||
*
|
||||
* @param attributeName the attribute name to set
|
||||
* @param attributeValue the value of the attribute to set. If null, the attribute
|
||||
* will be removed.
|
||||
@@ -113,21 +109,18 @@ public interface Session {
|
||||
|
||||
/**
|
||||
* Gets the time when this session was created.
|
||||
*
|
||||
* @return the time when this session was created.
|
||||
*/
|
||||
Instant getCreationTime();
|
||||
|
||||
/**
|
||||
* Sets the last accessed time.
|
||||
*
|
||||
* @param lastAccessedTime the last accessed time
|
||||
*/
|
||||
void setLastAccessedTime(Instant lastAccessedTime);
|
||||
|
||||
/**
|
||||
* Gets the last time this {@link Session} was accessed.
|
||||
*
|
||||
* @return the last time the client sent a request associated with the session
|
||||
*/
|
||||
Instant getLastAccessedTime();
|
||||
@@ -135,7 +128,6 @@ public interface Session {
|
||||
/**
|
||||
* Sets the maximum inactive interval between requests before this session will be
|
||||
* invalidated. A negative time indicates that the session will never timeout.
|
||||
*
|
||||
* @param interval the amount of time that the {@link Session} should be kept alive
|
||||
* between client requests.
|
||||
*/
|
||||
@@ -144,7 +136,6 @@ public interface Session {
|
||||
/**
|
||||
* Gets the maximum inactive interval between requests before this session will be
|
||||
* invalidated. A negative time indicates that the session will never timeout.
|
||||
*
|
||||
* @return the maximum inactive interval between requests before this session will be
|
||||
* invalidated. A negative time indicates that the session will never timeout.
|
||||
*/
|
||||
@@ -152,7 +143,6 @@ public interface Session {
|
||||
|
||||
/**
|
||||
* Returns true if the session is expired.
|
||||
*
|
||||
* @return true if the session is expired, else false.
|
||||
*/
|
||||
boolean isExpired();
|
||||
|
||||
@@ -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.
|
||||
@@ -34,7 +34,6 @@ public interface SessionRepository<S extends Session> {
|
||||
* persisted. For example, the implementation returned might keep track of the changes
|
||||
* ensuring that only the delta needs to be persisted on a save.
|
||||
* </p>
|
||||
*
|
||||
* @return a new {@link Session} that is capable of being persisted by this
|
||||
* {@link SessionRepository}
|
||||
*/
|
||||
@@ -49,7 +48,6 @@ public interface SessionRepository<S extends Session> {
|
||||
* returning a {@link Session} that immediately persists any changes. In this case,
|
||||
* this method may not actually do anything.
|
||||
* </p>
|
||||
*
|
||||
* @param session the {@link Session} to save
|
||||
*/
|
||||
void save(S session);
|
||||
@@ -57,7 +55,6 @@ public interface SessionRepository<S extends Session> {
|
||||
/**
|
||||
* Gets the {@link Session} by the {@link Session#getId()} or null if no
|
||||
* {@link Session} is found.
|
||||
*
|
||||
* @param id the {@link org.springframework.session.Session#getId()} to lookup
|
||||
* @return the {@link Session} by the {@link Session#getId()} or null if no
|
||||
* {@link Session} is found.
|
||||
@@ -70,4 +67,5 @@ public interface SessionRepository<S extends Session> {
|
||||
* @param id the {@link org.springframework.session.Session#getId()} to delete
|
||||
*/
|
||||
void deleteById(String id);
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Base class for {@link IndexResolver}s that resolve a single index.
|
||||
*
|
||||
* @param <S> the type of Session being handled
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
public abstract class SingleIndexResolver<S extends Session> implements IndexResolver<S> {
|
||||
|
||||
private final String indexName;
|
||||
|
||||
protected SingleIndexResolver(String indexName) {
|
||||
Assert.notNull(indexName, "Index name must not be null");
|
||||
this.indexName = indexName;
|
||||
}
|
||||
|
||||
protected String getIndexName() {
|
||||
return this.indexName;
|
||||
}
|
||||
|
||||
public abstract String resolveIndexValueFor(S session);
|
||||
|
||||
public final Map<String, String> resolveIndexesFor(S session) {
|
||||
String indexValue = resolveIndexValueFor(session);
|
||||
return (indexValue != null) ? Collections.singletonMap(this.indexName, indexValue) : Collections.emptyMap();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import org.springframework.session.ReactiveSessionRepository;
|
||||
|
||||
/**
|
||||
* Strategy that can be used to customize the {@link ReactiveSessionRepository} before it
|
||||
* is fully initialized, in particular to tune its configuration.
|
||||
*
|
||||
* @param <T> the {@link ReactiveSessionRepository} type
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ReactiveSessionRepositoryCustomizer<T extends ReactiveSessionRepository> {
|
||||
|
||||
/**
|
||||
* Customize the {@link ReactiveSessionRepository}.
|
||||
* @param sessionRepository the {@link ReactiveSessionRepository} to customize
|
||||
*/
|
||||
void customize(T sessionRepository);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import org.springframework.session.SessionRepository;
|
||||
|
||||
/**
|
||||
* Strategy that can be used to customize the {@link SessionRepository} before it is fully
|
||||
* initialized, in particular to tune its configuration.
|
||||
*
|
||||
* @param <T> the {@link SessionRepository} type
|
||||
* @author Vedran Pavic
|
||||
* @since 2.2.0
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface SessionRepositoryCustomizer<T extends SessionRepository> {
|
||||
|
||||
/**
|
||||
* Customize the {@link SessionRepository}.
|
||||
* @param sessionRepository the {@link SessionRepository} to customize
|
||||
*/
|
||||
void customize(T sessionRepository);
|
||||
|
||||
}
|
||||
@@ -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.
|
||||
@@ -40,7 +40,7 @@ import org.springframework.session.events.SessionDestroyedEvent;
|
||||
*
|
||||
* {@literal @Bean}
|
||||
* public MapSessionRepository sessionRepository() {
|
||||
* return new MapSessionRepository();
|
||||
* return new MapSessionRepository(new ConcurrentHashMap<>());
|
||||
* }
|
||||
*
|
||||
* }
|
||||
@@ -74,6 +74,7 @@ import org.springframework.session.events.SessionDestroyedEvent;
|
||||
@Target({ java.lang.annotation.ElementType.TYPE })
|
||||
@Documented
|
||||
@Import(SpringHttpSessionConfiguration.class)
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public @interface EnableSpringHttpSession {
|
||||
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ import org.springframework.util.ObjectUtils;
|
||||
*
|
||||
* {@literal @Bean}
|
||||
* public MapSessionRepository sessionRepository() {
|
||||
* return new MapSessionRepository();
|
||||
* return new MapSessionRepository(new ConcurrentHashMap<>());
|
||||
* }
|
||||
*
|
||||
* }
|
||||
@@ -88,7 +88,6 @@ import org.springframework.util.ObjectUtils;
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
* @since 1.1
|
||||
*
|
||||
* @see EnableSpringHttpSession
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -110,8 +109,7 @@ public class SpringHttpSessionConfiguration implements ApplicationContextAware {
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
CookieSerializer cookieSerializer = (this.cookieSerializer != null)
|
||||
? this.cookieSerializer
|
||||
CookieSerializer cookieSerializer = (this.cookieSerializer != null) ? this.cookieSerializer
|
||||
: createDefaultCookieSerializer();
|
||||
this.defaultHttpSessionIdResolver.setCookieSerializer(cookieSerializer);
|
||||
}
|
||||
@@ -124,21 +122,16 @@ public class SpringHttpSessionConfiguration implements ApplicationContextAware {
|
||||
@Bean
|
||||
public <S extends Session> SessionRepositoryFilter<? extends Session> springSessionRepositoryFilter(
|
||||
SessionRepository<S> sessionRepository) {
|
||||
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<>(
|
||||
sessionRepository);
|
||||
SessionRepositoryFilter<S> sessionRepositoryFilter = new SessionRepositoryFilter<>(sessionRepository);
|
||||
sessionRepositoryFilter.setHttpSessionIdResolver(this.httpSessionIdResolver);
|
||||
return sessionRepositoryFilter;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
if (ClassUtils.isPresent(
|
||||
"org.springframework.security.web.authentication.RememberMeServices",
|
||||
null)) {
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
if (ClassUtils.isPresent("org.springframework.security.web.authentication.RememberMeServices", null)) {
|
||||
this.usesSpringSessionRememberMeServices = !ObjectUtils
|
||||
.isEmpty(applicationContext
|
||||
.getBeanNamesForType(SpringSessionRememberMeServices.class));
|
||||
.isEmpty(applicationContext.getBeanNamesForType(SpringSessionRememberMeServices.class));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,8 +163,7 @@ public class SpringHttpSessionConfiguration implements ApplicationContextAware {
|
||||
sessionCookieConfig = this.servletContext.getSessionCookieConfig();
|
||||
}
|
||||
catch (UnsupportedOperationException ex) {
|
||||
this.logger
|
||||
.warn("Unable to obtain SessionCookieConfig: " + ex.getMessage());
|
||||
this.logger.warn("Unable to obtain SessionCookieConfig: " + ex.getMessage());
|
||||
}
|
||||
if (sessionCookieConfig != null) {
|
||||
if (sessionCookieConfig.getName() != null) {
|
||||
@@ -189,8 +181,7 @@ public class SpringHttpSessionConfiguration implements ApplicationContextAware {
|
||||
}
|
||||
}
|
||||
if (this.usesSpringSessionRememberMeServices) {
|
||||
cookieSerializer.setRememberMeRequestAttribute(
|
||||
SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);
|
||||
cookieSerializer.setRememberMeRequestAttribute(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);
|
||||
}
|
||||
return cookieSerializer;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -23,9 +23,10 @@ import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Add this annotation to a {@code @Configuration} class to configure a {@code WebSessionManager} for a WebFlux
|
||||
* application. This annotation assumes a {@code ReactiveSessionRepository} is defined somewhere in the application
|
||||
* context. If not, it will fail with a clear error message. For example:
|
||||
* Add this annotation to a {@code @Configuration} class to configure a
|
||||
* {@code WebSessionManager} for a WebFlux application. This annotation assumes a
|
||||
* {@code ReactiveSessionRepository} is defined somewhere in the application context. If
|
||||
* not, it will fail with a clear error message. For example:
|
||||
*
|
||||
* <pre>
|
||||
* <code>
|
||||
@@ -35,12 +36,11 @@ import org.springframework.context.annotation.Import;
|
||||
*
|
||||
* {@literal @Bean}
|
||||
* public ReactiveSessionRepository sessionRepository() {
|
||||
* return new ReactiveMapSessionRepository();
|
||||
* return new ReactiveMapSessionRepository(new ConcurrentHashMap<>());
|
||||
* }
|
||||
*
|
||||
* }
|
||||
* </code>
|
||||
* </pre>
|
||||
* </code> </pre>
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @since 2.0
|
||||
@@ -49,6 +49,7 @@ import org.springframework.context.annotation.Import;
|
||||
@Target({ java.lang.annotation.ElementType.TYPE })
|
||||
@Documented
|
||||
@Import(SpringWebSessionConfiguration.class)
|
||||
@Configuration
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
public @interface EnableSpringWebSession {
|
||||
|
||||
}
|
||||
|
||||
@@ -27,12 +27,12 @@ import org.springframework.web.server.session.WebSessionIdResolver;
|
||||
import org.springframework.web.server.session.WebSessionManager;
|
||||
|
||||
/**
|
||||
* Wire up a {@link WebSessionManager} using a Reactive {@link ReactiveSessionRepository} from the application context.
|
||||
* Wire up a {@link WebSessionManager} using a Reactive {@link ReactiveSessionRepository}
|
||||
* from the application context.
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
* @author Rob Winch
|
||||
* @since 2.0
|
||||
*
|
||||
* @see EnableSpringWebSession
|
||||
*/
|
||||
@Configuration(proxyBeanMethods = false)
|
||||
@@ -45,10 +45,11 @@ public class SpringWebSessionConfiguration {
|
||||
private WebSessionIdResolver webSessionIdResolver;
|
||||
|
||||
/**
|
||||
* Configure a {@link WebSessionManager} using a provided {@link ReactiveSessionRepository}.
|
||||
*
|
||||
* Configure a {@link WebSessionManager} using a provided
|
||||
* {@link ReactiveSessionRepository}.
|
||||
* @param repository a bean that implements {@link ReactiveSessionRepository}.
|
||||
* @return a configured {@link WebSessionManager} registered with a preconfigured name.
|
||||
* @return a configured {@link WebSessionManager} registered with a preconfigured
|
||||
* name.
|
||||
*/
|
||||
@Bean(WebHttpHandlerBuilder.WEB_SESSION_MANAGER_BEAN_NAME)
|
||||
public WebSessionManager webSessionManager(ReactiveSessionRepository<? extends Session> repository) {
|
||||
@@ -62,4 +63,5 @@ public class SpringWebSessionConfiguration {
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -44,7 +44,6 @@ public abstract class AbstractSessionEvent extends ApplicationEvent {
|
||||
* Gets the {@link Session} that was destroyed. For some {@link SessionRepository}
|
||||
* implementations it may not be possible to get the original session in which case
|
||||
* this may be null.
|
||||
*
|
||||
* @param <S> the type of Session
|
||||
* @return the expired {@link Session} or null if the data store does not support
|
||||
* obtaining it
|
||||
|
||||
@@ -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.
|
||||
@@ -36,23 +36,18 @@ import org.springframework.session.SessionRepository;
|
||||
* @author Vedran Pavic
|
||||
* @since 1.3
|
||||
*/
|
||||
class SpringSessionBackedSessionInformation<S extends Session>
|
||||
extends SessionInformation {
|
||||
class SpringSessionBackedSessionInformation<S extends Session> extends SessionInformation {
|
||||
|
||||
static final String EXPIRED_ATTR = SpringSessionBackedSessionInformation.class
|
||||
.getName() + ".EXPIRED";
|
||||
static final String EXPIRED_ATTR = SpringSessionBackedSessionInformation.class.getName() + ".EXPIRED";
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(SpringSessionBackedSessionInformation.class);
|
||||
private static final Log logger = LogFactory.getLog(SpringSessionBackedSessionInformation.class);
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
private final SessionRepository<S> sessionRepository;
|
||||
|
||||
SpringSessionBackedSessionInformation(S session,
|
||||
SessionRepository<S> sessionRepository) {
|
||||
super(resolvePrincipal(session), session.getId(),
|
||||
Date.from(session.getLastAccessedTime()));
|
||||
SpringSessionBackedSessionInformation(S session, SessionRepository<S> sessionRepository) {
|
||||
super(resolvePrincipal(session), session.getId(), Date.from(session.getLastAccessedTime()));
|
||||
this.sessionRepository = sessionRepository;
|
||||
Boolean expired = session.getAttribute(EXPIRED_ATTR);
|
||||
if (Boolean.TRUE.equals(expired)) {
|
||||
@@ -62,20 +57,16 @@ class SpringSessionBackedSessionInformation<S extends Session>
|
||||
|
||||
/**
|
||||
* Tries to determine the principal's name from the given Session.
|
||||
*
|
||||
* @param session the session
|
||||
* @return the principal's name, or empty String if it couldn't be determined
|
||||
*/
|
||||
private static String resolvePrincipal(Session session) {
|
||||
String principalName = session
|
||||
.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
String principalName = session.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME);
|
||||
if (principalName != null) {
|
||||
return principalName;
|
||||
}
|
||||
SecurityContext securityContext = session
|
||||
.getAttribute(SPRING_SECURITY_CONTEXT);
|
||||
if (securityContext != null
|
||||
&& securityContext.getAuthentication() != null) {
|
||||
SecurityContext securityContext = session.getAttribute(SPRING_SECURITY_CONTEXT);
|
||||
if (securityContext != null && securityContext.getAuthentication() != null) {
|
||||
return securityContext.getAuthentication().getName();
|
||||
}
|
||||
return "";
|
||||
@@ -84,9 +75,8 @@ class SpringSessionBackedSessionInformation<S extends Session>
|
||||
@Override
|
||||
public void expireNow() {
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Expiring session " + getSessionId() + " for user '"
|
||||
+ getPrincipal() + "', presumably because maximum allowed concurrent "
|
||||
+ "sessions was exceeded");
|
||||
logger.debug("Expiring session " + getSessionId() + " for user '" + getPrincipal()
|
||||
+ "', presumably because maximum allowed concurrent " + "sessions was exceeded");
|
||||
}
|
||||
super.expireNow();
|
||||
S session = this.sessionRepository.findById(getSessionId());
|
||||
@@ -95,8 +85,7 @@ class SpringSessionBackedSessionInformation<S extends Session>
|
||||
this.sessionRepository.save(session);
|
||||
}
|
||||
else {
|
||||
logger.info("Could not find Session with id " + getSessionId()
|
||||
+ " to mark as expired");
|
||||
logger.info("Could not find Session with id " + getSessionId() + " to mark as expired");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,14 +16,13 @@
|
||||
|
||||
package org.springframework.session.security;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.security.authentication.TestingAuthenticationToken;
|
||||
import org.springframework.security.core.session.SessionInformation;
|
||||
import org.springframework.security.core.session.SessionRegistry;
|
||||
import org.springframework.security.core.userdetails.UserDetails;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.util.Assert;
|
||||
@@ -44,13 +43,11 @@ import org.springframework.util.Assert;
|
||||
* @author Vedran Pavic
|
||||
* @since 1.3
|
||||
*/
|
||||
public class SpringSessionBackedSessionRegistry<S extends Session>
|
||||
implements SessionRegistry {
|
||||
public class SpringSessionBackedSessionRegistry<S extends Session> implements SessionRegistry {
|
||||
|
||||
private final FindByIndexNameSessionRepository<S> sessionRepository;
|
||||
|
||||
public SpringSessionBackedSessionRegistry(
|
||||
FindByIndexNameSessionRepository<S> sessionRepository) {
|
||||
public SpringSessionBackedSessionRegistry(FindByIndexNameSessionRepository<S> sessionRepository) {
|
||||
Assert.notNull(sessionRepository, "sessionRepository cannot be null");
|
||||
this.sessionRepository = sessionRepository;
|
||||
}
|
||||
@@ -63,16 +60,13 @@ public class SpringSessionBackedSessionRegistry<S extends Session>
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<SessionInformation> getAllSessions(Object principal,
|
||||
boolean includeExpiredSessions) {
|
||||
Collection<S> sessions = this.sessionRepository
|
||||
.findByPrincipalName(name(principal)).values();
|
||||
public List<SessionInformation> getAllSessions(Object principal, boolean includeExpiredSessions) {
|
||||
Collection<S> sessions = this.sessionRepository.findByPrincipalName(name(principal)).values();
|
||||
List<SessionInformation> infos = new ArrayList<>();
|
||||
for (S session : sessions) {
|
||||
if (includeExpiredSessions || !Boolean.TRUE.equals(session
|
||||
.getAttribute(SpringSessionBackedSessionInformation.EXPIRED_ATTR))) {
|
||||
infos.add(new SpringSessionBackedSessionInformation<>(session,
|
||||
this.sessionRepository));
|
||||
if (includeExpiredSessions
|
||||
|| !Boolean.TRUE.equals(session.getAttribute(SpringSessionBackedSessionInformation.EXPIRED_ATTR))) {
|
||||
infos.add(new SpringSessionBackedSessionInformation<>(session, this.sessionRepository));
|
||||
}
|
||||
}
|
||||
return infos;
|
||||
@@ -82,8 +76,7 @@ public class SpringSessionBackedSessionRegistry<S extends Session>
|
||||
public SessionInformation getSessionInformation(String sessionId) {
|
||||
S session = this.sessionRepository.findById(sessionId);
|
||||
if (session != null) {
|
||||
return new SpringSessionBackedSessionInformation<>(session,
|
||||
this.sessionRepository);
|
||||
return new SpringSessionBackedSessionInformation<>(session, this.sessionRepository);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -111,19 +104,13 @@ public class SpringSessionBackedSessionRegistry<S extends Session>
|
||||
|
||||
/**
|
||||
* Derives a String name for the given principal.
|
||||
*
|
||||
* @param principal as provided by Spring Security
|
||||
* @return name of the principal, or its {@code toString()} representation if no name
|
||||
* could be derived
|
||||
*/
|
||||
protected String name(Object principal) {
|
||||
if (principal instanceof UserDetails) {
|
||||
return ((UserDetails) principal).getUsername();
|
||||
}
|
||||
if (principal instanceof Principal) {
|
||||
return ((Principal) principal).getName();
|
||||
}
|
||||
return principal.toString();
|
||||
// We are reusing the logic from AbstractAuthenticationToken#getName
|
||||
return new TestingAuthenticationToken(principal, null).getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -36,21 +36,19 @@ import org.springframework.util.Assert;
|
||||
* @author Vedran Pavic
|
||||
* @since 1.3.0
|
||||
*/
|
||||
public class SpringSessionRememberMeServices
|
||||
implements RememberMeServices, LogoutHandler {
|
||||
public class SpringSessionRememberMeServices implements RememberMeServices, LogoutHandler {
|
||||
|
||||
/**
|
||||
* Remember-me login request attribute name.
|
||||
*/
|
||||
public static final String REMEMBER_ME_LOGIN_ATTR = SpringSessionRememberMeServices.class
|
||||
.getName() + "REMEMBER_ME_LOGIN_ATTR";
|
||||
public static final String REMEMBER_ME_LOGIN_ATTR = SpringSessionRememberMeServices.class.getName()
|
||||
+ "REMEMBER_ME_LOGIN_ATTR";
|
||||
|
||||
private static final String DEFAULT_REMEMBERME_PARAMETER = "remember-me";
|
||||
|
||||
private static final int THIRTY_DAYS_SECONDS = 2592000;
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(SpringSessionRememberMeServices.class);
|
||||
private static final Log logger = LogFactory.getLog(SpringSessionRememberMeServices.class);
|
||||
|
||||
private String rememberMeParameterName = DEFAULT_REMEMBERME_PARAMETER;
|
||||
|
||||
@@ -58,25 +56,20 @@ public class SpringSessionRememberMeServices
|
||||
|
||||
private int validitySeconds = THIRTY_DAYS_SECONDS;
|
||||
|
||||
private String sessionAttrToDeleteOnLoginFail = HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY;
|
||||
|
||||
@Override
|
||||
public final Authentication autoLogin(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
public final Authentication autoLogin(HttpServletRequest request, HttpServletResponse response) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void loginFail(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
public final void loginFail(HttpServletRequest request, HttpServletResponse response) {
|
||||
logout(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void loginSuccess(HttpServletRequest request,
|
||||
HttpServletResponse response, Authentication successfulAuthentication) {
|
||||
if (!this.alwaysRemember
|
||||
&& !rememberMeRequested(request, this.rememberMeParameterName)) {
|
||||
public final void loginSuccess(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication successfulAuthentication) {
|
||||
if (!this.alwaysRemember && !rememberMeRequested(request, this.rememberMeParameterName)) {
|
||||
logger.debug("Remember-me login not requested.");
|
||||
return;
|
||||
}
|
||||
@@ -103,8 +96,7 @@ public class SpringSessionRememberMeServices
|
||||
}
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Did not send remember-me cookie (principal did not set "
|
||||
+ "parameter '" + parameter + "')");
|
||||
logger.debug("Did not send remember-me cookie (principal did not set " + "parameter '" + parameter + "')");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -116,8 +108,7 @@ public class SpringSessionRememberMeServices
|
||||
* @param rememberMeParameterName the request parameter
|
||||
*/
|
||||
public void setRememberMeParameterName(String rememberMeParameterName) {
|
||||
Assert.hasText(rememberMeParameterName,
|
||||
"rememberMeParameterName cannot be empty or null");
|
||||
Assert.hasText(rememberMeParameterName, "rememberMeParameterName cannot be empty or null");
|
||||
this.rememberMeParameterName = rememberMeParameterName;
|
||||
}
|
||||
|
||||
@@ -130,8 +121,7 @@ public class SpringSessionRememberMeServices
|
||||
}
|
||||
|
||||
@Override
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response,
|
||||
Authentication authentication) {
|
||||
public void logout(HttpServletRequest request, HttpServletResponse response, Authentication authentication) {
|
||||
logout(request);
|
||||
}
|
||||
|
||||
@@ -139,7 +129,8 @@ public class SpringSessionRememberMeServices
|
||||
logger.debug("Interactive login attempt was unsuccessful.");
|
||||
HttpSession session = request.getSession(false);
|
||||
if (session != null) {
|
||||
session.removeAttribute(this.sessionAttrToDeleteOnLoginFail);
|
||||
session.removeAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -23,7 +23,6 @@ import javax.servlet.DispatcherType;
|
||||
import javax.servlet.Filter;
|
||||
import javax.servlet.FilterRegistration.Dynamic;
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.core.Conventions;
|
||||
@@ -71,8 +70,7 @@ import org.springframework.web.filter.DelegatingFilterProxy;
|
||||
*
|
||||
*/
|
||||
@Order(100)
|
||||
public abstract class AbstractHttpSessionApplicationInitializer
|
||||
implements WebApplicationInitializer {
|
||||
public abstract class AbstractHttpSessionApplicationInitializer implements WebApplicationInitializer {
|
||||
|
||||
private static final String SERVLET_CONTEXT_PREFIX = "org.springframework.web.servlet.FrameworkServlet.CONTEXT.";
|
||||
|
||||
@@ -98,17 +96,15 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
/**
|
||||
* Creates a new instance that will instantiate the {@link ContextLoaderListener} with
|
||||
* the specified classes.
|
||||
*
|
||||
* @param configurationClasses {@code @Configuration} classes that will be used to
|
||||
* configure the context
|
||||
*/
|
||||
protected AbstractHttpSessionApplicationInitializer(
|
||||
Class<?>... configurationClasses) {
|
||||
protected AbstractHttpSessionApplicationInitializer(Class<?>... configurationClasses) {
|
||||
this.configurationClasses = configurationClasses;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartup(ServletContext servletContext) throws ServletException {
|
||||
public void onStartup(ServletContext servletContext) {
|
||||
beforeSessionRepositoryFilter(servletContext);
|
||||
if (this.configurationClasses != null) {
|
||||
AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext();
|
||||
@@ -125,8 +121,7 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
*/
|
||||
private void insertSessionRepositoryFilter(ServletContext servletContext) {
|
||||
String filterName = DEFAULT_FILTER_NAME;
|
||||
DelegatingFilterProxy springSessionRepositoryFilter = new DelegatingFilterProxy(
|
||||
filterName);
|
||||
DelegatingFilterProxy springSessionRepositoryFilter = new DelegatingFilterProxy(filterName);
|
||||
String contextAttribute = getWebApplicationContextAttribute();
|
||||
if (contextAttribute != null) {
|
||||
springSessionRepositoryFilter.setContextAttribute(contextAttribute);
|
||||
@@ -138,7 +133,6 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
* Inserts the provided {@link Filter}s before existing {@link Filter}s using default
|
||||
* generated names, {@link #getSessionDispatcherTypes()}, and
|
||||
* {@link #isAsyncSessionSupported()}.
|
||||
*
|
||||
* @param servletContext the {@link ServletContext} to use
|
||||
* @param filters the {@link Filter}s to register
|
||||
*/
|
||||
@@ -150,7 +144,6 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
* Inserts the provided {@link Filter}s after existing {@link Filter}s using default
|
||||
* generated names, {@link #getSessionDispatcherTypes()}, and
|
||||
* {@link #isAsyncSessionSupported()}.
|
||||
*
|
||||
* @param servletContext the {@link ServletContext} to use
|
||||
* @param filters the {@link Filter}s to register
|
||||
*/
|
||||
@@ -161,22 +154,18 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
/**
|
||||
* Registers the provided {@link Filter}s using default generated names,
|
||||
* {@link #getSessionDispatcherTypes()}, and {@link #isAsyncSessionSupported()}.
|
||||
*
|
||||
* @param servletContext the {@link ServletContext} to use
|
||||
* @param insertBeforeOtherFilters if true, will insert the provided {@link Filter}s
|
||||
* before other {@link Filter}s. Otherwise, will insert the {@link Filter}s after
|
||||
* other {@link Filter}s.
|
||||
* @param filters the {@link Filter}s to register
|
||||
*/
|
||||
private void registerFilters(ServletContext servletContext,
|
||||
boolean insertBeforeOtherFilters, Filter... filters) {
|
||||
private void registerFilters(ServletContext servletContext, boolean insertBeforeOtherFilters, Filter... filters) {
|
||||
Assert.notEmpty(filters, "filters cannot be null or empty");
|
||||
|
||||
for (Filter filter : filters) {
|
||||
if (filter == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"filters cannot contain null values. Got "
|
||||
+ Arrays.asList(filters));
|
||||
throw new IllegalArgumentException("filters cannot contain null values. Got " + Arrays.asList(filters));
|
||||
}
|
||||
String filterName = Conventions.getVariableName(filter);
|
||||
registerFilter(servletContext, insertBeforeOtherFilters, filterName, filter);
|
||||
@@ -186,25 +175,22 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
/**
|
||||
* Registers the provided filter using the {@link #isAsyncSessionSupported()} and
|
||||
* {@link #getSessionDispatcherTypes()}.
|
||||
*
|
||||
* @param servletContext the servlet context
|
||||
* @param insertBeforeOtherFilters should this Filter be inserted before or after
|
||||
* other {@link Filter}
|
||||
* @param filterName the filter name
|
||||
* @param filter the filter
|
||||
*/
|
||||
private void registerFilter(ServletContext servletContext,
|
||||
boolean insertBeforeOtherFilters, String filterName, Filter filter) {
|
||||
private void registerFilter(ServletContext servletContext, boolean insertBeforeOtherFilters, String filterName,
|
||||
Filter filter) {
|
||||
Dynamic registration = servletContext.addFilter(filterName, filter);
|
||||
if (registration == null) {
|
||||
throw new IllegalStateException(
|
||||
"Duplicate Filter registration for '" + filterName
|
||||
+ "'. Check to ensure the Filter is only configured once.");
|
||||
throw new IllegalStateException("Duplicate Filter registration for '" + filterName
|
||||
+ "'. Check to ensure the Filter is only configured once.");
|
||||
}
|
||||
registration.setAsyncSupported(isAsyncSessionSupported());
|
||||
EnumSet<DispatcherType> dispatcherTypes = getSessionDispatcherTypes();
|
||||
registration.addMappingForUrlPatterns(dispatcherTypes, !insertBeforeOtherFilters,
|
||||
"/*");
|
||||
registration.addMappingForUrlPatterns(dispatcherTypes, !insertBeforeOtherFilters, "/*");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -218,7 +204,6 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
* {@link ApplicationContext} is used to look up the springSessionRepositoryFilter
|
||||
* bean.
|
||||
* </p>
|
||||
*
|
||||
* @return the {@link DelegatingFilterProxy#getContextAttribute()} or null if the
|
||||
* parent {@link ApplicationContext} should be used
|
||||
*/
|
||||
@@ -241,7 +226,6 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
* name, you can return "dispatcher" from this method to use the DispatcherServlet's
|
||||
* {@link WebApplicationContext}.
|
||||
* </p>
|
||||
*
|
||||
* @return the {@code <servlet-name>} of the DispatcherServlet to use its
|
||||
* {@link WebApplicationContext} or null (default) to use the parent
|
||||
* {@link ApplicationContext}.
|
||||
@@ -271,17 +255,16 @@ public abstract class AbstractHttpSessionApplicationInitializer
|
||||
* @return the {@link DispatcherType} for the filter
|
||||
*/
|
||||
protected EnumSet<DispatcherType> getSessionDispatcherTypes() {
|
||||
return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR,
|
||||
DispatcherType.ASYNC);
|
||||
return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the springSessionRepositoryFilter should be marked as supporting
|
||||
* asynch. Default is true.
|
||||
*
|
||||
* @return true if springSessionRepositoryFilter should be marked as supporting asynch
|
||||
*/
|
||||
protected boolean isAsyncSessionSupported() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -63,8 +63,8 @@ import org.springframework.session.web.http.CookieSerializer.CookieValue;
|
||||
*/
|
||||
public final class CookieHttpSessionIdResolver implements HttpSessionIdResolver {
|
||||
|
||||
private static final String WRITTEN_SESSION_ID_ATTR = CookieHttpSessionIdResolver.class
|
||||
.getName().concat(".WRITTEN_SESSION_ID_ATTR");
|
||||
private static final String WRITTEN_SESSION_ID_ATTR = CookieHttpSessionIdResolver.class.getName()
|
||||
.concat(".WRITTEN_SESSION_ID_ATTR");
|
||||
|
||||
private CookieSerializer cookieSerializer = new DefaultCookieSerializer();
|
||||
|
||||
@@ -74,14 +74,12 @@ public final class CookieHttpSessionIdResolver implements HttpSessionIdResolver
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionId(HttpServletRequest request, HttpServletResponse response,
|
||||
String sessionId) {
|
||||
public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
|
||||
if (sessionId.equals(request.getAttribute(WRITTEN_SESSION_ID_ATTR))) {
|
||||
return;
|
||||
}
|
||||
request.setAttribute(WRITTEN_SESSION_ID_ATTR, sessionId);
|
||||
this.cookieSerializer
|
||||
.writeCookieValue(new CookieValue(request, response, sessionId));
|
||||
this.cookieSerializer.writeCookieValue(new CookieValue(request, response, sessionId));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,7 +89,6 @@ public final class CookieHttpSessionIdResolver implements HttpSessionIdResolver
|
||||
|
||||
/**
|
||||
* Sets the {@link CookieSerializer} to be used.
|
||||
*
|
||||
* @param cookieSerializer the cookieSerializer to set. Cannot be null.
|
||||
*/
|
||||
public void setCookieSerializer(CookieSerializer cookieSerializer) {
|
||||
|
||||
@@ -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.
|
||||
@@ -32,7 +32,6 @@ public interface CookieSerializer {
|
||||
|
||||
/**
|
||||
* Writes a given {@link CookieValue} to the provided {@link HttpServletResponse}.
|
||||
*
|
||||
* @param cookieValue the {@link CookieValue} to write to
|
||||
* {@link CookieValue#getResponse()}. Cannot be null.
|
||||
*/
|
||||
@@ -43,7 +42,6 @@ public interface CookieSerializer {
|
||||
* List since there can be multiple {@link Cookie} in a single request with a matching
|
||||
* name. For example, one Cookie may have a path of / and another of /context, but the
|
||||
* path is not transmitted in the request.
|
||||
*
|
||||
* @param request the {@link HttpServletRequest} to read the cookie from. Cannot be
|
||||
* null.
|
||||
* @return the values of all the matching cookies
|
||||
@@ -70,7 +68,6 @@ public interface CookieSerializer {
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param request the {@link HttpServletRequest} to use. Useful for determining
|
||||
* the context in which the cookie is set. Cannot be null.
|
||||
* @param response the {@link HttpServletResponse} to use.
|
||||
@@ -78,8 +75,7 @@ public interface CookieSerializer {
|
||||
* modified by the {@link CookieSerializer} when writing to the actual cookie so
|
||||
* long as the original value is returned when the cookie is read.
|
||||
*/
|
||||
public CookieValue(HttpServletRequest request, HttpServletResponse response,
|
||||
String cookieValue) {
|
||||
public CookieValue(HttpServletRequest request, HttpServletResponse response, String cookieValue) {
|
||||
this.request = request;
|
||||
this.response = response;
|
||||
this.cookieValue = cookieValue;
|
||||
@@ -108,7 +104,6 @@ public interface CookieSerializer {
|
||||
* The value to be written. This value may be modified by the
|
||||
* {@link CookieSerializer} before written to the cookie. However, the value must
|
||||
* be the same as the original when it is read back in.
|
||||
*
|
||||
* @return the value to be written
|
||||
*/
|
||||
public String getCookieValue() {
|
||||
|
||||
@@ -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;
|
||||
@@ -97,15 +100,12 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
if (cookies != null) {
|
||||
for (Cookie cookie : cookies) {
|
||||
if (this.cookieName.equals(cookie.getName())) {
|
||||
String sessionId = (this.useBase64Encoding
|
||||
? base64Decode(cookie.getValue())
|
||||
: cookie.getValue());
|
||||
String sessionId = (this.useBase64Encoding ? base64Decode(cookie.getValue()) : cookie.getValue());
|
||||
if (sessionId == null) {
|
||||
continue;
|
||||
}
|
||||
if (this.jvmRoute != null && sessionId.endsWith(this.jvmRoute)) {
|
||||
sessionId = sessionId.substring(0,
|
||||
sessionId.length() - this.jvmRoute.length());
|
||||
sessionId = sessionId.substring(0, sessionId.length() - this.jvmRoute.length());
|
||||
}
|
||||
matchingCookieValues.add(sessionId);
|
||||
}
|
||||
@@ -124,7 +124,6 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
public void writeCookieValue(CookieValue cookieValue) {
|
||||
HttpServletRequest request = cookieValue.getRequest();
|
||||
HttpServletResponse response = cookieValue.getResponse();
|
||||
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append(this.cookieName).append('=');
|
||||
String value = getValue(cookieValue);
|
||||
@@ -135,11 +134,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);
|
||||
sb.append("; Expires=")
|
||||
.append(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME));
|
||||
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));
|
||||
}
|
||||
String domain = getDomainName(request);
|
||||
if (domain != null && domain.length() > 0) {
|
||||
@@ -160,7 +157,6 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
if (this.sameSite != null) {
|
||||
sb.append("; SameSite=").append(this.sameSite);
|
||||
}
|
||||
|
||||
response.addHeader("Set-Cookie", sb.toString());
|
||||
}
|
||||
|
||||
@@ -214,10 +210,8 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
char[] chars = value.toCharArray();
|
||||
for (int i = start; i < end; i++) {
|
||||
char c = chars[i];
|
||||
if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c
|
||||
|| c == 0x7f) {
|
||||
throw new IllegalArgumentException(
|
||||
"Invalid character in cookie value: " + Integer.toString(c));
|
||||
if (c < 0x21 || c == 0x22 || c == 0x2c || c == 0x3b || c == 0x5c || c == 0x7f) {
|
||||
throw new IllegalArgumentException("Invalid character in cookie value: " + c);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -225,8 +219,8 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
private int getMaxAge(CookieValue cookieValue) {
|
||||
int maxAge = cookieValue.getCookieMaxAge();
|
||||
if (maxAge < 0) {
|
||||
if (this.rememberMeRequestAttribute != null && cookieValue.getRequest()
|
||||
.getAttribute(this.rememberMeRequestAttribute) != null) {
|
||||
if (this.rememberMeRequestAttribute != null
|
||||
&& cookieValue.getRequest().getAttribute(this.rememberMeRequestAttribute) != null) {
|
||||
// the cookie is only written at time of session creation, so we rely on
|
||||
// session expiration rather than cookie expiration if remember me is
|
||||
// enabled
|
||||
@@ -247,8 +241,7 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
while (i < chars.length) {
|
||||
prev = cur;
|
||||
cur = chars[i];
|
||||
if (!domainValid.get(cur)
|
||||
|| ((prev == '.' || prev == -1) && (cur == '.' || cur == '-'))
|
||||
if (!domainValid.get(cur) || ((prev == '.' || prev == -1) && (cur == '.' || cur == '-'))
|
||||
|| (prev == '-' && cur == '.')) {
|
||||
throw new IllegalArgumentException("Invalid cookie domain: " + domain);
|
||||
}
|
||||
@@ -267,10 +260,13 @@ 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()}.
|
||||
*
|
||||
* @param useSecureCookie determines if the cookie should be marked as secure.
|
||||
*/
|
||||
public void setUseSecureCookie(boolean useSecureCookie) {
|
||||
@@ -279,7 +275,6 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
|
||||
/**
|
||||
* Sets if a Cookie marked as HTTP Only should be used. The default is true.
|
||||
*
|
||||
* @param useHttpOnlyCookie determines if the cookie should be marked as HTTP Only.
|
||||
*/
|
||||
public void setUseHttpOnlyCookie(boolean useHttpOnlyCookie) {
|
||||
@@ -296,7 +291,6 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
/**
|
||||
* Sets the path of the Cookie. The default is to use the context path from the
|
||||
* {@link HttpServletRequest}.
|
||||
*
|
||||
* @param cookiePath the path of the Cookie. If null, the default of the context path
|
||||
* will be used.
|
||||
*/
|
||||
@@ -314,8 +308,7 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
/**
|
||||
* Sets the maxAge property of the Cookie. The default is to delete the cookie when
|
||||
* the browser is closed.
|
||||
*
|
||||
* @param cookieMaxAge the maxAge property of the Cookie
|
||||
* @param cookieMaxAge the maxAge property of the Cookie (defined in seconds)
|
||||
*/
|
||||
public void setCookieMaxAge(int cookieMaxAge) {
|
||||
this.cookieMaxAge = cookieMaxAge;
|
||||
@@ -325,14 +318,12 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
* Sets an explicit Domain Name. This allow the domain of "example.com" to be used
|
||||
* when the request comes from www.example.com. This allows for sharing the cookie
|
||||
* across subdomains. The default is to use the current domain.
|
||||
*
|
||||
* @param domainName the name of the domain to use. (i.e. "example.com")
|
||||
* @throws IllegalStateException if the domainNamePattern is also set
|
||||
*/
|
||||
public void setDomainName(String domainName) {
|
||||
if (this.domainNamePattern != null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot set both domainName and domainNamePattern");
|
||||
throw new IllegalStateException("Cannot set both domainName and domainNamePattern");
|
||||
}
|
||||
this.domainName = domainName;
|
||||
}
|
||||
@@ -362,18 +353,15 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
* <li>localhost - null</li>
|
||||
* <li>127.0.1.1 - null</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param domainNamePattern the case insensitive pattern to extract the domain name
|
||||
* with
|
||||
* @throws IllegalStateException if the domainName is also set
|
||||
*/
|
||||
public void setDomainNamePattern(String domainNamePattern) {
|
||||
if (this.domainName != null) {
|
||||
throw new IllegalStateException(
|
||||
"Cannot set both domainName and domainNamePattern");
|
||||
throw new IllegalStateException("Cannot set both domainName and domainNamePattern");
|
||||
}
|
||||
this.domainNamePattern = Pattern.compile(domainNamePattern,
|
||||
Pattern.CASE_INSENSITIVE);
|
||||
this.domainNamePattern = Pattern.compile(domainNamePattern, Pattern.CASE_INSENSITIVE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -390,7 +378,6 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
* To use set a custom route on each JVM instance and setup a frontend proxy to
|
||||
* forward all requests to the JVM based on the route.
|
||||
* </p>
|
||||
*
|
||||
* @param jvmRoute the JVM Route to use (i.e. "node01jvmA", "n01ja", etc)
|
||||
*/
|
||||
public void setJvmRoute(String jvmRoute) {
|
||||
@@ -401,7 +388,6 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
* Set if the Base64 encoding of cookie value should be used. This is valuable in
|
||||
* order to support <a href="https://tools.ietf.org/html/rfc6265">RFC 6265</a> which
|
||||
* recommends using Base 64 encoding to the cookie value.
|
||||
*
|
||||
* @param useBase64Encoding the flag to indicate whether to use Base64 encoding
|
||||
*/
|
||||
public void setUseBase64Encoding(boolean useBase64Encoding) {
|
||||
@@ -416,8 +402,7 @@ public class DefaultCookieSerializer implements CookieSerializer {
|
||||
*/
|
||||
public void setRememberMeRequestAttribute(String rememberMeRequestAttribute) {
|
||||
if (rememberMeRequestAttribute == null) {
|
||||
throw new IllegalArgumentException(
|
||||
"rememberMeRequestAttribute cannot be null");
|
||||
throw new IllegalArgumentException("rememberMeRequestAttribute cannot be null");
|
||||
}
|
||||
this.rememberMeRequestAttribute = rememberMeRequestAttribute;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -98,13 +98,11 @@ public class HeaderHttpSessionIdResolver implements HttpSessionIdResolver {
|
||||
@Override
|
||||
public List<String> resolveSessionIds(HttpServletRequest request) {
|
||||
String headerValue = request.getHeader(this.headerName);
|
||||
return (headerValue != null) ? Collections.singletonList(headerValue)
|
||||
: Collections.emptyList();
|
||||
return (headerValue != null) ? Collections.singletonList(headerValue) : Collections.emptyList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSessionId(HttpServletRequest request, HttpServletResponse response,
|
||||
String sessionId) {
|
||||
public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) {
|
||||
response.setHeader(this.headerName, sessionId);
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -65,11 +65,7 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
|
||||
this.servletContext = servletContext;
|
||||
}
|
||||
|
||||
public void setSession(S session) {
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
public S getSession() {
|
||||
S getSession() {
|
||||
return this.session;
|
||||
}
|
||||
|
||||
@@ -142,8 +138,8 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
|
||||
if (value != oldValue) {
|
||||
if (oldValue instanceof HttpSessionBindingListener) {
|
||||
try {
|
||||
((HttpSessionBindingListener) oldValue).valueUnbound(
|
||||
new HttpSessionBindingEvent(this, name, oldValue));
|
||||
((HttpSessionBindingListener) oldValue)
|
||||
.valueUnbound(new HttpSessionBindingEvent(this, name, oldValue));
|
||||
}
|
||||
catch (Throwable th) {
|
||||
logger.error("Error invoking session binding event listener", th);
|
||||
@@ -151,8 +147,7 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
|
||||
}
|
||||
if (value instanceof HttpSessionBindingListener) {
|
||||
try {
|
||||
((HttpSessionBindingListener) value)
|
||||
.valueBound(new HttpSessionBindingEvent(this, name, value));
|
||||
((HttpSessionBindingListener) value).valueBound(new HttpSessionBindingEvent(this, name, value));
|
||||
}
|
||||
catch (Throwable th) {
|
||||
logger.error("Error invoking session binding event listener", th);
|
||||
@@ -173,8 +168,7 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
|
||||
this.session.removeAttribute(name);
|
||||
if (oldValue instanceof HttpSessionBindingListener) {
|
||||
try {
|
||||
((HttpSessionBindingListener) oldValue)
|
||||
.valueUnbound(new HttpSessionBindingEvent(this, name, oldValue));
|
||||
((HttpSessionBindingListener) oldValue).valueUnbound(new HttpSessionBindingEvent(this, name, oldValue));
|
||||
}
|
||||
catch (Throwable th) {
|
||||
logger.error("Error invoking session binding event listener", th);
|
||||
@@ -193,20 +187,19 @@ class HttpSessionAdapter<S extends Session> implements HttpSession {
|
||||
this.invalidated = true;
|
||||
}
|
||||
|
||||
public void setNew(boolean isNew) {
|
||||
this.old = !isNew;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isNew() {
|
||||
checkState();
|
||||
return !this.old;
|
||||
}
|
||||
|
||||
void markNotNew() {
|
||||
this.old = true;
|
||||
}
|
||||
|
||||
private void checkState() {
|
||||
if (this.invalidated) {
|
||||
throw new IllegalStateException(
|
||||
"The HttpSession has already be invalidated.");
|
||||
throw new IllegalStateException("The HttpSession has already be invalidated.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -49,8 +49,7 @@ public interface HttpSessionIdResolver {
|
||||
* @param response the current response
|
||||
* @param sessionId the session id
|
||||
*/
|
||||
void setSessionId(HttpServletRequest request, HttpServletResponse response,
|
||||
String sessionId);
|
||||
void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId);
|
||||
|
||||
/**
|
||||
* Instruct the client to end the current session. This method is invoked when a
|
||||
|
||||
@@ -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.
|
||||
@@ -25,9 +25,6 @@ import javax.servlet.WriteListener;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.HttpServletResponseWrapper;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
/**
|
||||
* Base class for response wrappers which encapsulate the logic for handling an event when
|
||||
* the {@link javax.servlet.http.HttpServletResponse} is committed.
|
||||
@@ -36,7 +33,6 @@ import org.apache.commons.logging.LogFactory;
|
||||
* @since 1.0
|
||||
*/
|
||||
abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
|
||||
private final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private boolean disableOnCommitted;
|
||||
|
||||
@@ -68,6 +64,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);
|
||||
@@ -85,7 +87,7 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
|
||||
* {@link javax.servlet.http.HttpServletResponse} is committed. This can be useful in
|
||||
* the event that Async Web Requests are made.
|
||||
*/
|
||||
public void disableOnResponseCommitted() {
|
||||
private void disableOnResponseCommitted() {
|
||||
this.disableOnCommitted = true;
|
||||
}
|
||||
|
||||
@@ -204,13 +206,11 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
|
||||
/**
|
||||
* Adds the contentLengthToWrite to the total contentWritten size and checks to see if
|
||||
* the response should be written.
|
||||
*
|
||||
* @param contentLengthToWrite the size of the content that is about to be written.
|
||||
*/
|
||||
private void checkContentLength(long contentLengthToWrite) {
|
||||
this.contentWritten += contentLengthToWrite;
|
||||
boolean isBodyFullyWritten = this.contentLength > 0
|
||||
&& this.contentWritten >= this.contentLength;
|
||||
boolean isBodyFullyWritten = this.contentLength > 0 && this.contentWritten >= this.contentLength;
|
||||
int bufferSize = getBufferSize();
|
||||
boolean requiresFlush = bufferSize > 0 && this.contentWritten >= bufferSize;
|
||||
if (isBodyFullyWritten || requiresFlush) {
|
||||
@@ -234,9 +234,11 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
|
||||
* calling the prior to methods that commit the response. We delegate all methods to
|
||||
* the original {@link java.io.PrintWriter} to ensure that the behavior is as close to
|
||||
* the original {@link java.io.PrintWriter} as possible. See SEC-2039
|
||||
*
|
||||
* @author Rob Winch
|
||||
*/
|
||||
private class SaveContextPrintWriter extends PrintWriter {
|
||||
|
||||
private final PrintWriter delegate;
|
||||
|
||||
SaveContextPrintWriter(PrintWriter delegate) {
|
||||
@@ -466,6 +468,7 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
|
||||
trackContentLength(c);
|
||||
return this.delegate.append(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -477,6 +480,7 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
|
||||
* @author Rob Winch
|
||||
*/
|
||||
private class SaveContextServletOutputStream extends ServletOutputStream {
|
||||
|
||||
private final ServletOutputStream delegate;
|
||||
|
||||
SaveContextServletOutputStream(ServletOutputStream delegate) {
|
||||
@@ -634,5 +638,7 @@ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper {
|
||||
public void setWriteListener(WriteListener writeListener) {
|
||||
this.delegate.setWriteListener(writeListener);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -37,19 +37,18 @@ import javax.servlet.http.HttpServletResponse;
|
||||
* @since 1.0
|
||||
*/
|
||||
abstract class OncePerRequestFilter implements Filter {
|
||||
|
||||
/**
|
||||
* Suffix that gets appended to the filter name for the "already filtered" request
|
||||
* attribute.
|
||||
*/
|
||||
public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED";
|
||||
|
||||
private String alreadyFilteredAttributeName = getClass().getName()
|
||||
.concat(ALREADY_FILTERED_SUFFIX);
|
||||
private String alreadyFilteredAttributeName = getClass().getName().concat(ALREADY_FILTERED_SUFFIX);
|
||||
|
||||
/**
|
||||
* This {@code doFilter} implementation stores a request attribute for
|
||||
* "already filtered", proceeding without filtering again if the attribute is already
|
||||
* there.
|
||||
* This {@code doFilter} implementation stores a request attribute for "already
|
||||
* filtered", proceeding without filtering again if the attribute is already there.
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param filterChain the filter chain
|
||||
@@ -57,24 +56,22 @@ abstract class OncePerRequestFilter implements Filter {
|
||||
* @throws IOException in case of I/O operation exception
|
||||
*/
|
||||
@Override
|
||||
public final void doFilter(ServletRequest request, ServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
|
||||
if (!(request instanceof HttpServletRequest)
|
||||
|| !(response instanceof HttpServletResponse)) {
|
||||
throw new ServletException(
|
||||
"OncePerRequestFilter just supports HTTP requests");
|
||||
if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) {
|
||||
throw new ServletException("OncePerRequestFilter just supports HTTP requests");
|
||||
}
|
||||
HttpServletRequest httpRequest = (HttpServletRequest) request;
|
||||
HttpServletResponse httpResponse = (HttpServletResponse) response;
|
||||
String alreadyFilteredAttributeName = this.alreadyFilteredAttributeName;
|
||||
alreadyFilteredAttributeName = updateForErrorDispatch(
|
||||
alreadyFilteredAttributeName, request);
|
||||
boolean hasAlreadyFilteredAttribute = request
|
||||
.getAttribute(alreadyFilteredAttributeName) != null;
|
||||
String alreadyFilteredAttributeName = getAlreadyFilteredAttributeName();
|
||||
boolean hasAlreadyFilteredAttribute = request.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);
|
||||
}
|
||||
@@ -91,15 +88,39 @@ abstract class OncePerRequestFilter implements Filter {
|
||||
}
|
||||
}
|
||||
|
||||
private String updateForErrorDispatch(String alreadyFilteredAttributeName,
|
||||
ServletRequest request) {
|
||||
// Jetty does ERROR dispatch within sendError, so request attribute is still present
|
||||
// Use a separate attribute for ERROR dispatches
|
||||
if (DispatcherType.ERROR.equals(request.getDispatcherType())
|
||||
&& request.getAttribute(alreadyFilteredAttributeName) != null) {
|
||||
return alreadyFilteredAttributeName + ".ERROR";
|
||||
}
|
||||
return 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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -108,7 +129,6 @@ abstract class OncePerRequestFilter implements Filter {
|
||||
* <p>
|
||||
* Provides HttpServletRequest and HttpServletResponse arguments instead of the
|
||||
* default ServletRequest and ServletResponse ones.
|
||||
*
|
||||
* @param request the request
|
||||
* @param response the response
|
||||
* @param filterChain the FilterChain
|
||||
@@ -116,9 +136,8 @@ abstract class OncePerRequestFilter implements Filter {
|
||||
* @throws IOException thrown when an I/O exception of some sort has occurred
|
||||
* @see Filter#doFilter
|
||||
*/
|
||||
protected abstract void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException;
|
||||
protected abstract void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException;
|
||||
|
||||
@Override
|
||||
public void init(FilterConfig config) {
|
||||
@@ -127,4 +146,5 @@ abstract class OncePerRequestFilter implements Filter {
|
||||
@Override
|
||||
public void destroy() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -40,6 +40,7 @@ import org.springframework.web.context.ServletContextAware;
|
||||
*/
|
||||
public class SessionEventHttpSessionListenerAdapter
|
||||
implements ApplicationListener<AbstractSessionEvent>, ServletContextAware {
|
||||
|
||||
private final List<HttpSessionListener> listeners;
|
||||
|
||||
private ServletContext context;
|
||||
@@ -75,8 +76,7 @@ public class SessionEventHttpSessionListenerAdapter
|
||||
|
||||
private HttpSessionEvent createHttpSessionEvent(AbstractSessionEvent event) {
|
||||
Session session = event.getSession();
|
||||
HttpSession httpSession = new HttpSessionAdapter<>(session,
|
||||
this.context);
|
||||
HttpSession httpSession = new HttpSessionAdapter<>(session, this.context);
|
||||
return new HttpSessionEvent(httpSession);
|
||||
}
|
||||
|
||||
@@ -91,4 +91,5 @@ public class SessionEventHttpSessionListenerAdapter
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.context = servletContext;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -59,6 +59,7 @@ import org.springframework.session.SessionRepository;
|
||||
* . The default is to look in a cookie named SESSION.</li>
|
||||
* <li>The session id of newly created {@link org.springframework.session.Session} is sent
|
||||
* to the client using
|
||||
* {@link HttpSessionIdResolver#setSessionId(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, String)}
|
||||
* <li>The client is notified that the session id is no longer valid with
|
||||
* {@link HttpSessionIdResolver#expireSession(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)}
|
||||
* </li>
|
||||
@@ -79,25 +80,21 @@ import org.springframework.session.SessionRepository;
|
||||
@Order(SessionRepositoryFilter.DEFAULT_ORDER)
|
||||
public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFilter {
|
||||
|
||||
private static final String SESSION_LOGGER_NAME = SessionRepositoryFilter.class
|
||||
.getName().concat(".SESSION_LOGGER");
|
||||
private static final String SESSION_LOGGER_NAME = SessionRepositoryFilter.class.getName().concat(".SESSION_LOGGER");
|
||||
|
||||
private static final Log SESSION_LOGGER = LogFactory.getLog(SESSION_LOGGER_NAME);
|
||||
|
||||
/**
|
||||
* The session repository request attribute name.
|
||||
*/
|
||||
public static final String SESSION_REPOSITORY_ATTR = SessionRepository.class
|
||||
.getName();
|
||||
public static final String SESSION_REPOSITORY_ATTR = SessionRepository.class.getName();
|
||||
|
||||
/**
|
||||
* Invalid session id (not backed by the session repository) request attribute name.
|
||||
*/
|
||||
public static final String INVALID_SESSION_ID_ATTR = SESSION_REPOSITORY_ATTR
|
||||
+ ".invalidSessionId";
|
||||
public static final String INVALID_SESSION_ID_ATTR = SESSION_REPOSITORY_ATTR + ".invalidSessionId";
|
||||
|
||||
private static final String CURRENT_SESSION_ATTR = SESSION_REPOSITORY_ATTR
|
||||
+ ".CURRENT_SESSION";
|
||||
private static final String CURRENT_SESSION_ATTR = SESSION_REPOSITORY_ATTR + ".CURRENT_SESSION";
|
||||
|
||||
/**
|
||||
* The default filter order.
|
||||
@@ -110,7 +107,6 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param sessionRepository the <code>SessionRepository</code> to use. Cannot be null.
|
||||
*/
|
||||
public SessionRepositoryFilter(SessionRepository<S> sessionRepository) {
|
||||
@@ -123,7 +119,6 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
/**
|
||||
* Sets the {@link HttpSessionIdResolver} to be used. The default is a
|
||||
* {@link CookieHttpSessionIdResolver}.
|
||||
*
|
||||
* @param httpSessionIdResolver the {@link HttpSessionIdResolver} to use. Cannot be
|
||||
* null.
|
||||
*/
|
||||
@@ -135,15 +130,13 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response, FilterChain filterChain)
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
request.setAttribute(SESSION_REPOSITORY_ATTR, this.sessionRepository);
|
||||
|
||||
SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(
|
||||
request, response);
|
||||
SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(
|
||||
wrappedRequest, response);
|
||||
SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response);
|
||||
SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(wrappedRequest,
|
||||
response);
|
||||
|
||||
try {
|
||||
filterChain.doFilter(wrappedRequest, wrappedResponse);
|
||||
@@ -153,14 +146,19 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
}
|
||||
}
|
||||
|
||||
@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.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 1.0
|
||||
*/
|
||||
private final class SessionRepositoryResponseWrapper
|
||||
extends OnCommittedResponseWrapper {
|
||||
private final class SessionRepositoryResponseWrapper extends OnCommittedResponseWrapper {
|
||||
|
||||
private final SessionRepositoryRequestWrapper request;
|
||||
|
||||
@@ -169,8 +167,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
* @param request the request to be wrapped
|
||||
* @param response the response to be wrapped
|
||||
*/
|
||||
SessionRepositoryResponseWrapper(SessionRepositoryRequestWrapper request,
|
||||
HttpServletResponse response) {
|
||||
SessionRepositoryResponseWrapper(SessionRepositoryRequestWrapper request, HttpServletResponse response) {
|
||||
super(response);
|
||||
if (request == null) {
|
||||
throw new IllegalArgumentException("request cannot be null");
|
||||
@@ -182,6 +179,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
protected void onResponseCommitted() {
|
||||
this.request.commitSession();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -192,8 +190,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
* @author Rob Winch
|
||||
* @since 1.0
|
||||
*/
|
||||
private final class SessionRepositoryRequestWrapper
|
||||
extends HttpServletRequestWrapper {
|
||||
private final class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper {
|
||||
|
||||
private final HttpServletResponse response;
|
||||
|
||||
@@ -207,8 +204,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
|
||||
private boolean requestedSessionInvalidated;
|
||||
|
||||
private SessionRepositoryRequestWrapper(HttpServletRequest request,
|
||||
HttpServletResponse response) {
|
||||
private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletResponse response) {
|
||||
super(request);
|
||||
this.response = response;
|
||||
}
|
||||
@@ -221,8 +217,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
HttpSessionWrapper wrappedSession = getCurrentSession();
|
||||
if (wrappedSession == null) {
|
||||
if (isInvalidateClientSession()) {
|
||||
SessionRepositoryFilter.this.httpSessionIdResolver.expireSession(this,
|
||||
this.response);
|
||||
SessionRepositoryFilter.this.httpSessionIdResolver.expireSession(this, this.response);
|
||||
}
|
||||
}
|
||||
else {
|
||||
@@ -230,10 +225,8 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
clearRequestedSessionCache();
|
||||
SessionRepositoryFilter.this.sessionRepository.save(session);
|
||||
String sessionId = session.getId();
|
||||
if (!isRequestedSessionIdValid()
|
||||
|| !sessionId.equals(getRequestedSessionId())) {
|
||||
SessionRepositoryFilter.this.httpSessionIdResolver.setSessionId(this,
|
||||
this.response, sessionId);
|
||||
if (!isRequestedSessionIdValid() || !sessionId.equals(getRequestedSessionId())) {
|
||||
SessionRepositoryFilter.this.httpSessionIdResolver.setSessionId(this, this.response, sessionId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -300,7 +293,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
requestedSession.setLastAccessedTime(Instant.now());
|
||||
this.requestedSessionIdValid = true;
|
||||
currentSession = new HttpSessionWrapper(requestedSession, getServletContext());
|
||||
currentSession.setNew(false);
|
||||
currentSession.markNotNew();
|
||||
setCurrentSession(currentSession);
|
||||
return currentSession;
|
||||
}
|
||||
@@ -317,12 +310,15 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
if (!create) {
|
||||
return null;
|
||||
}
|
||||
if (SessionRepositoryFilter.this.httpSessionIdResolver instanceof CookieHttpSessionIdResolver
|
||||
&& this.response.isCommitted()) {
|
||||
throw new IllegalStateException("Cannot create a session after the response has been committed");
|
||||
}
|
||||
if (SESSION_LOGGER.isDebugEnabled()) {
|
||||
SESSION_LOGGER.debug(
|
||||
"A new session was created. To help you troubleshoot where the session was created we provided a StackTrace (this is not an error). You can prevent this from appearing by disabling DEBUG logging for "
|
||||
+ SESSION_LOGGER_NAME,
|
||||
new RuntimeException(
|
||||
"For debugging purposes only (not an error)"));
|
||||
new RuntimeException("For debugging purposes only (not an error)"));
|
||||
}
|
||||
S session = SessionRepositoryFilter.this.sessionRepository.createSession();
|
||||
session.setLastAccessedTime(Instant.now());
|
||||
@@ -352,14 +348,12 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
|
||||
private S getRequestedSession() {
|
||||
if (!this.requestedSessionCached) {
|
||||
List<String> sessionIds = SessionRepositoryFilter.this.httpSessionIdResolver
|
||||
.resolveSessionIds(this);
|
||||
List<String> sessionIds = SessionRepositoryFilter.this.httpSessionIdResolver.resolveSessionIds(this);
|
||||
for (String sessionId : sessionIds) {
|
||||
if (this.requestedSessionId == null) {
|
||||
this.requestedSessionId = sessionId;
|
||||
}
|
||||
S session = SessionRepositoryFilter.this.sessionRepository
|
||||
.findById(sessionId);
|
||||
S session = SessionRepositoryFilter.this.sessionRepository.findById(sessionId);
|
||||
if (session != null) {
|
||||
this.requestedSession = session;
|
||||
this.requestedSessionId = sessionId;
|
||||
@@ -397,6 +391,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
clearRequestedSessionCache();
|
||||
SessionRepositoryFilter.this.sessionRepository.deleteById(getId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -404,8 +399,7 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
*
|
||||
* @since 1.3.4
|
||||
*/
|
||||
private final class SessionCommittingRequestDispatcher
|
||||
implements RequestDispatcher {
|
||||
private final class SessionCommittingRequestDispatcher implements RequestDispatcher {
|
||||
|
||||
private final RequestDispatcher delegate;
|
||||
|
||||
@@ -414,14 +408,12 @@ public class SessionRepositoryFilter<S extends Session> extends OncePerRequestFi
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forward(ServletRequest request, ServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException {
|
||||
this.delegate.forward(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void include(ServletRequest request, ServletResponse response)
|
||||
throws ServletException, IOException {
|
||||
public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException {
|
||||
SessionRepositoryRequestWrapper.this.commitSession();
|
||||
this.delegate.include(request, response);
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -61,12 +61,14 @@ public class SpringSessionWebSessionStore<S extends Session> implements WebSessi
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the {@link Clock} to use to set lastAccessTime on every created
|
||||
* session and to calculate if it is expired.
|
||||
* <p>This may be useful to align to different timezone or to set the clock
|
||||
* back in a test, e.g. {@code Clock.offset(clock, Duration.ofMinutes(-31))}
|
||||
* in order to simulate session expiration.
|
||||
* <p>By default this is {@code Clock.system(ZoneId.of("GMT"))}.
|
||||
* Configure the {@link Clock} to use to set lastAccessTime on every created session
|
||||
* and to calculate if it is expired.
|
||||
* <p>
|
||||
* This may be useful to align to different timezone or to set the clock back in a
|
||||
* test, e.g. {@code Clock.offset(clock, Duration.ofMinutes(-31))} in order to
|
||||
* simulate session expiration.
|
||||
* <p>
|
||||
* By default this is {@code Clock.system(ZoneId.of("GMT"))}.
|
||||
* @param clock the clock to use
|
||||
*/
|
||||
public void setClock(Clock clock) {
|
||||
@@ -90,8 +92,7 @@ public class SpringSessionWebSessionStore<S extends Session> implements WebSessi
|
||||
@Override
|
||||
public Mono<WebSession> retrieveSession(String sessionId) {
|
||||
return this.sessions.findById(sessionId)
|
||||
.doOnNext((session) -> session.setLastAccessedTime(this.clock.instant()))
|
||||
.map(this::existingSession);
|
||||
.doOnNext((session) -> session.setLastAccessedTime(this.clock.instant())).map(this::existingSession);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -133,8 +134,7 @@ public class SpringSessionWebSessionStore<S extends Session> implements WebSessi
|
||||
@Override
|
||||
public Mono<Void> changeSessionId() {
|
||||
return Mono.defer(() -> {
|
||||
this.session
|
||||
.changeSessionId();
|
||||
this.session.changeSessionId();
|
||||
return save();
|
||||
});
|
||||
}
|
||||
@@ -152,8 +152,7 @@ public class SpringSessionWebSessionStore<S extends Session> implements WebSessi
|
||||
@Override
|
||||
public boolean isStarted() {
|
||||
State value = this.state.get();
|
||||
return (State.STARTED.equals(value)
|
||||
|| (State.NEW.equals(value) && !getAttributes().isEmpty()));
|
||||
return (State.STARTED.equals(value) || (State.NEW.equals(value) && !getAttributes().isEmpty()));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -198,10 +197,13 @@ public class SpringSessionWebSessionStore<S extends Session> implements WebSessi
|
||||
public void setMaxIdleTime(Duration maxIdleTime) {
|
||||
this.session.setMaxInactiveInterval(maxIdleTime);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private enum State {
|
||||
|
||||
NEW, STARTED, EXPIRED
|
||||
|
||||
}
|
||||
|
||||
private static class SpringSessionMap implements Map<String, Object> {
|
||||
@@ -226,8 +228,7 @@ public class SpringSessionWebSessionStore<S extends Session> implements WebSessi
|
||||
|
||||
@Override
|
||||
public boolean containsKey(Object key) {
|
||||
return key instanceof String
|
||||
&& this.session.getAttributeNames().contains(key);
|
||||
return key instanceof String && this.session.getAttributeNames().contains(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -346,5 +347,7 @@ public class SpringSessionWebSessionStore<S extends Session> implements WebSessi
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -93,8 +93,7 @@ public abstract class AbstractSessionWebSocketMessageBrokerConfigurer<S extends
|
||||
public final void registerStompEndpoints(StompEndpointRegistry registry) {
|
||||
if (registry instanceof WebMvcStompEndpointRegistry) {
|
||||
WebMvcStompEndpointRegistry mvcRegistry = (WebMvcStompEndpointRegistry) registry;
|
||||
configureStompEndpoints(new SessionStompEndpointRegistry(mvcRegistry,
|
||||
sessionRepositoryInterceptor()));
|
||||
configureStompEndpoints(new SessionStompEndpointRegistry(mvcRegistry, sessionRepositoryInterceptor()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -102,7 +101,6 @@ public abstract class AbstractSessionWebSocketMessageBrokerConfigurer<S extends
|
||||
* Register STOMP endpoints mapping each to a specific URL and (optionally) enabling
|
||||
* and configuring SockJS fallback options with a
|
||||
* {@link SessionRepositoryMessageInterceptor} automatically added as an interceptor.
|
||||
*
|
||||
* @param registry the {@link StompEndpointRegistry} which automatically has a
|
||||
* {@link SessionRepositoryMessageInterceptor} added to it.
|
||||
*/
|
||||
@@ -133,19 +131,19 @@ public abstract class AbstractSessionWebSocketMessageBrokerConfigurer<S extends
|
||||
* A {@link StompEndpointRegistry} that applies {@link HandshakeInterceptor}.
|
||||
*/
|
||||
static class SessionStompEndpointRegistry implements StompEndpointRegistry {
|
||||
|
||||
private final WebMvcStompEndpointRegistry registry;
|
||||
|
||||
private final HandshakeInterceptor interceptor;
|
||||
|
||||
SessionStompEndpointRegistry(WebMvcStompEndpointRegistry registry,
|
||||
HandshakeInterceptor interceptor) {
|
||||
SessionStompEndpointRegistry(WebMvcStompEndpointRegistry registry, HandshakeInterceptor interceptor) {
|
||||
this.registry = registry;
|
||||
this.interceptor = interceptor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public StompWebSocketEndpointRegistration addEndpoint(String... paths) {
|
||||
StompWebSocketEndpointRegistration endpoints = this.registry
|
||||
.addEndpoint(paths);
|
||||
StompWebSocketEndpointRegistration endpoints = this.registry.addEndpoint(paths);
|
||||
endpoints.addInterceptors(this.interceptor);
|
||||
return endpoints;
|
||||
}
|
||||
@@ -161,9 +159,10 @@ public abstract class AbstractSessionWebSocketMessageBrokerConfigurer<S extends
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebMvcStompEndpointRegistry setErrorHandler(
|
||||
StompSubProtocolErrorHandler errorHandler) {
|
||||
public WebMvcStompEndpointRegistry setErrorHandler(StompSubProtocolErrorHandler errorHandler) {
|
||||
return this.registry.setErrorHandler(errorHandler);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -44,4 +44,5 @@ public class SessionConnectEvent extends ApplicationEvent {
|
||||
public WebSocketSession getWebSocketSession() {
|
||||
return this.webSocketSession;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -38,24 +38,19 @@ import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory;
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @since 1.0
|
||||
*
|
||||
* @see WebSocketRegistryListener
|
||||
*/
|
||||
public final class WebSocketConnectHandlerDecoratorFactory
|
||||
implements WebSocketHandlerDecoratorFactory {
|
||||
public final class WebSocketConnectHandlerDecoratorFactory implements WebSocketHandlerDecoratorFactory {
|
||||
|
||||
private static final Log logger = LogFactory
|
||||
.getLog(WebSocketConnectHandlerDecoratorFactory.class);
|
||||
private static final Log logger = LogFactory.getLog(WebSocketConnectHandlerDecoratorFactory.class);
|
||||
|
||||
private final ApplicationEventPublisher eventPublisher;
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param eventPublisher the {@link ApplicationEventPublisher} to use. Cannot be null.
|
||||
*/
|
||||
public WebSocketConnectHandlerDecoratorFactory(
|
||||
ApplicationEventPublisher eventPublisher) {
|
||||
public WebSocketConnectHandlerDecoratorFactory(ApplicationEventPublisher eventPublisher) {
|
||||
Assert.notNull(eventPublisher, "eventPublisher cannot be null");
|
||||
this.eventPublisher = eventPublisher;
|
||||
}
|
||||
@@ -72,8 +67,7 @@ public final class WebSocketConnectHandlerDecoratorFactory
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession wsSession)
|
||||
throws Exception {
|
||||
public void afterConnectionEstablished(WebSocketSession wsSession) throws Exception {
|
||||
super.afterConnectionEstablished(wsSession);
|
||||
|
||||
publishEvent(new SessionConnectEvent(this, wsSession));
|
||||
@@ -81,12 +75,13 @@ public final class WebSocketConnectHandlerDecoratorFactory
|
||||
|
||||
private void publishEvent(ApplicationEvent event) {
|
||||
try {
|
||||
WebSocketConnectHandlerDecoratorFactory.this.eventPublisher
|
||||
.publishEvent(event);
|
||||
WebSocketConnectHandlerDecoratorFactory.this.eventPublisher.publishEvent(event);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
logger.error("Error publishing " + event + ".", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -41,18 +41,15 @@ import org.springframework.web.socket.messaging.SessionDisconnectEvent;
|
||||
* {@link WebSocketSession} is closed.
|
||||
* </p>
|
||||
*
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Mark Anderson
|
||||
* @since 1.0
|
||||
*/
|
||||
public final class WebSocketRegistryListener
|
||||
implements ApplicationListener<ApplicationEvent> {
|
||||
public final class WebSocketRegistryListener implements ApplicationListener<ApplicationEvent> {
|
||||
|
||||
private static final Log logger = LogFactory.getLog(WebSocketRegistryListener.class);
|
||||
|
||||
static final CloseStatus SESSION_EXPIRED_STATUS = new CloseStatus(
|
||||
CloseStatus.POLICY_VIOLATION.getCode(),
|
||||
static final CloseStatus SESSION_EXPIRED_STATUS = new CloseStatus(CloseStatus.POLICY_VIOLATION.getCode(),
|
||||
"This connection was established under an authenticated HTTP Session that has expired");
|
||||
|
||||
private final ConcurrentHashMap<String, Map<String, WebSocketSession>> httpSessionIdToWsSessions = new ConcurrentHashMap<>();
|
||||
@@ -72,8 +69,7 @@ public final class WebSocketRegistryListener
|
||||
Map<String, Object> sessionAttributes = SimpMessageHeaderAccessor
|
||||
.getSessionAttributes(e.getMessage().getHeaders());
|
||||
String httpSessionId = (sessionAttributes != null)
|
||||
? SessionRepositoryMessageInterceptor.getSessionId(sessionAttributes)
|
||||
: null;
|
||||
? SessionRepositoryMessageInterceptor.getSessionId(sessionAttributes) : null;
|
||||
afterConnectionClosed(httpSessionId, e.getSessionId());
|
||||
}
|
||||
}
|
||||
@@ -98,8 +94,7 @@ public final class WebSocketRegistryListener
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, WebSocketSession> sessions = this.httpSessionIdToWsSessions
|
||||
.get(httpSessionId);
|
||||
Map<String, WebSocketSession> sessions = this.httpSessionIdToWsSessions.get(httpSessionId);
|
||||
if (sessions != null) {
|
||||
boolean result = sessions.remove(wsSessionId) != null;
|
||||
if (logger.isDebugEnabled()) {
|
||||
@@ -108,16 +103,15 @@ public final class WebSocketRegistryListener
|
||||
if (sessions.isEmpty()) {
|
||||
this.httpSessionIdToWsSessions.remove(httpSessionId);
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Removed the corresponding HTTP Session for "
|
||||
+ wsSessionId + " since it contained no WebSocket mappings");
|
||||
logger.debug("Removed the corresponding HTTP Session for " + wsSessionId
|
||||
+ " since it contained no WebSocket mappings");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void registerWsSession(String httpSessionId, WebSocketSession wsSession) {
|
||||
Map<String, WebSocketSession> sessions = this.httpSessionIdToWsSessions
|
||||
.get(httpSessionId);
|
||||
Map<String, WebSocketSession> sessions = this.httpSessionIdToWsSessions.get(httpSessionId);
|
||||
if (sessions == null) {
|
||||
sessions = new ConcurrentHashMap<>();
|
||||
this.httpSessionIdToWsSessions.putIfAbsent(httpSessionId, sessions);
|
||||
@@ -127,25 +121,22 @@ public final class WebSocketRegistryListener
|
||||
}
|
||||
|
||||
private void closeWsSessions(String httpSessionId) {
|
||||
Map<String, WebSocketSession> sessionsToClose = this.httpSessionIdToWsSessions
|
||||
.remove(httpSessionId);
|
||||
Map<String, WebSocketSession> sessionsToClose = this.httpSessionIdToWsSessions.remove(httpSessionId);
|
||||
if (sessionsToClose == null) {
|
||||
return;
|
||||
}
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(
|
||||
"Closing WebSocket connections associated to expired HTTP Session "
|
||||
+ httpSessionId);
|
||||
logger.debug("Closing WebSocket connections associated to expired HTTP Session " + httpSessionId);
|
||||
}
|
||||
for (WebSocketSession toClose : sessionsToClose.values()) {
|
||||
try {
|
||||
toClose.close(SESSION_EXPIRED_STATUS);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.debug(
|
||||
"Failed to close WebSocketSession (this is nothing to worry about but for debugging only)",
|
||||
logger.debug("Failed to close WebSocketSession (this is nothing to worry about but for debugging only)",
|
||||
ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
@@ -72,15 +72,13 @@ public final class SessionRepositoryMessageInterceptor<S extends Session>
|
||||
|
||||
/**
|
||||
* Creates a new instance.
|
||||
*
|
||||
* @param sessionRepository the {@link SessionRepository} to use. Cannot be null.
|
||||
*/
|
||||
public SessionRepositoryMessageInterceptor(SessionRepository<S> sessionRepository) {
|
||||
Assert.notNull(sessionRepository, "sessionRepository cannot be null");
|
||||
this.sessionRepository = sessionRepository;
|
||||
this.matchingMessageTypes = EnumSet.of(SimpMessageType.CONNECT,
|
||||
SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE,
|
||||
SimpMessageType.UNSUBSCRIBE);
|
||||
this.matchingMessageTypes = EnumSet.of(SimpMessageType.CONNECT, SimpMessageType.MESSAGE,
|
||||
SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -94,14 +92,12 @@ public final class SessionRepositoryMessageInterceptor<S extends Session>
|
||||
* The default is: SimpMessageType.CONNECT, SimpMessageType.MESSAGE,
|
||||
* SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE.
|
||||
* </p>
|
||||
*
|
||||
* @param matchingMessageTypes the {@link SimpMessageType} to match on in
|
||||
* {@link #preSend(Message, MessageChannel)}, else the {@link Message} is continued
|
||||
* without accessing or updating the {@link Session}
|
||||
*/
|
||||
public void setMatchingMessageTypes(Set<SimpMessageType> matchingMessageTypes) {
|
||||
Assert.notEmpty(matchingMessageTypes,
|
||||
"matchingMessageTypes cannot be null or empty");
|
||||
Assert.notEmpty(matchingMessageTypes, "matchingMessageTypes cannot be null or empty");
|
||||
this.matchingMessageTypes = matchingMessageTypes;
|
||||
}
|
||||
|
||||
@@ -110,16 +106,12 @@ public final class SessionRepositoryMessageInterceptor<S extends Session>
|
||||
if (message == null) {
|
||||
return message;
|
||||
}
|
||||
SimpMessageType messageType = SimpMessageHeaderAccessor
|
||||
.getMessageType(message.getHeaders());
|
||||
SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(message.getHeaders());
|
||||
if (!this.matchingMessageTypes.contains(messageType)) {
|
||||
return message;
|
||||
}
|
||||
Map<String, Object> sessionHeaders = SimpMessageHeaderAccessor
|
||||
.getSessionAttributes(message.getHeaders());
|
||||
String sessionId = (sessionHeaders != null)
|
||||
? (String) sessionHeaders.get(SPRING_SESSION_ID_ATTR_NAME)
|
||||
: null;
|
||||
Map<String, Object> sessionHeaders = SimpMessageHeaderAccessor.getSessionAttributes(message.getHeaders());
|
||||
String sessionId = (sessionHeaders != null) ? (String) sessionHeaders.get(SPRING_SESSION_ID_ATTR_NAME) : null;
|
||||
if (sessionId != null) {
|
||||
S session = this.sessionRepository.findById(sessionId);
|
||||
if (session != null) {
|
||||
@@ -132,8 +124,8 @@ public final class SessionRepositoryMessageInterceptor<S extends Session>
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response,
|
||||
WebSocketHandler wsHandler, Map<String, Object> attributes) throws Exception {
|
||||
public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
|
||||
Map<String, Object> attributes) {
|
||||
if (request instanceof ServletServerHttpRequest) {
|
||||
ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request;
|
||||
HttpSession session = servletRequest.getServletRequest().getSession(false);
|
||||
@@ -145,8 +137,8 @@ public final class SessionRepositoryMessageInterceptor<S extends Session>
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response,
|
||||
WebSocketHandler wsHandler, Exception exception) {
|
||||
public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler,
|
||||
Exception exception) {
|
||||
}
|
||||
|
||||
public static String getSessionId(Map<String, Object> attributes) {
|
||||
@@ -156,4 +148,5 @@ public final class SessionRepositoryMessageInterceptor<S extends Session>
|
||||
public static void setSessionId(Map<String, Object> attributes, String sessionId) {
|
||||
attributes.put(SPRING_SESSION_ID_ATTR_NAME, sessionId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link DelegatingIndexResolver}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
class DelegatingIndexResolverTests {
|
||||
|
||||
private DelegatingIndexResolver<MapSession> indexResolver;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.indexResolver = new DelegatingIndexResolver<>(new TestIndexResolver("one"), new TestIndexResolver("two"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolve() {
|
||||
MapSession session = new MapSession();
|
||||
session.setAttribute("one", "first");
|
||||
session.setAttribute("two", "second");
|
||||
Map<String, String> indexes = this.indexResolver.resolveIndexesFor(session);
|
||||
assertThat(indexes).hasSize(2);
|
||||
assertThat(indexes.get("one")).isEqualTo("first");
|
||||
assertThat(indexes.get("two")).isEqualTo("second");
|
||||
}
|
||||
|
||||
private static class TestIndexResolver implements IndexResolver<MapSession> {
|
||||
|
||||
private final String supportedIndex;
|
||||
|
||||
TestIndexResolver(String supportedIndex) {
|
||||
this.supportedIndex = supportedIndex;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> resolveIndexesFor(MapSession session) {
|
||||
return Collections.singletonMap(this.supportedIndex, session.getAttribute(this.supportedIndex));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,20 +29,20 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* Tests for {@link MapSessionRepository}.
|
||||
*/
|
||||
public class MapSessionRepositoryTests {
|
||||
class MapSessionRepositoryTests {
|
||||
|
||||
private MapSessionRepository repository;
|
||||
|
||||
private MapSession session;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.repository = new MapSessionRepository(new ConcurrentHashMap<>());
|
||||
this.session = new MapSession();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getSessionExpired() {
|
||||
void getSessionExpired() {
|
||||
this.session.setMaxInactiveInterval(Duration.ofSeconds(1));
|
||||
this.session.setLastAccessedTime(Instant.now().minus(5, ChronoUnit.MINUTES));
|
||||
this.repository.save(this.session);
|
||||
@@ -51,29 +51,25 @@ public class MapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionDefaultExpiration() {
|
||||
void createSessionDefaultExpiration() {
|
||||
Session session = this.repository.createSession();
|
||||
|
||||
assertThat(session).isInstanceOf(MapSession.class);
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionCustomDefaultExpiration() {
|
||||
final Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval()
|
||||
.plusSeconds(10);
|
||||
this.repository.setDefaultMaxInactiveInterval(
|
||||
(int) expectedMaxInterval.getSeconds());
|
||||
void createSessionCustomDefaultExpiration() {
|
||||
final Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval().plusSeconds(10);
|
||||
this.repository.setDefaultMaxInactiveInterval((int) expectedMaxInterval.getSeconds());
|
||||
|
||||
Session session = this.repository.createSession();
|
||||
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(expectedMaxInterval);
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(expectedMaxInterval);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenNotYetSaved() {
|
||||
void changeSessionIdWhenNotYetSaved() {
|
||||
MapSession createSession = this.repository.createSession();
|
||||
|
||||
String originalId = createSession.getId();
|
||||
@@ -86,7 +82,7 @@ public class MapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSaved() {
|
||||
void changeSessionIdWhenSaved() {
|
||||
MapSession createSession = this.repository.createSession();
|
||||
|
||||
this.repository.save(createSession);
|
||||
@@ -101,7 +97,7 @@ public class MapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test // gh-1120
|
||||
public void getAttributeNamesAndRemove() {
|
||||
void getAttributeNamesAndRemove() {
|
||||
MapSession session = this.repository.createSession();
|
||||
session.setAttribute("attribute1", "value1");
|
||||
session.setAttribute("attribute2", "value2");
|
||||
|
||||
@@ -26,38 +26,37 @@ import org.junit.jupiter.api.Test;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException;
|
||||
|
||||
public class MapSessionTests {
|
||||
class MapSessionTests {
|
||||
|
||||
private MapSession session;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.session = new MapSession();
|
||||
this.session.setLastAccessedTime(Instant.ofEpochMilli(1413258262962L));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorNullSession() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new MapSession((Session) null))
|
||||
void constructorNullSession() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new MapSession((Session) null))
|
||||
.withMessage("session cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAttributeWhenNullThenNull() {
|
||||
void getAttributeWhenNullThenNull() {
|
||||
String result = this.session.getAttribute("attrName");
|
||||
assertThat(result).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAttributeOrDefaultWhenNullThenDefaultValue() {
|
||||
void getAttributeOrDefaultWhenNullThenDefaultValue() {
|
||||
String defaultValue = "default";
|
||||
String result = this.session.getAttributeOrDefault("attrName", defaultValue);
|
||||
assertThat(result).isEqualTo(defaultValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAttributeOrDefaultWhenNotNullThenDefaultValue() {
|
||||
void getAttributeOrDefaultWhenNotNullThenDefaultValue() {
|
||||
String defaultValue = "default";
|
||||
String attrValue = "value";
|
||||
String attrName = "attrName";
|
||||
@@ -69,14 +68,13 @@ public class MapSessionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequiredAttributeWhenNullThenException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.session.getRequiredAttribute("attrName"))
|
||||
void getRequiredAttributeWhenNullThenException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.session.getRequiredAttribute("attrName"))
|
||||
.withMessage("Required attribute 'attrName' is missing.");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequiredAttributeWhenNotNullThenReturns() {
|
||||
void getRequiredAttributeWhenNotNullThenReturns() {
|
||||
String attrValue = "value";
|
||||
String attrName = "attrName";
|
||||
this.session.setAttribute(attrName, attrValue);
|
||||
@@ -90,7 +88,7 @@ public class MapSessionTests {
|
||||
* Ensure conforms to the javadoc of {@link Session}
|
||||
*/
|
||||
@Test
|
||||
public void setAttributeNullObjectRemoves() {
|
||||
void setAttributeNullObjectRemoves() {
|
||||
String attr = "attr";
|
||||
this.session.setAttribute(attr, new Object());
|
||||
this.session.setAttribute(attr, null);
|
||||
@@ -98,43 +96,43 @@ public class MapSessionTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsNonSessionFalse() {
|
||||
void equalsNonSessionFalse() {
|
||||
assertThat(this.session.equals(new Object())).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void equalsCustomSession() {
|
||||
void equalsCustomSession() {
|
||||
CustomSession other = new CustomSession();
|
||||
this.session.setId(other.getId());
|
||||
assertThat(this.session.equals(other)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void hashCodeEqualsIdHashCode() {
|
||||
void hashCodeEqualsIdHashCode() {
|
||||
this.session.setId("constantId");
|
||||
assertThat(this.session.hashCode()).isEqualTo(this.session.getId().hashCode());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isExpiredExact() {
|
||||
void isExpiredExact() {
|
||||
Instant now = Instant.ofEpochMilli(1413260062962L);
|
||||
assertThat(this.session.isExpired(now)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isExpiredOneMsTooSoon() {
|
||||
void isExpiredOneMsTooSoon() {
|
||||
Instant now = Instant.ofEpochMilli(1413260062961L);
|
||||
assertThat(this.session.isExpired(now)).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isExpiredOneMsAfter() {
|
||||
void isExpiredOneMsAfter() {
|
||||
Instant now = Instant.ofEpochMilli(1413260062963L);
|
||||
assertThat(this.session.isExpired(now)).isTrue();
|
||||
}
|
||||
|
||||
@Test // gh-1120
|
||||
public void getAttributeNamesAndRemove() {
|
||||
void getAttributeNamesAndRemove() {
|
||||
this.session.setAttribute("attribute1", "value1");
|
||||
this.session.setAttribute("attribute2", "value2");
|
||||
|
||||
@@ -206,6 +204,7 @@ public class MapSessionTests {
|
||||
public boolean isExpired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* 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;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.authority.AuthorityUtils;
|
||||
import org.springframework.security.core.context.SecurityContext;
|
||||
import org.springframework.security.core.context.SecurityContextImpl;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link PrincipalNameIndexResolver}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
class PrincipalNameIndexResolverTests {
|
||||
|
||||
private static final String PRINCIPAL_NAME = "principalName";
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
private PrincipalNameIndexResolver<Session> indexResolver;
|
||||
|
||||
@BeforeEach
|
||||
void setUp() {
|
||||
this.indexResolver = new PrincipalNameIndexResolver<>();
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveFromPrincipalName() {
|
||||
MapSession session = new MapSession();
|
||||
session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, PRINCIPAL_NAME);
|
||||
assertThat(this.indexResolver.resolveIndexValueFor(session)).isEqualTo(PRINCIPAL_NAME);
|
||||
}
|
||||
|
||||
@Test
|
||||
void resolveFromSpringSecurityContext() {
|
||||
Authentication authentication = new UsernamePasswordAuthenticationToken(PRINCIPAL_NAME, "notused",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
SecurityContext context = new SecurityContextImpl();
|
||||
context.setAuthentication(authentication);
|
||||
MapSession session = new MapSession();
|
||||
session.setAttribute(SPRING_SECURITY_CONTEXT, context);
|
||||
assertThat(this.indexResolver.resolveIndexValueFor(session)).isEqualTo(PRINCIPAL_NAME);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -35,20 +35,20 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
* @author Rob Winch
|
||||
* @since 2.0
|
||||
*/
|
||||
public class ReactiveMapSessionRepositoryTests {
|
||||
class ReactiveMapSessionRepositoryTests {
|
||||
|
||||
private ReactiveMapSessionRepository repository;
|
||||
|
||||
private MapSession session;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.repository = new ReactiveMapSessionRepository(new HashMap<>());
|
||||
this.session = new MapSession("session-id");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorMapThenFound() {
|
||||
void constructorMapThenFound() {
|
||||
Map<String, Session> sessions = new HashMap<>();
|
||||
sessions.put(this.session.getId(), this.session);
|
||||
this.repository = new ReactiveMapSessionRepository(sessions);
|
||||
@@ -59,21 +59,20 @@ public class ReactiveMapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorMapWhenNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new ReactiveMapSessionRepository(null))
|
||||
void constructorMapWhenNullThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new ReactiveMapSessionRepository(null))
|
||||
.withMessage("sessions cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveWhenNoSubscribersThenNotFound() {
|
||||
void saveWhenNoSubscribersThenNotFound() {
|
||||
this.repository.save(this.session);
|
||||
|
||||
assertThat(this.repository.findById(this.session.getId()).block()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saveWhenSubscriberThenFound() {
|
||||
void saveWhenSubscriberThenFound() {
|
||||
this.repository.save(this.session).block();
|
||||
|
||||
Session findByIdSession = this.repository.findById(this.session.getId()).block();
|
||||
@@ -82,7 +81,7 @@ public class ReactiveMapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByIdWhenExpiredRemovesFromSessionMap() {
|
||||
void findByIdWhenExpiredRemovesFromSessionMap() {
|
||||
this.session.setMaxInactiveInterval(Duration.ofMinutes(1));
|
||||
this.session.setLastAccessedTime(Instant.now().minus(5, ChronoUnit.MINUTES));
|
||||
|
||||
@@ -95,20 +94,17 @@ public class ReactiveMapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenDefaultMaxInactiveIntervalThenDefaultMaxInactiveInterval() {
|
||||
void createSessionWhenDefaultMaxInactiveIntervalThenDefaultMaxInactiveInterval() {
|
||||
Session session = this.repository.createSession().block();
|
||||
|
||||
assertThat(session).isInstanceOf(MapSession.class);
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(new MapSession().getMaxInactiveInterval());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenCustomMaxInactiveIntervalThenCustomMaxInactiveInterval() {
|
||||
final Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval()
|
||||
.plusSeconds(10);
|
||||
this.repository
|
||||
.setDefaultMaxInactiveInterval((int) expectedMaxInterval.getSeconds());
|
||||
void createSessionWhenCustomMaxInactiveIntervalThenCustomMaxInactiveInterval() {
|
||||
final Duration expectedMaxInterval = new MapSession().getMaxInactiveInterval().plusSeconds(10);
|
||||
this.repository.setDefaultMaxInactiveInterval((int) expectedMaxInterval.getSeconds());
|
||||
|
||||
Session session = this.repository.createSession().block();
|
||||
|
||||
@@ -116,7 +112,7 @@ public class ReactiveMapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenNotYetSaved() {
|
||||
void changeSessionIdWhenNotYetSaved() {
|
||||
MapSession createSession = this.repository.createSession().block();
|
||||
|
||||
String originalId = createSession.getId();
|
||||
@@ -129,7 +125,7 @@ public class ReactiveMapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSaved() {
|
||||
void changeSessionIdWhenSaved() {
|
||||
MapSession createSession = this.repository.createSession().block();
|
||||
|
||||
this.repository.save(createSession).block();
|
||||
@@ -144,7 +140,7 @@ public class ReactiveMapSessionRepositoryTests {
|
||||
}
|
||||
|
||||
@Test // gh-1120
|
||||
public void getAttributeNamesAndRemove() {
|
||||
void getAttributeNamesAndRemove() {
|
||||
MapSession session = this.repository.createSession().block();
|
||||
session.setAttribute("attribute1", "value1");
|
||||
session.setAttribute("attribute2", "value2");
|
||||
|
||||
@@ -61,7 +61,7 @@ import static org.mockito.Mockito.verify;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class EnableSpringHttpSessionCustomCookieSerializerTests {
|
||||
class EnableSpringHttpSessionCustomCookieSerializerTests {
|
||||
|
||||
@Autowired
|
||||
private MockHttpServletRequest request;
|
||||
@@ -81,7 +81,7 @@ public class EnableSpringHttpSessionCustomCookieSerializerTests {
|
||||
private CookieSerializer cookieSerializer;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.chain = new MockFilterChain();
|
||||
|
||||
reset(this.sessionRepository);
|
||||
@@ -89,12 +89,11 @@ public class EnableSpringHttpSessionCustomCookieSerializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesReadSessionIds() throws Exception {
|
||||
void usesReadSessionIds() throws Exception {
|
||||
String sessionId = "sessionId";
|
||||
given(this.cookieSerializer.readCookieValues(any(HttpServletRequest.class)))
|
||||
.willReturn(Collections.singletonList(sessionId));
|
||||
given(this.sessionRepository.findById(anyString()))
|
||||
.willReturn(new MapSession(sessionId));
|
||||
given(this.sessionRepository.findById(anyString())).willReturn(new MapSession(sessionId));
|
||||
|
||||
this.sessionRepositoryFilter.doFilter(this.request, this.response, this.chain);
|
||||
|
||||
@@ -102,19 +101,18 @@ public class EnableSpringHttpSessionCustomCookieSerializerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void usesWrite() throws Exception {
|
||||
void usesWrite() throws Exception {
|
||||
given(this.sessionRepository.createSession()).willReturn(new MapSession());
|
||||
|
||||
this.sessionRepositoryFilter.doFilter(this.request, this.response,
|
||||
new MockFilterChain() {
|
||||
this.sessionRepositoryFilter.doFilter(this.request, this.response, new MockFilterChain() {
|
||||
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
((HttpServletRequest) request).getSession();
|
||||
super.doFilter(request, response);
|
||||
}
|
||||
});
|
||||
@Override
|
||||
public void doFilter(ServletRequest request, ServletResponse response)
|
||||
throws IOException, ServletException {
|
||||
((HttpServletRequest) request).getSession();
|
||||
super.doFilter(request, response);
|
||||
}
|
||||
});
|
||||
|
||||
verify(this.cookieSerializer).writeCookieValue(any(CookieValue.class));
|
||||
}
|
||||
@@ -128,12 +126,12 @@ public class EnableSpringHttpSessionCustomCookieSerializerTests {
|
||||
static class Config {
|
||||
|
||||
@Bean
|
||||
public SessionRepository sessionRepository() {
|
||||
SessionRepository sessionRepository() {
|
||||
return mock(SessionRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CookieSerializer cookieSerializer() {
|
||||
CookieSerializer cookieSerializer() {
|
||||
return mock(CookieSerializer.class);
|
||||
}
|
||||
|
||||
|
||||
@@ -45,12 +45,12 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class SpringHttpSessionConfigurationTests {
|
||||
class SpringHttpSessionConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
|
||||
@AfterEach
|
||||
public void closeContext() {
|
||||
void closeContext() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
@@ -62,28 +62,26 @@ public class SpringHttpSessionConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noSessionRepositoryConfiguration() {
|
||||
void noSessionRepositoryConfiguration() {
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
|
||||
.isThrownBy(() -> registerAndRefresh(EmptyConfiguration.class))
|
||||
.withMessageContaining("org.springframework.session.SessionRepository");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultConfiguration() {
|
||||
void defaultConfiguration() {
|
||||
registerAndRefresh(DefaultConfiguration.class);
|
||||
|
||||
assertThat(this.context.getBean(SessionEventHttpSessionListenerAdapter.class))
|
||||
.isNotNull();
|
||||
assertThat(this.context.getBean(SessionEventHttpSessionListenerAdapter.class)).isNotNull();
|
||||
assertThat(this.context.getBean(SessionRepositoryFilter.class)).isNotNull();
|
||||
assertThat(this.context.getBean(SessionRepository.class)).isNotNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionCookieConfigConfiguration() {
|
||||
void sessionCookieConfigConfiguration() {
|
||||
registerAndRefresh(SessionCookieConfigConfiguration.class);
|
||||
|
||||
SessionRepositoryFilter sessionRepositoryFilter = this.context
|
||||
.getBean(SessionRepositoryFilter.class);
|
||||
SessionRepositoryFilter sessionRepositoryFilter = this.context.getBean(SessionRepositoryFilter.class);
|
||||
assertThat(sessionRepositoryFilter).isNotNull();
|
||||
CookieHttpSessionIdResolver httpSessionIdResolver = (CookieHttpSessionIdResolver) ReflectionTestUtils
|
||||
.getField(sessionRepositoryFilter, "httpSessionIdResolver");
|
||||
@@ -91,22 +89,17 @@ public class SpringHttpSessionConfigurationTests {
|
||||
DefaultCookieSerializer cookieSerializer = (DefaultCookieSerializer) ReflectionTestUtils
|
||||
.getField(httpSessionIdResolver, "cookieSerializer");
|
||||
assertThat(cookieSerializer).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "cookieName"))
|
||||
.isEqualTo("test-name");
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "cookiePath"))
|
||||
.isEqualTo("test-path");
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "cookieMaxAge"))
|
||||
.isEqualTo(600);
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "domainName"))
|
||||
.isEqualTo("test-domain");
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "cookieName")).isEqualTo("test-name");
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "cookiePath")).isEqualTo("test-path");
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "cookieMaxAge")).isEqualTo(600);
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "domainName")).isEqualTo("test-domain");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void rememberMeServicesConfiguration() {
|
||||
void rememberMeServicesConfiguration() {
|
||||
registerAndRefresh(RememberMeServicesConfiguration.class);
|
||||
|
||||
SessionRepositoryFilter sessionRepositoryFilter = this.context
|
||||
.getBean(SessionRepositoryFilter.class);
|
||||
SessionRepositoryFilter sessionRepositoryFilter = this.context.getBean(SessionRepositoryFilter.class);
|
||||
assertThat(sessionRepositoryFilter).isNotNull();
|
||||
CookieHttpSessionIdResolver httpSessionIdResolver = (CookieHttpSessionIdResolver) ReflectionTestUtils
|
||||
.getField(sessionRepositoryFilter, "httpSessionIdResolver");
|
||||
@@ -114,20 +107,20 @@ public class SpringHttpSessionConfigurationTests {
|
||||
DefaultCookieSerializer cookieSerializer = (DefaultCookieSerializer) ReflectionTestUtils
|
||||
.getField(httpSessionIdResolver, "cookieSerializer");
|
||||
assertThat(cookieSerializer).isNotNull();
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer,
|
||||
"rememberMeRequestAttribute")).isEqualTo(
|
||||
SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);
|
||||
assertThat(ReflectionTestUtils.getField(cookieSerializer, "rememberMeRequestAttribute"))
|
||||
.isEqualTo(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR);
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableSpringHttpSession
|
||||
static class EmptyConfiguration {
|
||||
|
||||
}
|
||||
|
||||
static class BaseConfiguration {
|
||||
|
||||
@Bean
|
||||
public MapSessionRepository sessionRepository() {
|
||||
MapSessionRepository sessionRepository() {
|
||||
return new MapSessionRepository(new ConcurrentHashMap<>());
|
||||
}
|
||||
|
||||
@@ -136,6 +129,7 @@ public class SpringHttpSessionConfigurationTests {
|
||||
@Configuration
|
||||
@EnableSpringHttpSession
|
||||
static class DefaultConfiguration extends BaseConfiguration {
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -143,7 +137,7 @@ public class SpringHttpSessionConfigurationTests {
|
||||
static class SessionCookieConfigConfiguration extends BaseConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServletContext servletContext() {
|
||||
ServletContext servletContext() {
|
||||
MockServletContext servletContext = new MockServletContext();
|
||||
servletContext.getSessionCookieConfig().setName("test-name");
|
||||
servletContext.getSessionCookieConfig().setDomain("test-domain");
|
||||
@@ -159,7 +153,7 @@ public class SpringHttpSessionConfigurationTests {
|
||||
static class RememberMeServicesConfiguration extends BaseConfiguration {
|
||||
|
||||
@Bean
|
||||
public SpringSessionRememberMeServices rememberMeServices() {
|
||||
SpringSessionRememberMeServices rememberMeServices() {
|
||||
return new SpringSessionRememberMeServices();
|
||||
}
|
||||
|
||||
|
||||
@@ -41,18 +41,19 @@ import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
*
|
||||
* @author Greg Turnquist
|
||||
*/
|
||||
public class SpringWebSessionConfigurationTests {
|
||||
class SpringWebSessionConfigurationTests {
|
||||
|
||||
private AnnotationConfigApplicationContext context;
|
||||
|
||||
@AfterEach
|
||||
public void cleanup() {
|
||||
void cleanup() {
|
||||
if (this.context != null) {
|
||||
this.context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void enableSpringWebSessionConfiguresThings() {
|
||||
void enableSpringWebSessionConfiguresThings() {
|
||||
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(GoodConfig.class);
|
||||
@@ -69,19 +70,18 @@ public class SpringWebSessionConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void missingReactiveSessionRepositoryBreaksAppContext() {
|
||||
void missingReactiveSessionRepositoryBreaksAppContext() {
|
||||
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(BadConfig.class);
|
||||
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class)
|
||||
.isThrownBy(this.context::refresh)
|
||||
.withMessageContaining("Error creating bean with name 'webSessionManager'")
|
||||
.withMessageContaining("No qualifying bean of type '" + ReactiveSessionRepository.class.getCanonicalName());
|
||||
assertThatExceptionOfType(UnsatisfiedDependencyException.class).isThrownBy(this.context::refresh)
|
||||
.withMessageContaining("Error creating bean with name 'webSessionManager'").withMessageContaining(
|
||||
"No qualifying bean of type '" + ReactiveSessionRepository.class.getCanonicalName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void defaultSessionIdResolverShouldBeCookieBased() {
|
||||
void defaultSessionIdResolverShouldBeCookieBased() {
|
||||
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(GoodConfig.class);
|
||||
@@ -92,7 +92,7 @@ public class SpringWebSessionConfigurationTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void providedSessionIdResolverShouldBePickedUpAutomatically() {
|
||||
void providedSessionIdResolverShouldBePickedUpAutomatically() {
|
||||
|
||||
this.context = new AnnotationConfigApplicationContext();
|
||||
this.context.register(OverrideSessionIdResolver.class);
|
||||
@@ -109,12 +109,14 @@ public class SpringWebSessionConfigurationTests {
|
||||
static class GoodConfig {
|
||||
|
||||
/**
|
||||
* Use Reactor-friendly, {@link java.util.Map}-backed {@link ReactiveSessionRepository} for test purposes.
|
||||
* Use Reactor-friendly, {@link java.util.Map}-backed
|
||||
* {@link ReactiveSessionRepository} for test purposes.
|
||||
*/
|
||||
@Bean
|
||||
ReactiveSessionRepository<?> reactiveSessionRepository() {
|
||||
return new ReactiveMapSessionRepository(new HashMap<>());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -137,6 +139,7 @@ public class SpringWebSessionConfigurationTests {
|
||||
WebSessionIdResolver alternateWebSessionIdResolver() {
|
||||
return new HeaderWebSessionIdResolver();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.springframework.session.security;
|
||||
|
||||
import java.security.Principal;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.Collections;
|
||||
@@ -30,6 +31,7 @@ import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import org.springframework.security.core.AuthenticatedPrincipal;
|
||||
import org.springframework.security.core.Authentication;
|
||||
import org.springframework.security.core.context.SecurityContextImpl;
|
||||
import org.springframework.security.core.session.SessionInformation;
|
||||
@@ -46,7 +48,7 @@ import static org.mockito.BDDMockito.when;
|
||||
/**
|
||||
* Tests for {@link SpringSessionBackedSessionRegistry}.
|
||||
*/
|
||||
public class SpringSessionBackedSessionRegistryTest {
|
||||
class SpringSessionBackedSessionRegistryTest {
|
||||
|
||||
private static final String SESSION_ID = "sessionId";
|
||||
|
||||
@@ -54,8 +56,7 @@ public class SpringSessionBackedSessionRegistryTest {
|
||||
|
||||
private static final String USER_NAME = "userName";
|
||||
|
||||
private static final User PRINCIPAL = new User(USER_NAME, "password",
|
||||
Collections.emptyList());
|
||||
private static final User PRINCIPAL = new User(USER_NAME, "password", Collections.emptyList());
|
||||
|
||||
private static final Instant NOW = Instant.now();
|
||||
|
||||
@@ -71,74 +72,77 @@ public class SpringSessionBackedSessionRegistryTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionInformationForExistingSession() {
|
||||
void sessionInformationForExistingSession() {
|
||||
Session session = createSession(SESSION_ID, USER_NAME, NOW);
|
||||
when(this.sessionRepository.findById(SESSION_ID)).thenReturn(session);
|
||||
|
||||
SessionInformation sessionInfo = this.sessionRegistry
|
||||
.getSessionInformation(SESSION_ID);
|
||||
SessionInformation sessionInfo = this.sessionRegistry.getSessionInformation(SESSION_ID);
|
||||
|
||||
assertThat(sessionInfo.getSessionId()).isEqualTo(SESSION_ID);
|
||||
assertThat(
|
||||
sessionInfo.getLastRequest().toInstant().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(NOW.truncatedTo(ChronoUnit.MILLIS));
|
||||
assertThat(sessionInfo.getLastRequest().toInstant().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(NOW.truncatedTo(ChronoUnit.MILLIS));
|
||||
assertThat(sessionInfo.getPrincipal()).isEqualTo(USER_NAME);
|
||||
assertThat(sessionInfo.isExpired()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void sessionInformationForExpiredSession() {
|
||||
void sessionInformationForExpiredSession() {
|
||||
Session session = createSession(SESSION_ID, USER_NAME, NOW);
|
||||
session.setAttribute(SpringSessionBackedSessionInformation.EXPIRED_ATTR,
|
||||
Boolean.TRUE);
|
||||
session.setAttribute(SpringSessionBackedSessionInformation.EXPIRED_ATTR, Boolean.TRUE);
|
||||
when(this.sessionRepository.findById(SESSION_ID)).thenReturn(session);
|
||||
|
||||
SessionInformation sessionInfo = this.sessionRegistry
|
||||
.getSessionInformation(SESSION_ID);
|
||||
SessionInformation sessionInfo = this.sessionRegistry.getSessionInformation(SESSION_ID);
|
||||
|
||||
assertThat(sessionInfo.getSessionId()).isEqualTo(SESSION_ID);
|
||||
assertThat(
|
||||
sessionInfo.getLastRequest().toInstant().truncatedTo(ChronoUnit.MILLIS))
|
||||
assertThat(sessionInfo.getLastRequest().toInstant().truncatedTo(ChronoUnit.MILLIS))
|
||||
.isEqualTo(NOW.truncatedTo(ChronoUnit.MILLIS));
|
||||
assertThat(sessionInfo.getPrincipal()).isEqualTo(USER_NAME);
|
||||
assertThat(sessionInfo.isExpired()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void noSessionInformationForMissingSession() {
|
||||
assertThat(this.sessionRegistry.getSessionInformation("nonExistingSessionId"))
|
||||
.isNull();
|
||||
void noSessionInformationForMissingSession() {
|
||||
assertThat(this.sessionRegistry.getSessionInformation("nonExistingSessionId")).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getAllSessions() {
|
||||
void getAllSessionsForUserDetails() {
|
||||
setUpSessions();
|
||||
List<SessionInformation> allSessionInfos = this.sessionRegistry.getAllSessions(PRINCIPAL, true);
|
||||
assertThat(allSessionInfos).extracting("sessionId").containsExactly(SESSION_ID, SESSION_ID2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getAllSessionsForAuthenticatedPrincipal() {
|
||||
setUpSessions();
|
||||
List<SessionInformation> allSessionInfos = this.sessionRegistry
|
||||
.getAllSessions(PRINCIPAL, true);
|
||||
|
||||
assertThat(allSessionInfos).extracting("sessionId").containsExactly(SESSION_ID,
|
||||
SESSION_ID2);
|
||||
.getAllSessions((AuthenticatedPrincipal) () -> USER_NAME, true);
|
||||
assertThat(allSessionInfos).extracting("sessionId").containsExactly(SESSION_ID, SESSION_ID2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getNonExpiredSessions() {
|
||||
void getAllSessionsForPrincipal() {
|
||||
setUpSessions();
|
||||
List<SessionInformation> allSessionInfos = this.sessionRegistry.getAllSessions(new TestPrincipal(USER_NAME),
|
||||
true);
|
||||
assertThat(allSessionInfos).extracting("sessionId").containsExactly(SESSION_ID, SESSION_ID2);
|
||||
}
|
||||
|
||||
@Test
|
||||
void getNonExpiredSessions() {
|
||||
setUpSessions();
|
||||
|
||||
List<SessionInformation> nonExpiredSessionInfos = this.sessionRegistry
|
||||
.getAllSessions(PRINCIPAL, false);
|
||||
List<SessionInformation> nonExpiredSessionInfos = this.sessionRegistry.getAllSessions(PRINCIPAL, false);
|
||||
|
||||
assertThat(nonExpiredSessionInfos).extracting("sessionId")
|
||||
.containsExactly(SESSION_ID2);
|
||||
assertThat(nonExpiredSessionInfos).extracting("sessionId").containsExactly(SESSION_ID2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expireNow() {
|
||||
void expireNow() {
|
||||
Session session = createSession(SESSION_ID, USER_NAME, NOW);
|
||||
when(this.sessionRepository.findById(SESSION_ID)).thenReturn(session);
|
||||
|
||||
SessionInformation sessionInfo = this.sessionRegistry
|
||||
.getSessionInformation(SESSION_ID);
|
||||
SessionInformation sessionInfo = this.sessionRegistry.getSessionInformation(SESSION_ID);
|
||||
assertThat(sessionInfo.isExpired()).isFalse();
|
||||
|
||||
sessionInfo.expireNow();
|
||||
@@ -146,13 +150,11 @@ public class SpringSessionBackedSessionRegistryTest {
|
||||
assertThat(sessionInfo.isExpired()).isTrue();
|
||||
ArgumentCaptor<Session> captor = ArgumentCaptor.forClass(Session.class);
|
||||
verify(this.sessionRepository).save(captor.capture());
|
||||
assertThat(captor.getValue().<Boolean>getAttribute(
|
||||
SpringSessionBackedSessionInformation.EXPIRED_ATTR))
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
assertThat(captor.getValue().<Boolean>getAttribute(SpringSessionBackedSessionInformation.EXPIRED_ATTR))
|
||||
.isEqualTo(Boolean.TRUE);
|
||||
}
|
||||
|
||||
private Session createSession(String sessionId, String userName,
|
||||
Instant lastAccessed) {
|
||||
private Session createSession(String sessionId, String userName, Instant lastAccessed) {
|
||||
MapSession session = new MapSession(sessionId);
|
||||
session.setLastAccessedTime(lastAccessed);
|
||||
Authentication authentication = mock(Authentication.class);
|
||||
@@ -165,14 +167,48 @@ public class SpringSessionBackedSessionRegistryTest {
|
||||
|
||||
private void setUpSessions() {
|
||||
Session session1 = createSession(SESSION_ID, USER_NAME, NOW);
|
||||
session1.setAttribute(SpringSessionBackedSessionInformation.EXPIRED_ATTR,
|
||||
Boolean.TRUE);
|
||||
session1.setAttribute(SpringSessionBackedSessionInformation.EXPIRED_ATTR, Boolean.TRUE);
|
||||
Session session2 = createSession(SESSION_ID2, USER_NAME, NOW);
|
||||
Map<String, Session> sessions = new LinkedHashMap<>();
|
||||
sessions.put(session1.getId(), session1);
|
||||
sessions.put(session2.getId(), session2);
|
||||
when(this.sessionRepository.findByPrincipalName(USER_NAME))
|
||||
.thenReturn(sessions);
|
||||
when(this.sessionRepository.findByPrincipalName(USER_NAME)).thenReturn(sessions);
|
||||
}
|
||||
|
||||
private static final class TestPrincipal implements Principal {
|
||||
|
||||
private final String name;
|
||||
|
||||
private TestPrincipal(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object another) {
|
||||
if (this == another) {
|
||||
return true;
|
||||
}
|
||||
if (another instanceof TestPrincipal) {
|
||||
return this.name.equals(((TestPrincipal) another).name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.name.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.name;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -33,77 +33,67 @@ import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link SpringSessionRememberMeServices}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class SpringSessionRememberMeServicesTests {
|
||||
class SpringSessionRememberMeServicesTests {
|
||||
|
||||
private SpringSessionRememberMeServices rememberMeServices;
|
||||
|
||||
@Test
|
||||
public void create() {
|
||||
void create() {
|
||||
this.rememberMeServices = new SpringSessionRememberMeServices();
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices,
|
||||
"rememberMeParameterName")).isEqualTo("remember-me");
|
||||
assertThat(
|
||||
ReflectionTestUtils.getField(this.rememberMeServices, "alwaysRemember"))
|
||||
.isEqualTo(false);
|
||||
assertThat(
|
||||
ReflectionTestUtils.getField(this.rememberMeServices, "validitySeconds"))
|
||||
.isEqualTo(2592000);
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "rememberMeParameterName"))
|
||||
.isEqualTo("remember-me");
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "alwaysRemember")).isEqualTo(false);
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "validitySeconds")).isEqualTo(2592000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithCustomParameter() {
|
||||
void createWithCustomParameter() {
|
||||
this.rememberMeServices = new SpringSessionRememberMeServices();
|
||||
this.rememberMeServices.setRememberMeParameterName("test-param");
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices,
|
||||
"rememberMeParameterName")).isEqualTo("test-param");
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "rememberMeParameterName"))
|
||||
.isEqualTo("test-param");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithNullParameter() {
|
||||
void createWithNullParameter() {
|
||||
this.rememberMeServices = new SpringSessionRememberMeServices();
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(
|
||||
() -> this.rememberMeServices.setRememberMeParameterName(null))
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.rememberMeServices.setRememberMeParameterName(null))
|
||||
.withMessage("rememberMeParameterName cannot be empty or null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithAlwaysRemember() {
|
||||
void createWithAlwaysRemember() {
|
||||
this.rememberMeServices = new SpringSessionRememberMeServices();
|
||||
this.rememberMeServices.setAlwaysRemember(true);
|
||||
assertThat(
|
||||
ReflectionTestUtils.getField(this.rememberMeServices, "alwaysRemember"))
|
||||
.isEqualTo(true);
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "alwaysRemember")).isEqualTo(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createWithCustomValidity() {
|
||||
void createWithCustomValidity() {
|
||||
this.rememberMeServices = new SpringSessionRememberMeServices();
|
||||
this.rememberMeServices.setValiditySeconds(100000);
|
||||
assertThat(
|
||||
ReflectionTestUtils.getField(this.rememberMeServices, "validitySeconds"))
|
||||
.isEqualTo(100000);
|
||||
assertThat(ReflectionTestUtils.getField(this.rememberMeServices, "validitySeconds")).isEqualTo(100000);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void autoLogin() {
|
||||
void autoLogin() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
this.rememberMeServices = new SpringSessionRememberMeServices();
|
||||
this.rememberMeServices.autoLogin(request, response);
|
||||
verifyZeroInteractions(request, response);
|
||||
verifyNoMoreInteractions(request, response);
|
||||
}
|
||||
|
||||
// gh-752
|
||||
@Test
|
||||
public void loginFailRemoveSecurityContext() {
|
||||
void loginFailRemoveSecurityContext() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
HttpSession session = mock(HttpSession.class);
|
||||
@@ -111,13 +101,12 @@ public class SpringSessionRememberMeServicesTests {
|
||||
this.rememberMeServices = new SpringSessionRememberMeServices();
|
||||
this.rememberMeServices.loginFail(request, response);
|
||||
verify(request, times(1)).getSession(eq(false));
|
||||
verify(session, times(1)).removeAttribute(
|
||||
HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
||||
verifyZeroInteractions(request, response, session);
|
||||
verify(session, times(1)).removeAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY);
|
||||
verifyNoMoreInteractions(request, response, session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginSuccess() {
|
||||
void loginSuccess() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
Authentication authentication = mock(Authentication.class);
|
||||
@@ -128,14 +117,13 @@ public class SpringSessionRememberMeServicesTests {
|
||||
this.rememberMeServices.loginSuccess(request, response, authentication);
|
||||
verify(request, times(1)).getParameter(eq("remember-me"));
|
||||
verify(request, times(1)).getSession();
|
||||
verify(request, times(1)).setAttribute(
|
||||
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(request, times(1)).setAttribute(eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(session, times(1)).setMaxInactiveInterval(eq(2592000));
|
||||
verifyZeroInteractions(request, response, session, authentication);
|
||||
verifyNoMoreInteractions(request, response, session, authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginSuccessWithCustomParameter() {
|
||||
void loginSuccessWithCustomParameter() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
Authentication authentication = mock(Authentication.class);
|
||||
@@ -147,14 +135,13 @@ public class SpringSessionRememberMeServicesTests {
|
||||
this.rememberMeServices.loginSuccess(request, response, authentication);
|
||||
verify(request, times(1)).getParameter(eq("test-param"));
|
||||
verify(request, times(1)).getSession();
|
||||
verify(request, times(1)).setAttribute(
|
||||
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(request, times(1)).setAttribute(eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(session, times(1)).setMaxInactiveInterval(eq(2592000));
|
||||
verifyZeroInteractions(request, response, session, authentication);
|
||||
verifyNoMoreInteractions(request, response, session, authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginSuccessWithAlwaysRemember() {
|
||||
void loginSuccessWithAlwaysRemember() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
Authentication authentication = mock(Authentication.class);
|
||||
@@ -164,14 +151,13 @@ public class SpringSessionRememberMeServicesTests {
|
||||
this.rememberMeServices.setAlwaysRemember(true);
|
||||
this.rememberMeServices.loginSuccess(request, response, authentication);
|
||||
verify(request, times(1)).getSession();
|
||||
verify(request, times(1)).setAttribute(
|
||||
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(request, times(1)).setAttribute(eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(session, times(1)).setMaxInactiveInterval(eq(2592000));
|
||||
verifyZeroInteractions(request, response, session, authentication);
|
||||
verifyNoMoreInteractions(request, response, session, authentication);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void loginSuccessWithCustomValidity() {
|
||||
void loginSuccessWithCustomValidity() {
|
||||
HttpServletRequest request = mock(HttpServletRequest.class);
|
||||
HttpServletResponse response = mock(HttpServletResponse.class);
|
||||
Authentication authentication = mock(Authentication.class);
|
||||
@@ -183,10 +169,9 @@ public class SpringSessionRememberMeServicesTests {
|
||||
this.rememberMeServices.loginSuccess(request, response, authentication);
|
||||
verify(request, times(1)).getParameter(eq("remember-me"));
|
||||
verify(request, times(1)).getSession();
|
||||
verify(request, times(1)).setAttribute(
|
||||
eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(request, times(1)).setAttribute(eq(SpringSessionRememberMeServices.REMEMBER_ME_LOGIN_ATTR), eq(true));
|
||||
verify(session, times(1)).setMaxInactiveInterval(eq(100000));
|
||||
verifyZeroInteractions(request, response, session, authentication);
|
||||
verifyNoMoreInteractions(request, response, session, authentication);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -34,17 +34,20 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
/**
|
||||
* Tests for {@link CookieHttpSessionIdResolver}.
|
||||
*/
|
||||
public class CookieHttpSessionIdResolverTests {
|
||||
class CookieHttpSessionIdResolverTests {
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
private CookieHttpSessionIdResolver strategy;
|
||||
|
||||
private String cookieName;
|
||||
|
||||
private Session session;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
void setup() {
|
||||
this.cookieName = "SESSION";
|
||||
this.session = new MapSession();
|
||||
this.request = new MockHttpServletRequest();
|
||||
@@ -53,19 +56,19 @@ public class CookieHttpSessionIdResolverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestedSessionIdNull() throws Exception {
|
||||
void getRequestedSessionIdNull() {
|
||||
assertThat(this.strategy.resolveSessionIds(this.request)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestedSessionIdNotNull() throws Exception {
|
||||
void getRequestedSessionIdNotNull() {
|
||||
setSessionCookie(this.session.getId());
|
||||
assertThat(this.strategy.resolveSessionIds(this.request))
|
||||
.isEqualTo(Collections.singletonList(this.session.getId()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestedSessionIdNotNullCustomCookieName() throws Exception {
|
||||
void getRequestedSessionIdNotNullCustomCookieName() {
|
||||
setCookieName("CUSTOM");
|
||||
setSessionCookie(this.session.getId());
|
||||
assertThat(this.strategy.resolveSessionIds(this.request))
|
||||
@@ -73,13 +76,13 @@ public class CookieHttpSessionIdResolverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onNewSession() throws Exception {
|
||||
void onNewSession() {
|
||||
this.strategy.setSessionId(this.request, this.response, this.session.getId());
|
||||
assertThat(getSessionId()).isEqualTo(this.session.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onNewSessionTwiceSameId() throws Exception {
|
||||
void onNewSessionTwiceSameId() {
|
||||
this.strategy.setSessionId(this.request, this.response, this.session.getId());
|
||||
this.strategy.setSessionId(this.request, this.response, this.session.getId());
|
||||
|
||||
@@ -87,7 +90,7 @@ public class CookieHttpSessionIdResolverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onNewSessionTwiceNewId() throws Exception {
|
||||
void onNewSessionTwiceNewId() {
|
||||
Session newSession = new MapSession();
|
||||
|
||||
this.strategy.setSessionId(this.request, this.response, this.session.getId());
|
||||
@@ -101,49 +104,47 @@ public class CookieHttpSessionIdResolverTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onNewSessionCookiePath() throws Exception {
|
||||
void onNewSessionCookiePath() {
|
||||
this.request.setContextPath("/somethingunique");
|
||||
this.strategy.setSessionId(this.request, this.response, this.session.getId());
|
||||
|
||||
Cookie sessionCookie = this.response.getCookie(this.cookieName);
|
||||
assertThat(sessionCookie.getPath())
|
||||
.isEqualTo(this.request.getContextPath() + "/");
|
||||
assertThat(sessionCookie.getPath()).isEqualTo(this.request.getContextPath() + "/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onNewSessionCustomCookieName() throws Exception {
|
||||
void onNewSessionCustomCookieName() {
|
||||
setCookieName("CUSTOM");
|
||||
this.strategy.setSessionId(this.request, this.response, this.session.getId());
|
||||
assertThat(getSessionId()).isEqualTo(this.session.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeleteSession() throws Exception {
|
||||
void onDeleteSession() {
|
||||
this.strategy.expireSession(this.request, this.response);
|
||||
assertThat(getSessionId()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeleteSessionCookiePath() throws Exception {
|
||||
void onDeleteSessionCookiePath() {
|
||||
this.request.setContextPath("/somethingunique");
|
||||
this.strategy.expireSession(this.request, this.response);
|
||||
|
||||
Cookie sessionCookie = this.response.getCookie(this.cookieName);
|
||||
assertThat(sessionCookie.getPath())
|
||||
.isEqualTo(this.request.getContextPath() + "/");
|
||||
assertThat(sessionCookie.getPath()).isEqualTo(this.request.getContextPath() + "/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeleteSessionCustomCookieName() throws Exception {
|
||||
void onDeleteSessionCustomCookieName() {
|
||||
setCookieName("CUSTOM");
|
||||
this.strategy.expireSession(this.request, this.response);
|
||||
assertThat(getSessionId()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionCookieValue() {
|
||||
assertThat(createSessionCookieValue(17)).isEqualToIgnoringCase(
|
||||
"0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 a 10 b 11 c 12 d 13 e 14 f 15 10 16");
|
||||
void createSessionCookieValue() {
|
||||
assertThat(createSessionCookieValue(17))
|
||||
.isEqualToIgnoringCase("0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 a 10 b 11 c 12 d 13 e 14 f 15 10 16");
|
||||
}
|
||||
|
||||
private String createSessionCookieValue(long size) {
|
||||
|
||||
@@ -16,6 +16,11 @@
|
||||
|
||||
package org.springframework.session.web.http;
|
||||
|
||||
import java.time.Clock;
|
||||
import java.time.Instant;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Base64;
|
||||
|
||||
import javax.servlet.http.Cookie;
|
||||
@@ -42,7 +47,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
* @author Vedran Pavic
|
||||
* @author Eddú Meléndez
|
||||
*/
|
||||
public class DefaultCookieSerializerTests {
|
||||
class DefaultCookieSerializerTests {
|
||||
|
||||
private String cookieName;
|
||||
|
||||
@@ -55,7 +60,7 @@ public class DefaultCookieSerializerTests {
|
||||
private String sessionId;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.cookieName = "SESSION";
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
@@ -66,459 +71,397 @@ public class DefaultCookieSerializerTests {
|
||||
// --- readCookieValues ---
|
||||
|
||||
@Test
|
||||
public void readCookieValuesNull() {
|
||||
void readCookieValuesNull() {
|
||||
assertThat(this.serializer.readCookieValues(this.request)).isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieValuesSingle(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieValuesSingle(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
this.request.setCookies(
|
||||
createCookie(this.cookieName, this.sessionId, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request))
|
||||
.containsOnly(this.sessionId);
|
||||
this.request.setCookies(createCookie(this.cookieName, this.sessionId, useBase64Encoding));
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsOnly(this.sessionId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void readCookieSerializerUseBase64EncodingTrueValuesNotBase64() {
|
||||
void readCookieSerializerUseBase64EncodingTrueValuesNotBase64() {
|
||||
this.sessionId = "&^%$*";
|
||||
this.serializer.setUseBase64Encoding(true);
|
||||
this.request.setCookies(new Cookie(this.cookieName, this.sessionId));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request)).isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieValuesSingleAndInvalidName(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieValuesSingleAndInvalidName(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
this.request.setCookies(
|
||||
createCookie(this.cookieName, this.sessionId, useBase64Encoding),
|
||||
createCookie(this.cookieName + "INVALID", this.sessionId + "INVALID",
|
||||
useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request))
|
||||
.containsOnly(this.sessionId);
|
||||
this.request.setCookies(createCookie(this.cookieName, this.sessionId, useBase64Encoding),
|
||||
createCookie(this.cookieName + "INVALID", this.sessionId + "INVALID", useBase64Encoding));
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsOnly(this.sessionId);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieValuesMulti(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieValuesMulti(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
String secondSession = "secondSessionId";
|
||||
this.request.setCookies(
|
||||
createCookie(this.cookieName, this.sessionId, useBase64Encoding),
|
||||
this.request.setCookies(createCookie(this.cookieName, this.sessionId, useBase64Encoding),
|
||||
createCookie(this.cookieName, secondSession, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request))
|
||||
.containsExactly(this.sessionId, secondSession);
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsExactly(this.sessionId, secondSession);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieValuesMultiCustomSessionCookieName(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieValuesMultiCustomSessionCookieName(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
setCookieName("JSESSIONID");
|
||||
String secondSession = "secondSessionId";
|
||||
this.request.setCookies(
|
||||
createCookie(this.cookieName, this.sessionId, useBase64Encoding),
|
||||
this.request.setCookies(createCookie(this.cookieName, this.sessionId, useBase64Encoding),
|
||||
createCookie(this.cookieName, secondSession, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request))
|
||||
.containsExactly(this.sessionId, secondSession);
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsExactly(this.sessionId, secondSession);
|
||||
}
|
||||
|
||||
// gh-392
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieValuesNullCookieValue(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieValuesNullCookieValue(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
this.request.setCookies(createCookie(this.cookieName, null, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request)).isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieValuesNullCookieValueAndJvmRoute(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieValuesNullCookieValueAndJvmRoute(boolean useBase64Encoding) {
|
||||
this.serializer.setJvmRoute("123");
|
||||
this.request.setCookies(createCookie(this.cookieName, null, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request)).isEmpty();
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieValuesNullCookieValueAndNotNullCookie(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieValuesNullCookieValueAndNotNullCookie(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
this.serializer.setJvmRoute("123");
|
||||
this.request.setCookies(createCookie(this.cookieName, null, useBase64Encoding),
|
||||
createCookie(this.cookieName, this.sessionId, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request))
|
||||
.containsOnly(this.sessionId);
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsOnly(this.sessionId);
|
||||
}
|
||||
|
||||
// --- writeCookie ---
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void writeCookie(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void writeCookie(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookieValue(useBase64Encoding)).isEqualTo(this.sessionId);
|
||||
}
|
||||
|
||||
// --- httpOnly ---
|
||||
|
||||
@Test
|
||||
public void writeCookieHttpOnlyDefault() {
|
||||
void writeCookieHttpOnlyDefault() {
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().isHttpOnly()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieHttpOnlySetTrue() {
|
||||
void writeCookieHttpOnlySetTrue() {
|
||||
this.serializer.setUseHttpOnlyCookie(true);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().isHttpOnly()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieHttpOnlySetFalse() {
|
||||
void writeCookieHttpOnlySetFalse() {
|
||||
this.serializer.setUseHttpOnlyCookie(false);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().isHttpOnly()).isFalse();
|
||||
}
|
||||
|
||||
// --- domainName ---
|
||||
|
||||
@Test
|
||||
public void writeCookieDomainNameDefault() {
|
||||
void writeCookieDomainNameDefault() {
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getDomain()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieDomainNameCustom() {
|
||||
void writeCookieDomainNameCustom() {
|
||||
String domainName = "example.com";
|
||||
this.serializer.setDomainName(domainName);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getDomain()).isEqualTo(domainName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDomainNameAndDomainNamePatternThrows() {
|
||||
void setDomainNameAndDomainNamePatternThrows() {
|
||||
this.serializer.setDomainName("example.com");
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.serializer.setDomainNamePattern(".*"))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.serializer.setDomainNamePattern(".*"))
|
||||
.withMessage("Cannot set both domainName and domainNamePattern");
|
||||
}
|
||||
|
||||
// --- domainNamePattern ---
|
||||
|
||||
@Test
|
||||
public void writeCookieDomainNamePattern() {
|
||||
void writeCookieDomainNamePattern() {
|
||||
String domainNamePattern = "^.+?\\.(\\w+\\.[a-z]+)$";
|
||||
this.serializer.setDomainNamePattern(domainNamePattern);
|
||||
|
||||
String[] matchingDomains = { "child.sub.example.com", "www.example.com" };
|
||||
for (String domain : matchingDomains) {
|
||||
this.request.setServerName(domain);
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
assertThat(getCookie().getDomain()).isEqualTo("example.com");
|
||||
|
||||
this.response = new MockHttpServletResponse();
|
||||
}
|
||||
|
||||
String[] notMatchingDomains = { "example.com", "localhost", "127.0.0.1" };
|
||||
for (String domain : notMatchingDomains) {
|
||||
this.request.setServerName(domain);
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
assertThat(getCookie().getDomain()).isNull();
|
||||
|
||||
this.response = new MockHttpServletResponse();
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setDomainNamePatternAndDomainNameThrows() {
|
||||
void setDomainNamePatternAndDomainNameThrows() {
|
||||
this.serializer.setDomainNamePattern(".*");
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.serializer.setDomainName("example.com"))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.serializer.setDomainName("example.com"))
|
||||
.withMessage("Cannot set both domainName and domainNamePattern");
|
||||
}
|
||||
|
||||
// --- cookieName ---
|
||||
|
||||
@Test
|
||||
public void writeCookieCookieNameDefault() {
|
||||
void writeCookieCookieNameDefault() {
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getName()).isEqualTo("SESSION");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieCookieNameCustom() {
|
||||
void writeCookieCookieNameCustom() {
|
||||
String cookieName = "JSESSIONID";
|
||||
setCookieName(cookieName);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getName()).isEqualTo(cookieName);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setCookieNameNullThrows() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.serializer.setCookieName(null))
|
||||
void setCookieNameNullThrows() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.serializer.setCookieName(null))
|
||||
.withMessage("cookieName cannot be null");
|
||||
}
|
||||
|
||||
// --- cookiePath ---
|
||||
|
||||
@Test
|
||||
public void writeCookieCookiePathDefaultEmptyContextPathUsed() {
|
||||
void writeCookieCookiePathDefaultEmptyContextPathUsed() {
|
||||
this.request.setContextPath("");
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getPath()).isEqualTo("/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieCookiePathDefaultContextPathUsed() {
|
||||
void writeCookieCookiePathDefaultContextPathUsed() {
|
||||
this.request.setContextPath("/context");
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getPath()).isEqualTo("/context/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieCookiePathExplicitNullCookiePathContextPathUsed() {
|
||||
void writeCookieCookiePathExplicitNullCookiePathContextPathUsed() {
|
||||
this.request.setContextPath("/context");
|
||||
this.serializer.setCookiePath(null);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getPath()).isEqualTo("/context/");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieCookiePathExplicitCookiePath() {
|
||||
void writeCookieCookiePathExplicitCookiePath() {
|
||||
this.request.setContextPath("/context");
|
||||
this.serializer.setCookiePath("/");
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getPath()).isEqualTo("/");
|
||||
}
|
||||
|
||||
// --- cookieMaxAge ---
|
||||
|
||||
@Test
|
||||
public void writeCookieCookieMaxAgeDefault() {
|
||||
void writeCookieCookieMaxAgeDefault() {
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getMaxAge()).isEqualTo(-1);
|
||||
assertThat(getCookie().getExpires()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieCookieMaxAgeExplicit() {
|
||||
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);
|
||||
MockCookie cookie = getCookie();
|
||||
assertThat(cookie.getMaxAge()).isEqualTo(100);
|
||||
ZonedDateTime expires = cookie.getExpires();
|
||||
assertThat(expires).isNotNull();
|
||||
assertThat(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME)).isEqualTo("Mon, 7 Oct 2019 20:11:40 GMT");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieCookieMaxAgeExplicitEmptyCookie() {
|
||||
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);
|
||||
MockCookie cookie = getCookie();
|
||||
assertThat(cookie.getMaxAge()).isEqualTo(0);
|
||||
ZonedDateTime expires = cookie.getExpires();
|
||||
assertThat(expires).isNotNull();
|
||||
assertThat(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME)).isEqualTo("Thu, 1 Jan 1970 00:00:00 GMT");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieCookieMaxAgeExplicitCookieValue() {
|
||||
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);
|
||||
MockCookie cookie = getCookie();
|
||||
assertThat(cookie.getMaxAge()).isEqualTo(100);
|
||||
ZonedDateTime expires = cookie.getExpires();
|
||||
assertThat(expires).isNotNull();
|
||||
assertThat(expires.format(DateTimeFormatter.RFC_1123_DATE_TIME)).isEqualTo("Mon, 7 Oct 2019 20:11:40 GMT");
|
||||
}
|
||||
|
||||
// --- secure ---
|
||||
|
||||
@Test
|
||||
public void writeCookieDefaultInsecureRequest() {
|
||||
void writeCookieDefaultInsecureRequest() {
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSecure()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieSecureSecureRequest() {
|
||||
void writeCookieSecureSecureRequest() {
|
||||
this.request.setSecure(true);
|
||||
this.serializer.setUseSecureCookie(true);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSecure()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieSecureInsecureRequest() {
|
||||
void writeCookieSecureInsecureRequest() {
|
||||
this.serializer.setUseSecureCookie(true);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSecure()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieInsecureSecureRequest() {
|
||||
void writeCookieInsecureSecureRequest() {
|
||||
this.request.setSecure(true);
|
||||
this.serializer.setUseSecureCookie(false);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSecure()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieInecureInsecureRequest() {
|
||||
void writeCookieInecureInsecureRequest() {
|
||||
this.serializer.setUseSecureCookie(false);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSecure()).isFalse();
|
||||
}
|
||||
|
||||
// --- jvmRoute ---
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void writeCookieJvmRoute(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void writeCookieJvmRoute(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
String jvmRoute = "route";
|
||||
this.serializer.setJvmRoute(jvmRoute);
|
||||
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookieValue(useBase64Encoding))
|
||||
.isEqualTo(this.sessionId + "." + jvmRoute);
|
||||
assertThat(getCookieValue(useBase64Encoding)).isEqualTo(this.sessionId + "." + jvmRoute);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieJvmRoute(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieJvmRoute(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
String jvmRoute = "route";
|
||||
this.serializer.setJvmRoute(jvmRoute);
|
||||
this.request.setCookies(createCookie(this.cookieName,
|
||||
this.sessionId + "." + jvmRoute, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request))
|
||||
.containsOnly(this.sessionId);
|
||||
this.request.setCookies(createCookie(this.cookieName, this.sessionId + "." + jvmRoute, useBase64Encoding));
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsOnly(this.sessionId);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieJvmRouteRouteMissing(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieJvmRouteRouteMissing(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
String jvmRoute = "route";
|
||||
this.serializer.setJvmRoute(jvmRoute);
|
||||
this.request.setCookies(
|
||||
createCookie(this.cookieName, this.sessionId, useBase64Encoding));
|
||||
|
||||
assertThat(this.serializer.readCookieValues(this.request))
|
||||
.containsOnly(this.sessionId);
|
||||
this.request.setCookies(createCookie(this.cookieName, this.sessionId, useBase64Encoding));
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsOnly(this.sessionId);
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = { "true", "false" })
|
||||
public void readCookieJvmRouteOnlyRoute(boolean useBase64Encoding) {
|
||||
@ValueSource(booleans = { true, false })
|
||||
void readCookieJvmRouteOnlyRoute(boolean useBase64Encoding) {
|
||||
this.serializer.setUseBase64Encoding(useBase64Encoding);
|
||||
String jvmRoute = "route";
|
||||
this.serializer.setJvmRoute(jvmRoute);
|
||||
this.request.setCookies(
|
||||
createCookie(this.cookieName, "." + jvmRoute, useBase64Encoding));
|
||||
|
||||
this.request.setCookies(createCookie(this.cookieName, "." + jvmRoute, useBase64Encoding));
|
||||
assertThat(this.serializer.readCookieValues(this.request)).containsOnly("");
|
||||
}
|
||||
|
||||
// --- rememberMe ---
|
||||
|
||||
@Test
|
||||
public void writeCookieRememberMeCookieMaxAgeDefault() {
|
||||
void writeCookieRememberMeCookieMaxAgeDefault() {
|
||||
this.request.setAttribute("rememberMe", true);
|
||||
this.serializer.setRememberMeRequestAttribute("rememberMe");
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getMaxAge()).isEqualTo(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieRememberMeCookieMaxAgeOverride() {
|
||||
void writeCookieRememberMeCookieMaxAgeOverride() {
|
||||
this.request.setAttribute("rememberMe", true);
|
||||
this.serializer.setRememberMeRequestAttribute("rememberMe");
|
||||
CookieValue cookieValue = cookieValue(this.sessionId);
|
||||
cookieValue.setCookieMaxAge(100);
|
||||
this.serializer.writeCookieValue(cookieValue);
|
||||
|
||||
assertThat(getCookie().getMaxAge()).isEqualTo(100);
|
||||
}
|
||||
|
||||
// --- sameSite ---
|
||||
|
||||
@Test
|
||||
public void writeCookieDefaultSameSiteLax() {
|
||||
void writeCookieDefaultSameSiteLax() {
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSameSite()).isEqualTo("Lax");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieSetSameSiteLax() {
|
||||
void writeCookieSetSameSiteLax() {
|
||||
this.serializer.setSameSite("Lax");
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSameSite()).isEqualTo("Lax");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieSetSameSiteStrict() {
|
||||
void writeCookieSetSameSiteStrict() {
|
||||
this.serializer.setSameSite("Strict");
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSameSite()).isEqualTo("Strict");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void writeCookieSetSameSiteNull() {
|
||||
void writeCookieSetSameSiteNull() {
|
||||
this.serializer.setSameSite(null);
|
||||
this.serializer.writeCookieValue(cookieValue(this.sessionId));
|
||||
|
||||
assertThat(getCookie().getSameSite()).isNull();
|
||||
}
|
||||
|
||||
public void setCookieName(String cookieName) {
|
||||
void setCookieName(String cookieName) {
|
||||
this.cookieName = cookieName;
|
||||
this.serializer.setCookieName(cookieName);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException
|
||||
/**
|
||||
* Tests for {@link HeaderHttpSessionIdResolver}.
|
||||
*/
|
||||
public class HeaderHttpSessionIdResolverTests {
|
||||
class HeaderHttpSessionIdResolverTests {
|
||||
|
||||
private static final String HEADER_X_AUTH_TOKEN = "X-Auth-Token";
|
||||
|
||||
@@ -43,71 +43,64 @@ public class HeaderHttpSessionIdResolverTests {
|
||||
private HeaderHttpSessionIdResolver resolver;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.request = new MockHttpServletRequest();
|
||||
this.response = new MockHttpServletResponse();
|
||||
this.resolver = HeaderHttpSessionIdResolver.xAuthToken();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createResolverWithXAuthTokenHeader() {
|
||||
void createResolverWithXAuthTokenHeader() {
|
||||
HeaderHttpSessionIdResolver resolver = HeaderHttpSessionIdResolver.xAuthToken();
|
||||
assertThat(ReflectionTestUtils.getField(resolver, "headerName"))
|
||||
.isEqualTo("X-Auth-Token");
|
||||
assertThat(ReflectionTestUtils.getField(resolver, "headerName")).isEqualTo("X-Auth-Token");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createResolverWithAuthenticationInfoHeader() {
|
||||
HeaderHttpSessionIdResolver resolver = HeaderHttpSessionIdResolver
|
||||
.authenticationInfo();
|
||||
assertThat(ReflectionTestUtils.getField(resolver, "headerName"))
|
||||
.isEqualTo("Authentication-Info");
|
||||
void createResolverWithAuthenticationInfoHeader() {
|
||||
HeaderHttpSessionIdResolver resolver = HeaderHttpSessionIdResolver.authenticationInfo();
|
||||
assertThat(ReflectionTestUtils.getField(resolver, "headerName")).isEqualTo("Authentication-Info");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createResolverWithCustomHeaderName() {
|
||||
HeaderHttpSessionIdResolver resolver = new HeaderHttpSessionIdResolver(
|
||||
"Custom-Header");
|
||||
assertThat(ReflectionTestUtils.getField(resolver, "headerName"))
|
||||
.isEqualTo("Custom-Header");
|
||||
void createResolverWithCustomHeaderName() {
|
||||
HeaderHttpSessionIdResolver resolver = new HeaderHttpSessionIdResolver("Custom-Header");
|
||||
assertThat(ReflectionTestUtils.getField(resolver, "headerName")).isEqualTo("Custom-Header");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createResolverWithNullHeaderName() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new HeaderHttpSessionIdResolver(null))
|
||||
void createResolverWithNullHeaderName() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new HeaderHttpSessionIdResolver(null))
|
||||
.withMessage("headerName cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestedSessionIdNull() {
|
||||
void getRequestedSessionIdNull() {
|
||||
assertThat(this.resolver.resolveSessionIds(this.request)).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getRequestedSessionIdNotNull() {
|
||||
void getRequestedSessionIdNotNull() {
|
||||
String sessionId = UUID.randomUUID().toString();
|
||||
setSessionId(sessionId);
|
||||
assertThat(this.resolver.resolveSessionIds(this.request))
|
||||
.isEqualTo(Collections.singletonList(sessionId));
|
||||
assertThat(this.resolver.resolveSessionIds(this.request)).isEqualTo(Collections.singletonList(sessionId));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onNewSession() {
|
||||
void onNewSession() {
|
||||
String sessionId = UUID.randomUUID().toString();
|
||||
this.resolver.setSessionId(this.request, this.response, sessionId);
|
||||
assertThat(getSessionId()).isEqualTo(sessionId);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onDeleteSession() {
|
||||
void onDeleteSession() {
|
||||
this.resolver.expireSession(this.request, this.response);
|
||||
assertThat(getSessionId()).isEmpty();
|
||||
}
|
||||
|
||||
// the header is set as apposed to added
|
||||
@Test
|
||||
public void onNewSessionMulti() {
|
||||
void onNewSessionMulti() {
|
||||
String sessionId = UUID.randomUUID().toString();
|
||||
this.resolver.setSessionId(this.request, this.response, sessionId);
|
||||
this.resolver.setSessionId(this.request, this.response, sessionId);
|
||||
@@ -117,7 +110,7 @@ public class HeaderHttpSessionIdResolverTests {
|
||||
|
||||
// the header is set as apposed to added
|
||||
@Test
|
||||
public void onDeleteSessionMulti() {
|
||||
void onDeleteSessionMulti() {
|
||||
this.resolver.expireSession(this.request, this.response);
|
||||
this.resolver.expireSession(this.request, this.response);
|
||||
assertThat(this.response.getHeaders(HEADER_X_AUTH_TOKEN).size()).isEqualTo(1);
|
||||
|
||||
@@ -18,6 +18,7 @@ package org.springframework.session.web.http;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.servlet.ServletOutputStream;
|
||||
@@ -32,22 +33,25 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class OnCommittedResponseWrapperTests {
|
||||
class OnCommittedResponseWrapperTests {
|
||||
|
||||
private static final String NL = "\r\n";
|
||||
|
||||
@Mock
|
||||
HttpServletResponse delegate;
|
||||
|
||||
@Mock
|
||||
PrintWriter writer;
|
||||
|
||||
@Mock
|
||||
ServletOutputStream out;
|
||||
|
||||
OnCommittedResponseWrapper response;
|
||||
private OnCommittedResponseWrapper response;
|
||||
|
||||
boolean committed;
|
||||
private boolean committed;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() throws Exception {
|
||||
void setup() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.response = new OnCommittedResponseWrapper(this.delegate) {
|
||||
@Override
|
||||
@@ -62,14 +66,14 @@ public class OnCommittedResponseWrapperTests {
|
||||
// --- printwriter
|
||||
|
||||
@Test
|
||||
public void printWriterHashCode() throws Exception {
|
||||
void printWriterHashCode() throws Exception {
|
||||
int expected = this.writer.hashCode();
|
||||
|
||||
assertThat(this.response.getWriter().hashCode()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterCheckError() throws Exception {
|
||||
void printWriterCheckError() throws Exception {
|
||||
boolean expected = true;
|
||||
given(this.writer.checkError()).willReturn(expected);
|
||||
|
||||
@@ -77,7 +81,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteInt() throws Exception {
|
||||
void printWriterWriteInt() throws Exception {
|
||||
int expected = 1;
|
||||
|
||||
this.response.getWriter().write(expected);
|
||||
@@ -86,7 +90,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteCharIntInt() throws Exception {
|
||||
void printWriterWriteCharIntInt() throws Exception {
|
||||
char[] buff = new char[0];
|
||||
int off = 2;
|
||||
int len = 3;
|
||||
@@ -97,7 +101,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteChar() throws Exception {
|
||||
void printWriterWriteChar() throws Exception {
|
||||
char[] buff = new char[0];
|
||||
|
||||
this.response.getWriter().write(buff);
|
||||
@@ -106,7 +110,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteStringIntInt() throws Exception {
|
||||
void printWriterWriteStringIntInt() throws Exception {
|
||||
String s = "";
|
||||
int off = 2;
|
||||
int len = 3;
|
||||
@@ -117,7 +121,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteString() throws Exception {
|
||||
void printWriterWriteString() throws Exception {
|
||||
String s = "";
|
||||
|
||||
this.response.getWriter().write(s);
|
||||
@@ -126,7 +130,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintBoolean() throws Exception {
|
||||
void printWriterPrintBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
this.response.getWriter().print(b);
|
||||
@@ -135,7 +139,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintChar() throws Exception {
|
||||
void printWriterPrintChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
this.response.getWriter().print(c);
|
||||
@@ -144,7 +148,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintInt() throws Exception {
|
||||
void printWriterPrintInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
this.response.getWriter().print(i);
|
||||
@@ -153,7 +157,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintLong() throws Exception {
|
||||
void printWriterPrintLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
this.response.getWriter().print(l);
|
||||
@@ -162,7 +166,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintFloat() throws Exception {
|
||||
void printWriterPrintFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
this.response.getWriter().print(f);
|
||||
@@ -171,7 +175,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintDouble() throws Exception {
|
||||
void printWriterPrintDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
this.response.getWriter().print(x);
|
||||
@@ -180,7 +184,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintCharArray() throws Exception {
|
||||
void printWriterPrintCharArray() throws Exception {
|
||||
char[] x = new char[0];
|
||||
|
||||
this.response.getWriter().print(x);
|
||||
@@ -189,7 +193,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintString() throws Exception {
|
||||
void printWriterPrintString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
this.response.getWriter().print(x);
|
||||
@@ -198,7 +202,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintObject() throws Exception {
|
||||
void printWriterPrintObject() throws Exception {
|
||||
Object x = "1";
|
||||
|
||||
this.response.getWriter().print(x);
|
||||
@@ -207,14 +211,14 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintln() throws Exception {
|
||||
void printWriterPrintln() throws Exception {
|
||||
this.response.getWriter().println();
|
||||
|
||||
verify(this.writer).println();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnBoolean() throws Exception {
|
||||
void printWriterPrintlnBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
this.response.getWriter().println(b);
|
||||
@@ -223,7 +227,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnChar() throws Exception {
|
||||
void printWriterPrintlnChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
this.response.getWriter().println(c);
|
||||
@@ -232,7 +236,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnInt() throws Exception {
|
||||
void printWriterPrintlnInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
this.response.getWriter().println(i);
|
||||
@@ -241,7 +245,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnLong() throws Exception {
|
||||
void printWriterPrintlnLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
this.response.getWriter().println(l);
|
||||
@@ -250,7 +254,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnFloat() throws Exception {
|
||||
void printWriterPrintlnFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
this.response.getWriter().println(f);
|
||||
@@ -259,7 +263,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnDouble() throws Exception {
|
||||
void printWriterPrintlnDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
this.response.getWriter().println(x);
|
||||
@@ -268,7 +272,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnCharArray() throws Exception {
|
||||
void printWriterPrintlnCharArray() throws Exception {
|
||||
char[] x = new char[0];
|
||||
|
||||
this.response.getWriter().println(x);
|
||||
@@ -277,7 +281,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnString() throws Exception {
|
||||
void printWriterPrintlnString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
this.response.getWriter().println(x);
|
||||
@@ -286,7 +290,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintlnObject() throws Exception {
|
||||
void printWriterPrintlnObject() throws Exception {
|
||||
Object x = "1";
|
||||
|
||||
this.response.getWriter().println(x);
|
||||
@@ -295,7 +299,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintfStringObjectVargs() throws Exception {
|
||||
void printWriterPrintfStringObjectVargs() throws Exception {
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
|
||||
@@ -305,7 +309,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterPrintfLocaleStringObjectVargs() throws Exception {
|
||||
void printWriterPrintfLocaleStringObjectVargs() throws Exception {
|
||||
Locale l = Locale.US;
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
@@ -316,7 +320,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterFormatStringObjectVargs() throws Exception {
|
||||
void printWriterFormatStringObjectVargs() throws Exception {
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
|
||||
@@ -326,7 +330,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterFormatLocaleStringObjectVargs() throws Exception {
|
||||
void printWriterFormatLocaleStringObjectVargs() throws Exception {
|
||||
Locale l = Locale.US;
|
||||
String format = "format";
|
||||
Object[] args = new Object[] { "1" };
|
||||
@@ -337,7 +341,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterAppendCharSequence() throws Exception {
|
||||
void printWriterAppendCharSequence() throws Exception {
|
||||
String x = "a";
|
||||
|
||||
this.response.getWriter().append(x);
|
||||
@@ -346,7 +350,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterAppendCharSequenceIntInt() throws Exception {
|
||||
void printWriterAppendCharSequenceIntInt() throws Exception {
|
||||
String x = "abcdef";
|
||||
int start = 1;
|
||||
int end = 3;
|
||||
@@ -357,7 +361,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterAppendChar() throws Exception {
|
||||
void printWriterAppendChar() throws Exception {
|
||||
char x = 1;
|
||||
|
||||
this.response.getWriter().append(x);
|
||||
@@ -368,14 +372,14 @@ public class OnCommittedResponseWrapperTests {
|
||||
// servletoutputstream
|
||||
|
||||
@Test
|
||||
public void outputStreamHashCode() throws Exception {
|
||||
void outputStreamHashCode() throws Exception {
|
||||
int expected = this.out.hashCode();
|
||||
|
||||
assertThat(this.response.getOutputStream().hashCode()).isEqualTo(expected);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamWriteInt() throws Exception {
|
||||
void outputStreamWriteInt() throws Exception {
|
||||
int expected = 1;
|
||||
|
||||
this.response.getOutputStream().write(expected);
|
||||
@@ -384,7 +388,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamWriteByte() throws Exception {
|
||||
void outputStreamWriteByte() throws Exception {
|
||||
byte[] expected = new byte[0];
|
||||
|
||||
this.response.getOutputStream().write(expected);
|
||||
@@ -393,7 +397,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamWriteByteIntInt() throws Exception {
|
||||
void outputStreamWriteByteIntInt() throws Exception {
|
||||
int start = 1;
|
||||
int end = 2;
|
||||
byte[] expected = new byte[0];
|
||||
@@ -404,7 +408,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintBoolean() throws Exception {
|
||||
void outputStreamPrintBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
this.response.getOutputStream().print(b);
|
||||
@@ -413,7 +417,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintChar() throws Exception {
|
||||
void outputStreamPrintChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
this.response.getOutputStream().print(c);
|
||||
@@ -422,7 +426,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintInt() throws Exception {
|
||||
void outputStreamPrintInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
this.response.getOutputStream().print(i);
|
||||
@@ -431,7 +435,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintLong() throws Exception {
|
||||
void outputStreamPrintLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
this.response.getOutputStream().print(l);
|
||||
@@ -440,7 +444,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintFloat() throws Exception {
|
||||
void outputStreamPrintFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
this.response.getOutputStream().print(f);
|
||||
@@ -449,7 +453,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintDouble() throws Exception {
|
||||
void outputStreamPrintDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
this.response.getOutputStream().print(x);
|
||||
@@ -458,7 +462,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintString() throws Exception {
|
||||
void outputStreamPrintString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
this.response.getOutputStream().print(x);
|
||||
@@ -467,14 +471,14 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintln() throws Exception {
|
||||
void outputStreamPrintln() throws Exception {
|
||||
this.response.getOutputStream().println();
|
||||
|
||||
verify(this.out).println();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnBoolean() throws Exception {
|
||||
void outputStreamPrintlnBoolean() throws Exception {
|
||||
boolean b = true;
|
||||
|
||||
this.response.getOutputStream().println(b);
|
||||
@@ -483,7 +487,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnChar() throws Exception {
|
||||
void outputStreamPrintlnChar() throws Exception {
|
||||
char c = 1;
|
||||
|
||||
this.response.getOutputStream().println(c);
|
||||
@@ -492,7 +496,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnInt() throws Exception {
|
||||
void outputStreamPrintlnInt() throws Exception {
|
||||
int i = 1;
|
||||
|
||||
this.response.getOutputStream().println(i);
|
||||
@@ -501,7 +505,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnLong() throws Exception {
|
||||
void outputStreamPrintlnLong() throws Exception {
|
||||
long l = 1;
|
||||
|
||||
this.response.getOutputStream().println(l);
|
||||
@@ -510,7 +514,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnFloat() throws Exception {
|
||||
void outputStreamPrintlnFloat() throws Exception {
|
||||
float f = 1;
|
||||
|
||||
this.response.getOutputStream().println(f);
|
||||
@@ -519,7 +523,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnDouble() throws Exception {
|
||||
void outputStreamPrintlnDouble() throws Exception {
|
||||
double x = 1;
|
||||
|
||||
this.response.getOutputStream().println(x);
|
||||
@@ -528,7 +532,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void outputStreamPrintlnString() throws Exception {
|
||||
void outputStreamPrintlnString() throws Exception {
|
||||
String x = "1";
|
||||
|
||||
this.response.getOutputStream().println(x);
|
||||
@@ -540,7 +544,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
// has been greater than zero and has been written to the response.
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterWriteIntCommits() throws Exception {
|
||||
void contentLengthPrintWriterWriteIntCommits() throws Exception {
|
||||
int expected = 1;
|
||||
this.response.setContentLength(String.valueOf(expected).length());
|
||||
|
||||
@@ -550,7 +554,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterWriteIntMultiDigitCommits() throws Exception {
|
||||
void contentLengthPrintWriterWriteIntMultiDigitCommits() throws Exception {
|
||||
int expected = 10000;
|
||||
this.response.setContentLength(String.valueOf(expected).length());
|
||||
|
||||
@@ -560,8 +564,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPlus1PrintWriterWriteIntMultiDigitCommits()
|
||||
throws Exception {
|
||||
void contentLengthPlus1PrintWriterWriteIntMultiDigitCommits() throws Exception {
|
||||
int expected = 10000;
|
||||
this.response.setContentLength(String.valueOf(expected).length() + 1);
|
||||
|
||||
@@ -575,7 +578,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterWriteCharIntIntCommits() throws Exception {
|
||||
void contentLengthPrintWriterWriteCharIntIntCommits() throws Exception {
|
||||
char[] buff = new char[0];
|
||||
int off = 2;
|
||||
int len = 3;
|
||||
@@ -587,7 +590,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterWriteCharCommits() throws Exception {
|
||||
void contentLengthPrintWriterWriteCharCommits() throws Exception {
|
||||
char[] buff = new char[4];
|
||||
this.response.setContentLength(buff.length);
|
||||
|
||||
@@ -597,7 +600,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterWriteStringIntIntCommits() throws Exception {
|
||||
void contentLengthPrintWriterWriteStringIntIntCommits() throws Exception {
|
||||
String s = "";
|
||||
int off = 2;
|
||||
int len = 3;
|
||||
@@ -609,7 +612,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterWriteStringCommits() throws IOException {
|
||||
void contentLengthPrintWriterWriteStringCommits() throws IOException {
|
||||
String body = "something";
|
||||
this.response.setContentLength(body.length());
|
||||
|
||||
@@ -619,7 +622,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteStringContentLengthCommits() throws IOException {
|
||||
void printWriterWriteStringContentLengthCommits() throws IOException {
|
||||
String body = "something";
|
||||
this.response.getWriter().write(body);
|
||||
|
||||
@@ -629,7 +632,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void printWriterWriteStringDoesNotCommit() throws IOException {
|
||||
void printWriterWriteStringDoesNotCommit() throws IOException {
|
||||
String body = "something";
|
||||
|
||||
this.response.getWriter().write(body);
|
||||
@@ -638,7 +641,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintBooleanCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintBooleanCommits() throws Exception {
|
||||
boolean b = true;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -648,7 +651,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintCharCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintCharCommits() throws Exception {
|
||||
char c = 1;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -658,7 +661,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintIntCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintIntCommits() throws Exception {
|
||||
int i = 1234;
|
||||
this.response.setContentLength(String.valueOf(i).length());
|
||||
|
||||
@@ -668,7 +671,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintLongCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintLongCommits() throws Exception {
|
||||
long l = 12345;
|
||||
this.response.setContentLength(String.valueOf(l).length());
|
||||
|
||||
@@ -678,7 +681,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintFloatCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintFloatCommits() throws Exception {
|
||||
float f = 12345;
|
||||
this.response.setContentLength(String.valueOf(f).length());
|
||||
|
||||
@@ -688,7 +691,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintDoubleCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintDoubleCommits() throws Exception {
|
||||
double x = 1.2345;
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
|
||||
@@ -698,7 +701,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintCharArrayCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintCharArrayCommits() throws Exception {
|
||||
char[] x = new char[10];
|
||||
this.response.setContentLength(x.length);
|
||||
|
||||
@@ -708,7 +711,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintStringCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintStringCommits() throws Exception {
|
||||
String x = "12345";
|
||||
this.response.setContentLength(x.length());
|
||||
|
||||
@@ -718,7 +721,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintObjectCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintObjectCommits() throws Exception {
|
||||
Object x = "12345";
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
|
||||
@@ -728,7 +731,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnCommits() throws Exception {
|
||||
this.response.setContentLength(NL.length());
|
||||
|
||||
this.response.getWriter().println();
|
||||
@@ -737,7 +740,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnBooleanCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnBooleanCommits() throws Exception {
|
||||
boolean b = true;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -747,7 +750,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnCharCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnCharCommits() throws Exception {
|
||||
char c = 1;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -757,7 +760,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnIntCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnIntCommits() throws Exception {
|
||||
int i = 12345;
|
||||
this.response.setContentLength(String.valueOf(i).length());
|
||||
|
||||
@@ -767,7 +770,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnLongCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnLongCommits() throws Exception {
|
||||
long l = 12345678;
|
||||
this.response.setContentLength(String.valueOf(l).length());
|
||||
|
||||
@@ -777,7 +780,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnFloatCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnFloatCommits() throws Exception {
|
||||
float f = 1234;
|
||||
this.response.setContentLength(String.valueOf(f).length());
|
||||
|
||||
@@ -787,7 +790,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnDoubleCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnDoubleCommits() throws Exception {
|
||||
double x = 1;
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
|
||||
@@ -797,7 +800,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnCharArrayCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnCharArrayCommits() throws Exception {
|
||||
char[] x = new char[20];
|
||||
this.response.setContentLength(x.length);
|
||||
|
||||
@@ -807,9 +810,9 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnStringCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnStringCommits() throws Exception {
|
||||
String x = "1";
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
this.response.setContentLength(x.length());
|
||||
|
||||
this.response.getWriter().println(x);
|
||||
|
||||
@@ -817,7 +820,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterPrintlnObjectCommits() throws Exception {
|
||||
void contentLengthPrintWriterPrintlnObjectCommits() throws Exception {
|
||||
Object x = "1";
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
|
||||
@@ -827,9 +830,9 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterAppendCharSequenceCommits() throws Exception {
|
||||
void contentLengthPrintWriterAppendCharSequenceCommits() throws Exception {
|
||||
String x = "a";
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
this.response.setContentLength(x.length());
|
||||
|
||||
this.response.getWriter().append(x);
|
||||
|
||||
@@ -837,8 +840,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterAppendCharSequenceIntIntCommits()
|
||||
throws Exception {
|
||||
void contentLengthPrintWriterAppendCharSequenceIntIntCommits() throws Exception {
|
||||
String x = "abcdef";
|
||||
int start = 1;
|
||||
int end = 3;
|
||||
@@ -850,7 +852,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPrintWriterAppendCharCommits() throws Exception {
|
||||
void contentLengthPrintWriterAppendCharCommits() throws Exception {
|
||||
char x = 1;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -860,7 +862,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamWriteIntCommits() throws Exception {
|
||||
void contentLengthOutputStreamWriteIntCommits() throws Exception {
|
||||
int expected = 1;
|
||||
this.response.setContentLength(String.valueOf(expected).length());
|
||||
|
||||
@@ -870,7 +872,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamWriteIntMultiDigitCommits() throws Exception {
|
||||
void contentLengthOutputStreamWriteIntMultiDigitCommits() throws Exception {
|
||||
int expected = 10000;
|
||||
this.response.setContentLength(String.valueOf(expected).length());
|
||||
|
||||
@@ -880,8 +882,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthPlus1OutputStreamWriteIntMultiDigitCommits()
|
||||
throws Exception {
|
||||
void contentLengthPlus1OutputStreamWriteIntMultiDigitCommits() throws Exception {
|
||||
int expected = 10000;
|
||||
this.response.setContentLength(String.valueOf(expected).length() + 1);
|
||||
|
||||
@@ -896,24 +897,23 @@ public class OnCommittedResponseWrapperTests {
|
||||
|
||||
// gh-171
|
||||
@Test
|
||||
public void contentLengthPlus1OutputStreamWriteByteArrayMultiDigitCommits()
|
||||
throws Exception {
|
||||
void contentLengthPlus1OutputStreamWriteByteArrayMultiDigitCommits() throws Exception {
|
||||
String expected = "{\n" + " \"parameterName\" : \"_csrf\",\n"
|
||||
+ " \"token\" : \"06300b65-c4aa-4c8f-8cda-39ee17f545a0\",\n"
|
||||
+ " \"headerName\" : \"X-CSRF-TOKEN\"\n" + "}";
|
||||
+ " \"token\" : \"06300b65-c4aa-4c8f-8cda-39ee17f545a0\",\n" + " \"headerName\" : \"X-CSRF-TOKEN\"\n"
|
||||
+ "}";
|
||||
this.response.setContentLength(expected.length() + 1);
|
||||
|
||||
this.response.getOutputStream().write(expected.getBytes());
|
||||
|
||||
assertThat(this.committed).isFalse();
|
||||
|
||||
this.response.getOutputStream().write("1".getBytes("UTF-8"));
|
||||
this.response.getOutputStream().write("1".getBytes(StandardCharsets.UTF_8));
|
||||
|
||||
assertThat(this.committed).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintBooleanCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintBooleanCommits() throws Exception {
|
||||
boolean b = true;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -923,7 +923,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintCharCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintCharCommits() throws Exception {
|
||||
char c = 1;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -933,7 +933,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintIntCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintIntCommits() throws Exception {
|
||||
int i = 1234;
|
||||
this.response.setContentLength(String.valueOf(i).length());
|
||||
|
||||
@@ -943,7 +943,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintLongCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintLongCommits() throws Exception {
|
||||
long l = 12345;
|
||||
this.response.setContentLength(String.valueOf(l).length());
|
||||
|
||||
@@ -953,7 +953,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintFloatCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintFloatCommits() throws Exception {
|
||||
float f = 12345;
|
||||
this.response.setContentLength(String.valueOf(f).length());
|
||||
|
||||
@@ -963,7 +963,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintDoubleCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintDoubleCommits() throws Exception {
|
||||
double x = 1.2345;
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
|
||||
@@ -973,7 +973,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintStringCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintStringCommits() throws Exception {
|
||||
String x = "12345";
|
||||
this.response.setContentLength(x.length());
|
||||
|
||||
@@ -983,7 +983,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnCommits() throws Exception {
|
||||
this.response.setContentLength(NL.length());
|
||||
|
||||
this.response.getOutputStream().println();
|
||||
@@ -992,7 +992,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnBooleanCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnBooleanCommits() throws Exception {
|
||||
boolean b = true;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -1002,7 +1002,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnCharCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnCharCommits() throws Exception {
|
||||
char c = 1;
|
||||
this.response.setContentLength(1);
|
||||
|
||||
@@ -1012,7 +1012,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnIntCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnIntCommits() throws Exception {
|
||||
int i = 12345;
|
||||
this.response.setContentLength(String.valueOf(i).length());
|
||||
|
||||
@@ -1022,7 +1022,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnLongCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnLongCommits() throws Exception {
|
||||
long l = 12345678;
|
||||
this.response.setContentLength(String.valueOf(l).length());
|
||||
|
||||
@@ -1032,7 +1032,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnFloatCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnFloatCommits() throws Exception {
|
||||
float f = 1234;
|
||||
this.response.setContentLength(String.valueOf(f).length());
|
||||
|
||||
@@ -1042,7 +1042,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnDoubleCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnDoubleCommits() throws Exception {
|
||||
double x = 1;
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
|
||||
@@ -1052,9 +1052,9 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamPrintlnStringCommits() throws Exception {
|
||||
void contentLengthOutputStreamPrintlnStringCommits() throws Exception {
|
||||
String x = "1";
|
||||
this.response.setContentLength(String.valueOf(x).length());
|
||||
this.response.setContentLength(x.length());
|
||||
|
||||
this.response.getOutputStream().println(x);
|
||||
|
||||
@@ -1062,7 +1062,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthDoesNotCommit() throws IOException {
|
||||
void contentLengthDoesNotCommit() {
|
||||
String body = "something";
|
||||
|
||||
this.response.setContentLength(body.length());
|
||||
@@ -1071,7 +1071,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void contentLengthOutputStreamWriteStringCommits() throws IOException {
|
||||
void contentLengthOutputStreamWriteStringCommits() throws IOException {
|
||||
String body = "something";
|
||||
this.response.setContentLength(body.length());
|
||||
|
||||
@@ -1081,10 +1081,9 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void addHeaderContentLengthPrintWriterWriteStringCommits() throws Exception {
|
||||
void addHeaderContentLengthPrintWriterWriteStringCommits() throws Exception {
|
||||
int expected = 1234;
|
||||
this.response.addHeader("Content-Length",
|
||||
String.valueOf(String.valueOf(expected).length()));
|
||||
this.response.addHeader("Content-Length", String.valueOf(String.valueOf(expected).length()));
|
||||
|
||||
this.response.getWriter().write(expected);
|
||||
|
||||
@@ -1092,7 +1091,7 @@ public class OnCommittedResponseWrapperTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void bufferSizePrintWriterWriteCommits() throws Exception {
|
||||
void bufferSizePrintWriterWriteCommits() throws Exception {
|
||||
String expected = "1234567890";
|
||||
given(this.response.getBufferSize()).willReturn(expected.length());
|
||||
|
||||
@@ -1101,8 +1100,19 @@ public class OnCommittedResponseWrapperTests {
|
||||
assertThat(this.committed).isTrue();
|
||||
}
|
||||
|
||||
// gh-7261
|
||||
@Test
|
||||
public void bufferSizeCommitsOnce() throws Exception {
|
||||
void contentLengthLongOutputStreamWriteStringCommits() throws IOException {
|
||||
String body = "something";
|
||||
this.response.setContentLengthLong(body.length());
|
||||
|
||||
this.response.getOutputStream().print(body);
|
||||
|
||||
assertThat(this.committed).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
void bufferSizeCommitsOnce() throws Exception {
|
||||
String expected = "1234567890";
|
||||
given(this.response.getBufferSize()).willReturn(expected.length());
|
||||
|
||||
@@ -1116,4 +1126,5 @@ public class OnCommittedResponseWrapperTests {
|
||||
|
||||
assertThat(this.committed).isFalse();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* 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.web.http;
|
||||
|
||||
import org.aspectj.lang.annotation.AfterReturning;
|
||||
import org.aspectj.lang.annotation.Aspect;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.EnableAspectJAutoProxy;
|
||||
import org.springframework.mock.web.MockFilterChain;
|
||||
import org.springframework.mock.web.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.MockHttpServletResponse;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.web.http.OncePerRequestFilterAopTests.Config;
|
||||
import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
|
||||
@SpringJUnitConfig(classes = Config.class)
|
||||
class OncePerRequestFilterAopTests {
|
||||
|
||||
@Test
|
||||
void doFilterOnce(@Autowired final OncePerRequestFilter filter) {
|
||||
assertThatCode(() -> filter.doFilter(new MockHttpServletRequest(), new MockHttpServletResponse(),
|
||||
new MockFilterChain())).as("`doFilter` does not throw NPE with the bean is being proxied by Spring AOP")
|
||||
.doesNotThrowAnyException();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Configuration
|
||||
@EnableAspectJAutoProxy(proxyTargetClass = true)
|
||||
@Aspect
|
||||
public static class Config {
|
||||
|
||||
@Bean
|
||||
public SessionRepository sessionRepository() {
|
||||
return Mockito.mock(SessionRepository.class);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SessionRepositoryFilter filter() {
|
||||
return new SessionRepositoryFilter(sessionRepository());
|
||||
}
|
||||
|
||||
@AfterReturning("execution(* SessionRepositoryFilter.doFilterInternal(..))")
|
||||
public void doInternalFilterPointcut() {
|
||||
// no op
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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,21 +33,27 @@ import org.junit.jupiter.api.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;
|
||||
|
||||
public class OncePerRequestFilterTests {
|
||||
class OncePerRequestFilterTests {
|
||||
|
||||
private MockHttpServletRequest request;
|
||||
|
||||
private MockHttpServletResponse response;
|
||||
|
||||
private MockFilterChain chain;
|
||||
|
||||
private OncePerRequestFilter filter;
|
||||
|
||||
private HttpServlet servlet;
|
||||
|
||||
private List<OncePerRequestFilter> invocations;
|
||||
|
||||
@BeforeEach
|
||||
@SuppressWarnings("serial")
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.servlet = new HttpServlet() {
|
||||
};
|
||||
this.request = new MockHttpServletRequest();
|
||||
@@ -55,9 +62,8 @@ public class OncePerRequestFilterTests {
|
||||
this.invocations = new ArrayList<>();
|
||||
this.filter = new OncePerRequestFilter() {
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
OncePerRequestFilterTests.this.invocations.add(this);
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
@@ -65,34 +71,63 @@ public class OncePerRequestFilterTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterOnce() throws ServletException, IOException {
|
||||
void doFilterOnce() throws ServletException, IOException {
|
||||
this.filter.doFilter(this.request, this.response, this.chain);
|
||||
|
||||
assertThat(this.invocations).containsOnly(this.filter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterMultiOnlyIvokesOnce() throws ServletException, IOException {
|
||||
this.filter.doFilter(this.request, this.response,
|
||||
new MockFilterChain(this.servlet, this.filter));
|
||||
void doFilterMultiOnlyIvokesOnce() throws ServletException, IOException {
|
||||
this.filter.doFilter(this.request, this.response, new MockFilterChain(this.servlet, this.filter));
|
||||
|
||||
assertThat(this.invocations).containsOnly(this.filter);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void doFilterOtherSubclassInvoked() throws ServletException, IOException {
|
||||
void doFilterOtherSubclassInvoked() throws ServletException, IOException {
|
||||
OncePerRequestFilter filter2 = new OncePerRequestFilter() {
|
||||
@Override
|
||||
protected void doFilterInternal(HttpServletRequest request,
|
||||
HttpServletResponse response, FilterChain filterChain)
|
||||
throws ServletException, IOException {
|
||||
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response,
|
||||
FilterChain filterChain) throws ServletException, IOException {
|
||||
OncePerRequestFilterTests.this.invocations.add(this);
|
||||
filterChain.doFilter(request, response);
|
||||
}
|
||||
};
|
||||
this.filter.doFilter(this.request, this.response,
|
||||
new MockFilterChain(this.servlet, filter2));
|
||||
this.filter.doFilter(this.request, this.response, new MockFilterChain(this.servlet, filter2));
|
||||
|
||||
assertThat(this.invocations).containsOnly(this.filter, filter2);
|
||||
}
|
||||
|
||||
@Test // gh-1470
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import org.springframework.session.events.SessionDestroyedEvent;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
/**
|
||||
* Tests for {@link SessionEventHttpSessionListenerAdapter}.
|
||||
@@ -47,7 +47,7 @@ import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
* @author Rob Winch
|
||||
* @since 1.1
|
||||
*/
|
||||
public class SessionEventHttpSessionListenerAdapterTests {
|
||||
class SessionEventHttpSessionListenerAdapterTests {
|
||||
|
||||
@Mock
|
||||
private HttpSessionListener listener1;
|
||||
@@ -68,10 +68,9 @@ public class SessionEventHttpSessionListenerAdapterTests {
|
||||
private SessionEventHttpSessionListenerAdapter listener;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.listener = new SessionEventHttpSessionListenerAdapter(
|
||||
Arrays.asList(this.listener1, this.listener2));
|
||||
this.listener = new SessionEventHttpSessionListenerAdapter(Arrays.asList(this.listener1, this.listener2));
|
||||
this.listener.setServletContext(new MockServletContext());
|
||||
|
||||
Session session = new MapSession();
|
||||
@@ -83,7 +82,7 @@ public class SessionEventHttpSessionListenerAdapterTests {
|
||||
// make configuration easier (i.e. autowire all HttpSessionListeners and might get
|
||||
// none)
|
||||
@Test
|
||||
public void constructorEmptyWorks() {
|
||||
void constructorEmptyWorks() {
|
||||
new SessionEventHttpSessionListenerAdapter(Collections.emptyList());
|
||||
}
|
||||
|
||||
@@ -92,36 +91,33 @@ public class SessionEventHttpSessionListenerAdapterTests {
|
||||
* listeners
|
||||
*/
|
||||
@Test
|
||||
public void onApplicationEventEmptyListenersDoesNotUseEvent() {
|
||||
this.listener = new SessionEventHttpSessionListenerAdapter(
|
||||
Collections.emptyList());
|
||||
void onApplicationEventEmptyListenersDoesNotUseEvent() {
|
||||
this.listener = new SessionEventHttpSessionListenerAdapter(Collections.emptyList());
|
||||
this.destroyed = mock(SessionDestroyedEvent.class);
|
||||
|
||||
this.listener.onApplicationEvent(this.destroyed);
|
||||
|
||||
verifyZeroInteractions(this.destroyed, this.listener1, this.listener2);
|
||||
verifyNoMoreInteractions(this.destroyed, this.listener1, this.listener2);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventDestroyed() {
|
||||
void onApplicationEventDestroyed() {
|
||||
this.listener.onApplicationEvent(this.destroyed);
|
||||
|
||||
verify(this.listener1).sessionDestroyed(this.sessionEvent.capture());
|
||||
verify(this.listener2).sessionDestroyed(this.sessionEvent.capture());
|
||||
|
||||
assertThat(this.sessionEvent.getValue().getSession().getId())
|
||||
.isEqualTo(this.destroyed.getSessionId());
|
||||
assertThat(this.sessionEvent.getValue().getSession().getId()).isEqualTo(this.destroyed.getSessionId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventCreated() {
|
||||
void onApplicationEventCreated() {
|
||||
this.listener.onApplicationEvent(this.created);
|
||||
|
||||
verify(this.listener1).sessionCreated(this.sessionEvent.capture());
|
||||
verify(this.listener2).sessionCreated(this.sessionEvent.capture());
|
||||
|
||||
assertThat(this.sessionEvent.getValue().getSession().getId())
|
||||
.isEqualTo(this.created.getSessionId());
|
||||
assertThat(this.sessionEvent.getValue().getSession().getId()).isEqualTo(this.created.getSessionId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -43,7 +43,7 @@ import static org.mockito.Mockito.verify;
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
|
||||
@Mock
|
||||
private ReactiveSessionRepository<S> sessionRepository;
|
||||
@@ -57,68 +57,62 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
private SpringSessionWebSessionStore<S> webSessionStore;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.webSessionStore = new SpringSessionWebSessionStore<>(this.sessionRepository);
|
||||
given(this.sessionRepository.findById(any()))
|
||||
.willReturn(Mono.just(this.findByIdSession));
|
||||
given(this.sessionRepository.createSession())
|
||||
.willReturn(Mono.just(this.createSession));
|
||||
given(this.sessionRepository.findById(any())).willReturn(Mono.just(this.findByIdSession));
|
||||
given(this.sessionRepository.createSession()).willReturn(Mono.just(this.createSession));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorWhenNullRepositoryThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new SpringSessionWebSessionStore<S>(null))
|
||||
void constructorWhenNullRepositoryThenThrowsIllegalArgumentException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new SpringSessionWebSessionStore<S>(null))
|
||||
.withMessage("reactiveSessionRepository cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenNoAttributesThenNotStarted() {
|
||||
void createSessionWhenNoAttributesThenNotStarted() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
assertThat(createdWebSession.isStarted()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenAddAttributeThenStarted() {
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton("a"));
|
||||
void createSessionWhenAddAttributeThenStarted() {
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton("a"));
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
assertThat(createdWebSession.isStarted()).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndSizeThenDelegatesToCreateSession() {
|
||||
void createSessionWhenGetAttributesAndSizeThenDelegatesToCreateSession() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
|
||||
assertThat(attributes.size()).isEqualTo(0);
|
||||
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton("a"));
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton("a"));
|
||||
|
||||
assertThat(attributes.size()).isEqualTo(1);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndIsEmptyThenDelegatesToCreateSession() {
|
||||
void createSessionWhenGetAttributesAndIsEmptyThenDelegatesToCreateSession() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
|
||||
assertThat(attributes.isEmpty()).isTrue();
|
||||
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton("a"));
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton("a"));
|
||||
|
||||
assertThat(attributes.isEmpty()).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndContainsKeyAndNotStringThenFalse() {
|
||||
void createSessionWhenGetAttributesAndContainsKeyAndNotStringThenFalse() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -127,7 +121,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndContainsKeyAndNotFoundThenFalse() {
|
||||
void createSessionWhenGetAttributesAndContainsKeyAndNotFoundThenFalse() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -136,9 +130,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndContainsKeyAndFoundThenTrue() {
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton("a"));
|
||||
void createSessionWhenGetAttributesAndContainsKeyAndFoundThenTrue() {
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton("a"));
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -147,7 +140,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndPutThenDelegatesToCreateSession() {
|
||||
void createSessionWhenGetAttributesAndPutThenDelegatesToCreateSession() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -157,7 +150,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndPutNullThenDelegatesToCreateSession() {
|
||||
void createSessionWhenGetAttributesAndPutNullThenDelegatesToCreateSession() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -167,7 +160,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndRemoveThenDelegatesToCreateSession() {
|
||||
void createSessionWhenGetAttributesAndRemoveThenDelegatesToCreateSession() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -177,7 +170,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndPutAllThenDelegatesToCreateSession() {
|
||||
void createSessionWhenGetAttributesAndPutAllThenDelegatesToCreateSession() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -187,9 +180,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndClearThenDelegatesToCreateSession() {
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton("a"));
|
||||
void createSessionWhenGetAttributesAndClearThenDelegatesToCreateSession() {
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton("a"));
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -199,9 +191,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndKeySetThenDelegatesToCreateSession() {
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton("a"));
|
||||
void createSessionWhenGetAttributesAndKeySetThenDelegatesToCreateSession() {
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton("a"));
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
@@ -210,9 +201,8 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndValuesThenDelegatesToCreateSession() {
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton("a"));
|
||||
void createSessionWhenGetAttributesAndValuesThenDelegatesToCreateSession() {
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton("a"));
|
||||
given(this.createSession.getAttribute("a")).willReturn("b");
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
@@ -222,10 +212,9 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void createSessionWhenGetAttributesAndEntrySetThenDelegatesToCreateSession() {
|
||||
void createSessionWhenGetAttributesAndEntrySetThenDelegatesToCreateSession() {
|
||||
String attrName = "attrName";
|
||||
given(this.createSession.getAttributeNames())
|
||||
.willReturn(Collections.singleton(attrName));
|
||||
given(this.createSession.getAttributeNames()).willReturn(Collections.singleton(attrName));
|
||||
String attrValue = "attrValue";
|
||||
given(this.createSession.getAttribute(attrName)).willReturn(attrValue);
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
@@ -233,12 +222,11 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
Map<String, Object> attributes = createdWebSession.getAttributes();
|
||||
Set<Map.Entry<String, Object>> entries = attributes.entrySet();
|
||||
|
||||
assertThat(entries)
|
||||
.containsExactly(new AbstractMap.SimpleEntry<>(attrName, attrValue));
|
||||
assertThat(entries).containsExactly(new AbstractMap.SimpleEntry<>(attrName, attrValue));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void retrieveSessionThenStarted() {
|
||||
void retrieveSessionThenStarted() {
|
||||
String id = "id";
|
||||
WebSession retrievedWebSession = this.webSessionStore.retrieveSession(id).block();
|
||||
|
||||
@@ -247,7 +235,7 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void removeSessionWhenInvokedThenSessionSaved() {
|
||||
void removeSessionWhenInvokedThenSessionSaved() {
|
||||
String sessionId = "session-id";
|
||||
given(this.sessionRepository.deleteById(sessionId)).willReturn(Mono.empty());
|
||||
|
||||
@@ -257,21 +245,20 @@ public class SpringSessionWebSessionStoreTests<S extends Session> {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setClockWhenNullThenException() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.webSessionStore.setClock(null))
|
||||
void setClockWhenNullThenException() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.webSessionStore.setClock(null))
|
||||
.withMessage("clock cannot be null");
|
||||
}
|
||||
|
||||
@Test // gh-1114
|
||||
public void createSessionThenSessionIsNotExpired() {
|
||||
void createSessionThenSessionIsNotExpired() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
|
||||
assertThat(createdWebSession.isExpired()).isFalse();
|
||||
}
|
||||
|
||||
@Test // gh-1114
|
||||
public void invalidateSessionThenSessionIsExpired() {
|
||||
void invalidateSessionThenSessionIsExpired() {
|
||||
WebSession createdWebSession = this.webSessionStore.createWebSession().block();
|
||||
given(createdWebSession.invalidate()).willReturn(Mono.empty());
|
||||
|
||||
|
||||
@@ -35,33 +35,36 @@ import static org.mockito.BDDMockito.willThrow;
|
||||
import static org.mockito.Mockito.any;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class WebSocketConnectHandlerDecoratorFactoryTests {
|
||||
class WebSocketConnectHandlerDecoratorFactoryTests {
|
||||
|
||||
@Mock
|
||||
ApplicationEventPublisher eventPublisher;
|
||||
|
||||
@Mock
|
||||
WebSocketHandler delegate;
|
||||
|
||||
@Mock
|
||||
WebSocketSession session;
|
||||
|
||||
@Captor
|
||||
ArgumentCaptor<SessionConnectEvent> event;
|
||||
|
||||
WebSocketConnectHandlerDecoratorFactory factory;
|
||||
private WebSocketConnectHandlerDecoratorFactory factory;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.factory = new WebSocketConnectHandlerDecoratorFactory(this.eventPublisher);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void constructorNullEventPublisher() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new WebSocketConnectHandlerDecoratorFactory(null))
|
||||
void constructorNullEventPublisher() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new WebSocketConnectHandlerDecoratorFactory(null))
|
||||
.withMessage("eventPublisher cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decorateAfterConnectionEstablished() throws Exception {
|
||||
void decorateAfterConnectionEstablished() throws Exception {
|
||||
WebSocketHandler decorated = this.factory.decorate(this.delegate);
|
||||
|
||||
decorated.afterConnectionEstablished(this.session);
|
||||
@@ -71,13 +74,14 @@ public class WebSocketConnectHandlerDecoratorFactoryTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void decorateAfterConnectionEstablishedEventError() throws Exception {
|
||||
void decorateAfterConnectionEstablishedEventError() throws Exception {
|
||||
WebSocketHandler decorated = this.factory.decorate(this.delegate);
|
||||
willThrow(new IllegalStateException("Test throw on publishEvent"))
|
||||
.given(this.eventPublisher).publishEvent(any(ApplicationEvent.class));
|
||||
willThrow(new IllegalStateException("Test throw on publishEvent")).given(this.eventPublisher)
|
||||
.publishEvent(any(ApplicationEvent.class));
|
||||
|
||||
decorated.afterConnectionEstablished(this.session);
|
||||
|
||||
verify(this.eventPublisher).publishEvent(any(SessionConnectEvent.class));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,7 +44,7 @@ import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
public class WebSocketRegistryListenerTests {
|
||||
class WebSocketRegistryListenerTests {
|
||||
|
||||
@Mock
|
||||
private WebSocketSession wsSession;
|
||||
@@ -73,7 +73,7 @@ public class WebSocketRegistryListenerTests {
|
||||
private WebSocketRegistryListener listener;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
String sessionId = "session-id";
|
||||
MapSession session = new MapSession(sessionId);
|
||||
@@ -96,14 +96,14 @@ public class WebSocketRegistryListenerTests {
|
||||
this.listener = new WebSocketRegistryListener();
|
||||
this.connect = new SessionConnectEvent(this.listener, this.wsSession);
|
||||
this.connect2 = new SessionConnectEvent(this.listener, this.wsSession2);
|
||||
this.disconnect = new SessionDisconnectEvent(this.listener, this.message,
|
||||
this.wsSession.getId(), CloseStatus.NORMAL);
|
||||
this.disconnect = new SessionDisconnectEvent(this.listener, this.message, this.wsSession.getId(),
|
||||
CloseStatus.NORMAL);
|
||||
this.deleted = new SessionDeletedEvent(this.listener, session);
|
||||
this.expired = new SessionExpiredEvent(this.listener, session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventConnectSessionDeleted() throws Exception {
|
||||
void onApplicationEventConnectSessionDeleted() throws Exception {
|
||||
this.listener.onApplicationEvent(this.connect);
|
||||
|
||||
this.listener.onApplicationEvent(this.deleted);
|
||||
@@ -112,7 +112,7 @@ public class WebSocketRegistryListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventConnectSessionExpired() throws Exception {
|
||||
void onApplicationEventConnectSessionExpired() throws Exception {
|
||||
this.listener.onApplicationEvent(this.connect);
|
||||
|
||||
this.listener.onApplicationEvent(this.expired);
|
||||
@@ -121,7 +121,7 @@ public class WebSocketRegistryListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventConnectSessionDeletedNullPrincipal() throws Exception {
|
||||
void onApplicationEventConnectSessionDeletedNullPrincipal() throws Exception {
|
||||
given(this.wsSession.getPrincipal()).willReturn(null);
|
||||
this.listener.onApplicationEvent(this.connect);
|
||||
|
||||
@@ -131,7 +131,7 @@ public class WebSocketRegistryListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventConnectDisconnect() throws Exception {
|
||||
void onApplicationEventConnectDisconnect() throws Exception {
|
||||
this.listener.onApplicationEvent(this.connect);
|
||||
this.listener.onApplicationEvent(this.disconnect);
|
||||
|
||||
@@ -143,7 +143,7 @@ public class WebSocketRegistryListenerTests {
|
||||
// gh-76
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void onApplicationEventConnectDisconnectCleanup() {
|
||||
void onApplicationEventConnectDisconnectCleanup() {
|
||||
this.listener.onApplicationEvent(this.connect);
|
||||
|
||||
this.listener.onApplicationEvent(this.disconnect);
|
||||
@@ -154,7 +154,7 @@ public class WebSocketRegistryListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventConnectDisconnectNullSession() throws Exception {
|
||||
void onApplicationEventConnectDisconnectNullSession() {
|
||||
this.listener.onApplicationEvent(this.connect);
|
||||
this.attributes.clear();
|
||||
|
||||
@@ -164,7 +164,7 @@ public class WebSocketRegistryListenerTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onApplicationEventConnectConnectDisonnect() throws Exception {
|
||||
void onApplicationEventConnectConnectDisonnect() throws Exception {
|
||||
this.listener.onApplicationEvent(this.connect);
|
||||
this.listener.onApplicationEvent(this.connect2);
|
||||
this.listener.onApplicationEvent(this.disconnect);
|
||||
|
||||
@@ -49,27 +49,29 @@ import static org.mockito.ArgumentMatchers.argThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
|
||||
class SessionRepositoryMessageInterceptorTests {
|
||||
|
||||
public class SessionRepositoryMessageInterceptorTests {
|
||||
@Mock
|
||||
SessionRepository<Session> sessionRepository;
|
||||
|
||||
@Mock
|
||||
MessageChannel channel;
|
||||
|
||||
@Mock
|
||||
Session session;
|
||||
|
||||
Message<?> createMessage;
|
||||
private Message<?> createMessage;
|
||||
|
||||
SimpMessageHeaderAccessor headers;
|
||||
private SimpMessageHeaderAccessor headers;
|
||||
|
||||
SessionRepositoryMessageInterceptor<Session> interceptor;
|
||||
private SessionRepositoryMessageInterceptor<Session> interceptor;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
this.interceptor = new SessionRepositoryMessageInterceptor<>(
|
||||
this.sessionRepository);
|
||||
this.interceptor = new SessionRepositoryMessageInterceptor<>(this.sessionRepository);
|
||||
this.headers = SimpMessageHeaderAccessor.create();
|
||||
this.headers.setSessionId("session");
|
||||
this.headers.setSessionAttributes(new HashMap<>());
|
||||
@@ -80,123 +82,112 @@ public class SessionRepositoryMessageInterceptorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendconstructorNullRepository() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> new SessionRepositoryMessageInterceptor<>(null))
|
||||
void preSendconstructorNullRepository() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> new SessionRepositoryMessageInterceptor<>(null))
|
||||
.withMessage("sessionRepository cannot be null");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendNullMessage() {
|
||||
void preSendNullMessage() {
|
||||
assertThat(this.interceptor.preSend(null, this.channel)).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendConnectAckDoesNotInvokeSessionRepository() {
|
||||
void preSendConnectAckDoesNotInvokeSessionRepository() {
|
||||
setMessageType(SimpMessageType.CONNECT_ACK);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendHeartbeatDoesNotInvokeSessionRepository() {
|
||||
void preSendHeartbeatDoesNotInvokeSessionRepository() {
|
||||
setMessageType(SimpMessageType.HEARTBEAT);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendDisconnectDoesNotInvokeSessionRepository() {
|
||||
void preSendDisconnectDoesNotInvokeSessionRepository() {
|
||||
setMessageType(SimpMessageType.DISCONNECT);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendOtherDoesNotInvokeSessionRepository() {
|
||||
void preSendOtherDoesNotInvokeSessionRepository() {
|
||||
setMessageType(SimpMessageType.OTHER);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMatchingMessageTypesNull() {
|
||||
void setMatchingMessageTypesNull() {
|
||||
assertThatIllegalArgumentException().isThrownBy(() -> this.interceptor.setMatchingMessageTypes(null))
|
||||
.withMessage("matchingMessageTypes cannot be null or empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
void setMatchingMessageTypesEmpty() {
|
||||
assertThatIllegalArgumentException()
|
||||
.isThrownBy(() -> this.interceptor.setMatchingMessageTypes(null))
|
||||
.isThrownBy(() -> this.interceptor.setMatchingMessageTypes(Collections.emptySet()))
|
||||
.withMessage("matchingMessageTypes cannot be null or empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setMatchingMessageTypesEmpty() {
|
||||
assertThatIllegalArgumentException().isThrownBy(
|
||||
() -> this.interceptor.setMatchingMessageTypes(Collections.emptySet()))
|
||||
.withMessage("matchingMessageTypes cannot be null or empty");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendSetMatchingMessageTypes() {
|
||||
void preSendSetMatchingMessageTypes() {
|
||||
this.interceptor.setMatchingMessageTypes(EnumSet.of(SimpMessageType.DISCONNECT));
|
||||
setMessageType(SimpMessageType.DISCONNECT);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verify(this.sessionRepository).findById(anyString());
|
||||
verify(this.sessionRepository).save(this.session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendConnectUpdatesLastUpdateTime() {
|
||||
void preSendConnectUpdatesLastUpdateTime() {
|
||||
setMessageType(SimpMessageType.CONNECT);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verify(this.session).setLastAccessedTime(argThat(isAlmostNow()));
|
||||
verify(this.sessionRepository).save(this.session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendMessageUpdatesLastUpdateTime() {
|
||||
void preSendMessageUpdatesLastUpdateTime() {
|
||||
setMessageType(SimpMessageType.MESSAGE);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verify(this.session).setLastAccessedTime(argThat(isAlmostNow()));
|
||||
verify(this.sessionRepository).save(this.session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendSubscribeUpdatesLastUpdateTime() {
|
||||
void preSendSubscribeUpdatesLastUpdateTime() {
|
||||
setMessageType(SimpMessageType.SUBSCRIBE);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verify(this.session).setLastAccessedTime(argThat(isAlmostNow()));
|
||||
verify(this.sessionRepository).save(this.session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendUnsubscribeUpdatesLastUpdateTime() {
|
||||
void preSendUnsubscribeUpdatesLastUpdateTime() {
|
||||
setMessageType(SimpMessageType.UNSUBSCRIBE);
|
||||
this.session.setLastAccessedTime(Instant.EPOCH);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verify(this.session).setLastAccessedTime(argThat(isAlmostNow()));
|
||||
verify(this.sessionRepository).save(this.session);
|
||||
@@ -204,7 +195,7 @@ public class SessionRepositoryMessageInterceptorTests {
|
||||
|
||||
// This will updated when SPR-12288 is resolved
|
||||
@Test
|
||||
public void preSendExpiredSession() {
|
||||
void preSendExpiredSession() {
|
||||
setSessionId("expired");
|
||||
|
||||
this.interceptor.preSend(createMessage(), this.channel);
|
||||
@@ -213,74 +204,67 @@ public class SessionRepositoryMessageInterceptorTests {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendNullSessionId() {
|
||||
void preSendNullSessionId() {
|
||||
setSessionId(null);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void preSendNullSessionAttributes() {
|
||||
void preSendNullSessionAttributes() {
|
||||
this.headers.setSessionAttributes(null);
|
||||
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel))
|
||||
.isSameAs(this.createMessage);
|
||||
assertThat(this.interceptor.preSend(createMessage(), this.channel)).isSameAs(this.createMessage);
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beforeHandshakeNotServletServerHttpRequest() throws Exception {
|
||||
void beforeHandshakeNotServletServerHttpRequest() {
|
||||
assertThat(this.interceptor.beforeHandshake(null, null, null, null)).isTrue();
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beforeHandshakeNullSession() throws Exception {
|
||||
ServletServerHttpRequest request = new ServletServerHttpRequest(
|
||||
new MockHttpServletRequest());
|
||||
void beforeHandshakeNullSession() {
|
||||
ServletServerHttpRequest request = new ServletServerHttpRequest(new MockHttpServletRequest());
|
||||
assertThat(this.interceptor.beforeHandshake(request, null, null, null)).isTrue();
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void beforeHandshakeSession() throws Exception {
|
||||
void beforeHandshakeSession() {
|
||||
MockHttpServletRequest httpRequest = new MockHttpServletRequest();
|
||||
HttpSession httpSession = httpRequest.getSession();
|
||||
ServletServerHttpRequest request = new ServletServerHttpRequest(httpRequest);
|
||||
Map<String, Object> attributes = new HashMap<>();
|
||||
|
||||
assertThat(this.interceptor.beforeHandshake(request, null, null, attributes))
|
||||
.isTrue();
|
||||
assertThat(this.interceptor.beforeHandshake(request, null, null, attributes)).isTrue();
|
||||
|
||||
assertThat(attributes.size()).isEqualTo(1);
|
||||
assertThat(SessionRepositoryMessageInterceptor.getSessionId(attributes))
|
||||
.isEqualTo(httpSession.getId());
|
||||
assertThat(SessionRepositoryMessageInterceptor.getSessionId(attributes)).isEqualTo(httpSession.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* At the moment there is no need for afterHandshake to do anything.
|
||||
*/
|
||||
@Test
|
||||
public void afterHandshakeDoesNothing() {
|
||||
void afterHandshakeDoesNothing() {
|
||||
this.interceptor.afterHandshake(null, null, null, null);
|
||||
|
||||
verifyZeroInteractions(this.sessionRepository);
|
||||
verifyNoMoreInteractions(this.sessionRepository);
|
||||
}
|
||||
|
||||
private void setSessionId(String id) {
|
||||
SessionRepositoryMessageInterceptor
|
||||
.setSessionId(this.headers.getSessionAttributes(), id);
|
||||
SessionRepositoryMessageInterceptor.setSessionId(this.headers.getSessionAttributes(), id);
|
||||
}
|
||||
|
||||
private Message<?> createMessage() {
|
||||
this.createMessage = MessageBuilder.createMessage("",
|
||||
this.headers.getMessageHeaders());
|
||||
this.createMessage = MessageBuilder.createMessage("", this.headers.getMessageHeaders());
|
||||
return this.createMessage;
|
||||
}
|
||||
|
||||
@@ -302,4 +286,5 @@ public class SessionRepositoryMessageInterceptorTests {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ description = "Spring Session Redis implementation"
|
||||
dependencies {
|
||||
compile project(':spring-session-core')
|
||||
compile ("org.springframework.data:spring-data-redis") {
|
||||
exclude group: "org.slf4j", module: 'slf4j-api'
|
||||
exclude group: "org.slf4j", module: 'jcl-over-slf4j'
|
||||
}
|
||||
|
||||
|
||||
@@ -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.
|
||||
@@ -25,7 +25,9 @@ import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.session.events.AbstractSessionEvent;
|
||||
|
||||
public class SessionEventRegistry implements ApplicationListener<AbstractSessionEvent> {
|
||||
|
||||
private Map<String, AbstractSessionEvent> events = new HashMap<>();
|
||||
|
||||
private ConcurrentMap<String, Object> locks = new ConcurrentHashMap<>();
|
||||
|
||||
@Override
|
||||
@@ -48,14 +50,12 @@ public class SessionEventRegistry implements ApplicationListener<AbstractSession
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public <E extends AbstractSessionEvent> E getEvent(String sessionId)
|
||||
throws InterruptedException {
|
||||
public <E extends AbstractSessionEvent> E getEvent(String sessionId) throws InterruptedException {
|
||||
return (E) waitForEvent(sessionId);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private <E extends AbstractSessionEvent> E waitForEvent(String sessionId)
|
||||
throws InterruptedException {
|
||||
private <E extends AbstractSessionEvent> E waitForEvent(String sessionId) throws InterruptedException {
|
||||
Object lock = getLock(sessionId);
|
||||
synchronized (lock) {
|
||||
if (!this.events.containsKey(sessionId)) {
|
||||
@@ -68,4 +68,5 @@ public class SessionEventRegistry implements ApplicationListener<AbstractSession
|
||||
private Object getLock(String sessionId) {
|
||||
return this.locks.computeIfAbsent(sessionId, (k) -> new Object());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,20 +23,19 @@ import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
|
||||
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
|
||||
|
||||
/**
|
||||
* Base class for {@link RedisOperationsSessionRepository} integration tests.
|
||||
* Base class for Redis integration tests.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
public abstract class AbstractRedisITests {
|
||||
|
||||
private static final String DOCKER_IMAGE = "redis:5.0.5";
|
||||
private static final String DOCKER_IMAGE = "redis:5.0.10";
|
||||
|
||||
protected static class BaseConfig {
|
||||
|
||||
@Bean
|
||||
public GenericContainer redisContainer() {
|
||||
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE)
|
||||
.withExposedPorts(6379);
|
||||
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE).withExposedPorts(6379);
|
||||
redisContainer.start();
|
||||
return redisContainer;
|
||||
}
|
||||
@@ -44,8 +43,7 @@ public abstract class AbstractRedisITests {
|
||||
@Bean
|
||||
public LettuceConnectionFactory redisConnectionFactory() {
|
||||
RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(
|
||||
redisContainer().getContainerIpAddress(),
|
||||
redisContainer().getFirstMappedPort());
|
||||
redisContainer().getContainerIpAddress(), redisContainer().getFirstMappedPort());
|
||||
return new LettuceConnectionFactory(configuration);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import reactor.core.publisher.Mono;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.data.redis.ReactiveRedisSessionRepository.RedisSession;
|
||||
import org.springframework.session.data.redis.config.annotation.web.server.EnableRedisWebSession;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
@@ -34,22 +35,21 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link ReactiveRedisOperationsSessionRepository}.
|
||||
* Integration tests for {@link ReactiveRedisSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
class ReactiveRedisSessionRepositoryITests extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private ReactiveRedisOperationsSessionRepository repository;
|
||||
private ReactiveRedisSessionRepository repository;
|
||||
|
||||
@Test
|
||||
public void saves() throws InterruptedException {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void saves() {
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
|
||||
String expectedAttributeName = "a";
|
||||
String expectedAttributeValue = "b";
|
||||
@@ -70,9 +70,8 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test // gh-1399
|
||||
public void saveMultipleTimes() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession session = this.repository
|
||||
.createSession().block();
|
||||
void saveMultipleTimes() {
|
||||
RedisSession session = this.repository.createSession().block();
|
||||
session.setAttribute("attribute1", "value1");
|
||||
Mono<Void> save1 = this.repository.save(session);
|
||||
session.setAttribute("attribute2", "value2");
|
||||
@@ -81,9 +80,8 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
toSave.setAttribute("a", "b");
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
@@ -103,17 +101,15 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
void changeSessionIdWhenOnlyChangeId() {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
toSave.setAttribute(attrName, attrValue);
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findById = this.repository
|
||||
.findById(toSave.getId()).block();
|
||||
RedisSession findById = this.repository.findById(toSave.getId()).block();
|
||||
|
||||
assertThat(findById.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
|
||||
@@ -124,17 +120,14 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
|
||||
assertThat(this.repository.findById(originalFindById).block()).isNull();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findByChangeSessionId = this.repository
|
||||
.findById(changeSessionId).block();
|
||||
RedisSession findByChangeSessionId = this.repository.findById(changeSessionId).block();
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName))
|
||||
.isEqualTo(attrValue);
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionIdWhenChangeTwice() {
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
@@ -150,17 +143,15 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
void changeSessionIdWhenSetAttributeOnChangedSession() {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findById = this.repository
|
||||
.findById(toSave.getId()).block();
|
||||
RedisSession findById = this.repository.findById(toSave.getId()).block();
|
||||
|
||||
findById.setAttribute(attrName, attrValue);
|
||||
|
||||
@@ -171,17 +162,14 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
|
||||
assertThat(this.repository.findById(originalFindById).block()).isNull();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession findByChangeSessionId = this.repository
|
||||
.findById(changeSessionId).block();
|
||||
RedisSession findByChangeSessionId = this.repository.findById(changeSessionId).block();
|
||||
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName))
|
||||
.isEqualTo(attrValue);
|
||||
assertThat(findByChangeSessionId.<String>getAttribute(attrName)).isEqualTo(attrValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionIdWhenHasNotSaved() {
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
|
||||
@@ -193,9 +181,8 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
|
||||
// gh-954
|
||||
@Test
|
||||
public void changeSessionIdSaveTwice() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionIdSaveTwice() {
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
|
||||
@@ -208,23 +195,20 @@ public class ReactiveRedisOperationsSessionRepositoryITests extends AbstractRedi
|
||||
|
||||
// gh-1111
|
||||
@Test
|
||||
public void changeSessionSaveOldSessionInstance() {
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession toSave = this.repository
|
||||
.createSession().block();
|
||||
void changeSessionSaveOldSessionInstance() {
|
||||
RedisSession toSave = this.repository.createSession().block();
|
||||
String sessionId = toSave.getId();
|
||||
|
||||
this.repository.save(toSave).block();
|
||||
|
||||
ReactiveRedisOperationsSessionRepository.RedisSession session = this.repository
|
||||
.findById(sessionId).block();
|
||||
RedisSession session = this.repository.findById(sessionId).block();
|
||||
session.changeSessionId();
|
||||
session.setLastAccessedTime(Instant.now());
|
||||
this.repository.save(session).block();
|
||||
|
||||
toSave.setLastAccessedTime(Instant.now());
|
||||
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.repository.save(toSave).block())
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.repository.save(toSave).block())
|
||||
.withMessage("Session was invalidated");
|
||||
|
||||
assertThat(this.repository.findById(sessionId).block()).isNull();
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2019 the original author or authors.
|
||||
* Copyright 2014-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -37,7 +37,7 @@ import org.springframework.security.core.context.SecurityContextHolder;
|
||||
import org.springframework.session.FindByIndexNameSessionRepository;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.data.SessionEventRegistry;
|
||||
import org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession;
|
||||
import org.springframework.session.data.redis.RedisIndexedSessionRepository.RedisSession;
|
||||
import org.springframework.session.data.redis.config.annotation.SpringSessionRedisOperations;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
import org.springframework.session.events.SessionCreatedEvent;
|
||||
@@ -48,17 +48,23 @@ import org.springframework.test.context.web.WebAppConfiguration;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link RedisIndexedSessionRepository}.
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
class RedisIndexedSessionRepositoryITests extends AbstractRedisITests {
|
||||
|
||||
private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT";
|
||||
|
||||
private static final String INDEX_NAME = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME;
|
||||
|
||||
@Autowired
|
||||
private RedisOperationsSessionRepository repository;
|
||||
private RedisIndexedSessionRepository repository;
|
||||
|
||||
@Autowired
|
||||
private SessionEventRegistry registry;
|
||||
@@ -71,34 +77,31 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
private SecurityContext changedContext;
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
if (this.registry != null) {
|
||||
this.registry.clear();
|
||||
}
|
||||
this.context = SecurityContextHolder.createEmptyContext();
|
||||
this.context.setAuthentication(
|
||||
new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(),
|
||||
"na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
this.context.setAuthentication(new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), "na",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
|
||||
this.changedContext = SecurityContextHolder.createEmptyContext();
|
||||
this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken(
|
||||
"changedContext-" + UUID.randomUUID(), "na",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
"changedContext-" + UUID.randomUUID(), "na", AuthorityUtils.createAuthorityList("ROLE_USER")));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void saves() throws InterruptedException {
|
||||
void saves() throws InterruptedException {
|
||||
String username = "saves-" + System.currentTimeMillis();
|
||||
|
||||
String usernameSessionKey = "RedisOperationsSessionRepositoryITests:index:"
|
||||
+ INDEX_NAME + ":" + username;
|
||||
String usernameSessionKey = "RedisIndexedSessionRepositoryITests:index:" + INDEX_NAME + ":" + username;
|
||||
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String expectedAttributeName = "a";
|
||||
String expectedAttributeValue = "b";
|
||||
toSave.setAttribute(expectedAttributeName, expectedAttributeValue);
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username,
|
||||
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken(username, "password",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||
toSaveContext.setAuthentication(toSaveToken);
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, toSaveContext);
|
||||
@@ -108,10 +111,8 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
this.repository.save(toSave);
|
||||
|
||||
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||
assertThat(this.registry.<SessionCreatedEvent>getEvent(toSave.getId()))
|
||||
.isInstanceOf(SessionCreatedEvent.class);
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members())
|
||||
.contains(toSave.getId());
|
||||
assertThat(this.registry.<SessionCreatedEvent>getEvent(toSave.getId())).isInstanceOf(SessionCreatedEvent.class);
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).contains(toSave.getId());
|
||||
|
||||
Session session = this.repository.findById(toSave.getId());
|
||||
|
||||
@@ -127,16 +128,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
assertThat(this.repository.findById(toSave.getId())).isNull();
|
||||
assertThat(this.registry.<SessionDestroyedEvent>getEvent(toSave.getId()))
|
||||
.isInstanceOf(SessionDestroyedEvent.class);
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members())
|
||||
.doesNotContain(toSave.getId());
|
||||
assertThat(this.redis.boundSetOps(usernameSessionKey).members()).doesNotContain(toSave.getId());
|
||||
|
||||
assertThat(this.registry.getEvent(toSave.getId()).getSession()
|
||||
.<String>getAttribute(expectedAttributeName))
|
||||
assertThat(this.registry.getEvent(toSave.getId()).getSession().<String>getAttribute(expectedAttributeName))
|
||||
.isEqualTo(expectedAttributeValue);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
void putAllOnSingleAttrDoesNotRemoveOld() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute("a", "b");
|
||||
|
||||
@@ -157,15 +156,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalName() throws Exception {
|
||||
void findByPrincipalName() throws Exception {
|
||||
String principalName = "findByPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
@@ -173,7 +172,28 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
this.repository.deleteById(toSave.getId());
|
||||
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findByPrincipalNameExpireRemovesIndex() {
|
||||
String principalName = "findByPrincipalNameExpireRemovesIndex" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisIndexedSessionRepositoryITests:sessions:expires:" + toSave.getId();
|
||||
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);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
@@ -181,34 +201,8 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameExpireRemovesIndex() throws Exception {
|
||||
String principalName = "findByPrincipalNameExpireRemovesIndex"
|
||||
+ UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisOperationsSessionRepositoryITests:sessions:expires:"
|
||||
+ toSave.getId();
|
||||
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);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoPrincipalNameChange() throws Exception {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChange"
|
||||
+ UUID.randomUUID();
|
||||
void findByPrincipalNameNoPrincipalNameChange() {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChange" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
@@ -217,17 +211,16 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoPrincipalNameChangeReload() throws Exception {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload"
|
||||
+ UUID.randomUUID();
|
||||
void findByPrincipalNameNoPrincipalNameChangeReload() {
|
||||
String principalName = "findByPrincipalNameNoPrincipalNameChangeReload" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
|
||||
@@ -238,15 +231,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedPrincipalName() throws Exception {
|
||||
void findByDeletedPrincipalName() {
|
||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
@@ -256,14 +249,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(INDEX_NAME, null);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedPrincipalName() throws Exception {
|
||||
void findByChangedPrincipalName() {
|
||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
@@ -274,19 +267,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(INDEX_NAME, principalNameChanged);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalNameChanged);
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedPrincipalNameReload() throws Exception {
|
||||
void findByDeletedPrincipalNameReload() {
|
||||
String principalName = "findByDeletedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(INDEX_NAME, principalName);
|
||||
@@ -297,14 +289,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(INDEX_NAME, null);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedPrincipalNameReload() throws Exception {
|
||||
void findByChangedPrincipalNameReload() {
|
||||
String principalName = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
String principalNameChanged = "findByChangedPrincipalName" + UUID.randomUUID();
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
@@ -317,26 +309,25 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(INDEX_NAME, principalNameChanged);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, principalName);
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalName);
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
principalNameChanged);
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, principalNameChanged);
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findBySecurityPrincipalName() throws Exception {
|
||||
void findBySecurityPrincipalName() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
@@ -344,7 +335,27 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
this.repository.deleteById(toSave.getId());
|
||||
assertThat(this.registry.receivedEvent(toSave.getId())).isTrue();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
void findBySecurityPrincipalNameExpireRemovesIndex() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisIndexedSessionRepositoryITests:sessions:expires:" + toSave.getId();
|
||||
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);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
@@ -352,30 +363,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findBySecurityPrincipalNameExpireRemovesIndex() throws Exception {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
this.repository.save(toSave);
|
||||
|
||||
String body = "RedisOperationsSessionRepositoryITests:sessions:expires:"
|
||||
+ toSave.getId();
|
||||
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);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(0);
|
||||
assertThat(findByPrincipalName.keySet()).doesNotContain(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoSecurityPrincipalNameChange() throws Exception {
|
||||
void findByPrincipalNameNoSecurityPrincipalNameChange() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -384,16 +372,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByPrincipalNameNoSecurityPrincipalNameChangeReload()
|
||||
throws Exception {
|
||||
void findByPrincipalNameNoSecurityPrincipalNameChangeReload() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -404,15 +391,15 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute("other", "value");
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedSecurityPrincipalName() throws Exception {
|
||||
void findByDeletedSecurityPrincipalName() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -421,14 +408,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, null);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedSecurityPrincipalName() throws Exception {
|
||||
void findByChangedSecurityPrincipalName() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -437,19 +424,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||
this.repository.save(toSave);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getChangedSecurityName());
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByDeletedSecurityPrincipalNameReload() throws Exception {
|
||||
void findByDeletedSecurityPrincipalNameReload() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -459,14 +445,14 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(INDEX_NAME, null);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getChangedSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void findByChangedSecurityPrincipalNameReload() throws Exception {
|
||||
void findByChangedSecurityPrincipalNameReload() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context);
|
||||
|
||||
@@ -477,19 +463,18 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
getSession.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext);
|
||||
this.repository.save(getSession);
|
||||
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository
|
||||
.findByIndexNameAndIndexValue(INDEX_NAME, getSecurityName());
|
||||
Map<String, RedisSession> findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getSecurityName());
|
||||
assertThat(findByPrincipalName).isEmpty();
|
||||
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME,
|
||||
getChangedSecurityName());
|
||||
findByPrincipalName = this.repository.findByIndexNameAndIndexValue(INDEX_NAME, getChangedSecurityName());
|
||||
|
||||
assertThat(findByPrincipalName).hasSize(1);
|
||||
assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenOnlyChangeId() throws Exception {
|
||||
void changeSessionIdWhenOnlyChangeId() {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
@@ -514,7 +499,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenChangeTwice() throws Exception {
|
||||
void changeSessionIdWhenChangeTwice() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
|
||||
this.repository.save(toSave);
|
||||
@@ -531,7 +516,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenSetAttributeOnChangedSession() throws Exception {
|
||||
void changeSessionIdWhenSetAttributeOnChangedSession() {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
@@ -556,7 +541,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test
|
||||
public void changeSessionIdWhenHasNotSaved() throws Exception {
|
||||
void changeSessionIdWhenHasNotSaved() {
|
||||
String attrName = "changeSessionId";
|
||||
String attrValue = "changeSessionId-value";
|
||||
|
||||
@@ -572,7 +557,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
|
||||
// gh-962
|
||||
@Test
|
||||
public void changeSessionIdSaveTwice() {
|
||||
void changeSessionIdSaveTwice() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String originalId = toSave.getId();
|
||||
toSave.changeSessionId();
|
||||
@@ -586,7 +571,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
|
||||
// gh-1137
|
||||
@Test
|
||||
public void changeSessionIdWhenSessionIsDeleted() {
|
||||
void changeSessionIdWhenSessionIsDeleted() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String sessionId = toSave.getId();
|
||||
this.repository.save(toSave);
|
||||
@@ -601,7 +586,7 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Test // gh-1270
|
||||
public void changeSessionIdSaveConcurrently() {
|
||||
void changeSessionIdSaveConcurrently() {
|
||||
RedisSession toSave = this.repository.createSession();
|
||||
String originalId = toSave.getId();
|
||||
this.repository.save(toSave);
|
||||
@@ -628,11 +613,11 @@ public class RedisOperationsSessionRepositoryITests extends AbstractRedisITests
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession(redisNamespace = "RedisOperationsSessionRepositoryITests")
|
||||
@EnableRedisHttpSession(redisNamespace = "RedisIndexedSessionRepositoryITests")
|
||||
static class Config extends BaseConfig {
|
||||
|
||||
@Bean
|
||||
public SessionEventRegistry sessionEventRegistry() {
|
||||
SessionEventRegistry sessionEventRegistry() {
|
||||
return new SessionEventRegistry();
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ import org.springframework.data.redis.connection.RedisConnectionFactory;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.config.annotation.web.http.EnableSpringHttpSession;
|
||||
import org.springframework.session.data.redis.SimpleRedisOperationsSessionRepository.RedisSession;
|
||||
import org.springframework.session.data.redis.RedisSessionRepository.RedisSession;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
import org.springframework.test.context.web.WebAppConfiguration;
|
||||
@@ -41,25 +41,24 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatIllegalStateException;
|
||||
|
||||
/**
|
||||
* Integration tests for {@link SimpleRedisOperationsSessionRepository}.
|
||||
* Integration tests for {@link RedisSessionRepository}.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
*/
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
class RedisSessionRepositoryITests extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private SimpleRedisOperationsSessionRepository sessionRepository;
|
||||
private RedisSessionRepository sessionRepository;
|
||||
|
||||
@Test
|
||||
void save_NewSession_ShouldSaveSession() {
|
||||
RedisSession session = createAndSaveSession(Instant.now());
|
||||
assertThat(session.getMaxInactiveInterval()).isEqualTo(
|
||||
Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
assertThat(session.getAttributeNames())
|
||||
.isEqualTo(Collections.singleton("attribute1"));
|
||||
assertThat(session.getMaxInactiveInterval())
|
||||
.isEqualTo(Duration.ofSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS));
|
||||
assertThat(session.getAttributeNames()).isEqualTo(Collections.singleton("attribute1"));
|
||||
assertThat(session.<String>getAttribute("attribute1")).isEqualTo("value1");
|
||||
}
|
||||
|
||||
@@ -72,8 +71,7 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
void save_DeletedSession_ShouldThrowException() {
|
||||
RedisSession session = createAndSaveSession(Instant.now());
|
||||
this.sessionRepository.deleteById(session.getId());
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.sessionRepository.save(session))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.sessionRepository.save(session))
|
||||
.withMessage("Session was invalidated");
|
||||
}
|
||||
|
||||
@@ -164,8 +162,7 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
this.sessionRepository.deleteById(originalSessionId);
|
||||
updateSession(session, Instant.now(), "attribute1", "value1");
|
||||
String newSessionId = session.changeSessionId();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.sessionRepository.save(session))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.sessionRepository.save(session))
|
||||
.withMessage("Session was invalidated");
|
||||
assertThat(this.sessionRepository.findById(newSessionId)).isNull();
|
||||
assertThat(this.sessionRepository.findById(originalSessionId)).isNull();
|
||||
@@ -182,8 +179,7 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
this.sessionRepository.save(copy1);
|
||||
updateSession(copy2, now.plusSeconds(2L), "attribute3", "value3");
|
||||
String newSessionId2 = copy2.changeSessionId();
|
||||
assertThatIllegalStateException()
|
||||
.isThrownBy(() -> this.sessionRepository.save(copy2))
|
||||
assertThatIllegalStateException().isThrownBy(() -> this.sessionRepository.save(copy2))
|
||||
.withMessage("Session was invalidated");
|
||||
assertThat(this.sessionRepository.findById(newSessionId1)).isNotNull();
|
||||
assertThat(this.sessionRepository.findById(newSessionId2)).isNull();
|
||||
@@ -220,8 +216,8 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
return this.sessionRepository.findById(session.getId());
|
||||
}
|
||||
|
||||
private static void updateSession(RedisSession session, Instant lastAccessedTime,
|
||||
String attributeName, Object attributeValue) {
|
||||
private static void updateSession(RedisSession session, Instant lastAccessedTime, String attributeName,
|
||||
Object attributeValue) {
|
||||
session.setLastAccessedTime(lastAccessedTime);
|
||||
session.setAttribute(attributeName, attributeValue);
|
||||
}
|
||||
@@ -231,12 +227,11 @@ class SimpleRedisOperationsSessionRepositoryITests extends AbstractRedisITests {
|
||||
static class Config extends BaseConfig {
|
||||
|
||||
@Bean
|
||||
public SimpleRedisOperationsSessionRepository sessionRepository(
|
||||
RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisSessionRepository sessionRepository(RedisConnectionFactory redisConnectionFactory) {
|
||||
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
|
||||
redisTemplate.setConnectionFactory(redisConnectionFactory);
|
||||
redisTemplate.afterPropertiesSet();
|
||||
return new SimpleRedisOperationsSessionRepository(redisTemplate);
|
||||
return new RedisSessionRepository(redisTemplate);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -44,8 +44,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session>
|
||||
extends AbstractRedisITests {
|
||||
class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session> extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private SessionRepository<S> repository;
|
||||
@@ -56,16 +55,16 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session
|
||||
private final Object lock = new Object();
|
||||
|
||||
@BeforeEach
|
||||
public void setup() {
|
||||
void setup() {
|
||||
this.registry.setLock(this.lock);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void expireFiresSessionExpiredEvent() throws InterruptedException {
|
||||
void expireFiresSessionExpiredEvent() throws InterruptedException {
|
||||
S toSave = this.repository.createSession();
|
||||
toSave.setAttribute("a", "b");
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user",
|
||||
"password", AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user", "password",
|
||||
AuthorityUtils.createAuthorityList("ROLE_USER"));
|
||||
SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext();
|
||||
toSaveContext.setAuthentication(toSaveToken);
|
||||
toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext);
|
||||
@@ -89,9 +88,10 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session
|
||||
assertThat(this.registry.receivedEvent()).isTrue();
|
||||
}
|
||||
|
||||
static class SessionExpiredEventRegistry
|
||||
implements ApplicationListener<SessionExpiredEvent> {
|
||||
static class SessionExpiredEventRegistry implements ApplicationListener<SessionExpiredEvent> {
|
||||
|
||||
private boolean receivedEvent;
|
||||
|
||||
private Object lock;
|
||||
|
||||
@Override
|
||||
@@ -102,13 +102,14 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session
|
||||
}
|
||||
}
|
||||
|
||||
public boolean receivedEvent() {
|
||||
boolean receivedEvent() {
|
||||
return this.receivedEvent;
|
||||
}
|
||||
|
||||
public void setLock(Object lock) {
|
||||
void setLock(Object lock) {
|
||||
this.lock = lock;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -116,7 +117,7 @@ public class EnableRedisHttpSessionExpireSessionDestroyedTests<S extends Session
|
||||
static class Config extends BaseConfig {
|
||||
|
||||
@Bean
|
||||
public SessionExpiredEventRegistry sessionDestroyedEventRegistry() {
|
||||
SessionExpiredEventRegistry sessionDestroyedEventRegistry() {
|
||||
return new SessionExpiredEventRegistry();
|
||||
}
|
||||
|
||||
|
||||
@@ -21,10 +21,10 @@ import org.junit.jupiter.api.extension.ExtendWith;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.session.FlushMode;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.session.SessionRepository;
|
||||
import org.springframework.session.data.redis.AbstractRedisITests;
|
||||
import org.springframework.session.data.redis.RedisFlushMode;
|
||||
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit.jupiter.SpringExtension;
|
||||
@@ -35,14 +35,13 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisOperationsSessionRepositoryFlushImmediatelyITests<S extends Session>
|
||||
extends AbstractRedisITests {
|
||||
class RedisIndexedSessionRepositoryFlushImmediatelyITests<S extends Session> extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private SessionRepository<S> sessionRepository;
|
||||
|
||||
@Test
|
||||
public void savesOnCreate() throws InterruptedException {
|
||||
void savesOnCreate() {
|
||||
S created = this.sessionRepository.createSession();
|
||||
|
||||
S getSession = this.sessionRepository.findById(created.getId());
|
||||
@@ -51,7 +50,7 @@ public class RedisOperationsSessionRepositoryFlushImmediatelyITests<S extends Se
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@EnableRedisHttpSession(redisFlushMode = RedisFlushMode.IMMEDIATE)
|
||||
@EnableRedisHttpSession(flushMode = FlushMode.IMMEDIATE)
|
||||
static class RedisHttpSessionConfig extends BaseConfig {
|
||||
|
||||
}
|
||||
@@ -45,7 +45,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
@ExtendWith(SpringExtension.class)
|
||||
@ContextConfiguration
|
||||
@WebAppConfiguration
|
||||
public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITests {
|
||||
class RedisListenerContainerTaskExecutorITests extends AbstractRedisITests {
|
||||
|
||||
@Autowired
|
||||
private SessionTaskExecutor executor;
|
||||
@@ -54,10 +54,9 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
private RedisOperations<Object, Object> redis;
|
||||
|
||||
@Test
|
||||
public void testRedisDelEventsAreDispatchedInSessionTaskExecutor()
|
||||
throws InterruptedException {
|
||||
BoundSetOperations<Object, Object> ops = this.redis.boundSetOps(
|
||||
"spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
|
||||
void testRedisDelEventsAreDispatchedInSessionTaskExecutor() throws InterruptedException {
|
||||
BoundSetOperations<Object, Object> ops = this.redis
|
||||
.boundSetOps("spring:session:RedisListenerContainerTaskExecutorITests:expirations:dummy");
|
||||
ops.add("value");
|
||||
ops.remove("value");
|
||||
assertThat(this.executor.taskDispatched()).isTrue();
|
||||
@@ -65,7 +64,8 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
}
|
||||
|
||||
static class SessionTaskExecutor implements TaskExecutor {
|
||||
private Object lock = new Object();
|
||||
|
||||
private final Object lock = new Object();
|
||||
|
||||
private final Executor executor;
|
||||
|
||||
@@ -88,7 +88,7 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
}
|
||||
}
|
||||
|
||||
public boolean taskDispatched() throws InterruptedException {
|
||||
boolean taskDispatched() throws InterruptedException {
|
||||
if (this.taskDispatched != null) {
|
||||
return this.taskDispatched;
|
||||
}
|
||||
@@ -97,6 +97,7 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
}
|
||||
return (this.taskDispatched != null) ? this.taskDispatched : Boolean.FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@@ -104,12 +105,12 @@ public class RedisListenerContainerTaskExecutorITests extends AbstractRedisITest
|
||||
static class Config extends BaseConfig {
|
||||
|
||||
@Bean
|
||||
public Executor springSessionRedisTaskExecutor() {
|
||||
Executor springSessionRedisTaskExecutor() {
|
||||
return new SessionTaskExecutor(Executors.newSingleThreadExecutor());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Executor springSessionRedisSubscriptionExecutor() {
|
||||
Executor springSessionRedisSubscriptionExecutor() {
|
||||
return new SimpleAsyncTaskExecutor();
|
||||
}
|
||||
|
||||
|
||||
@@ -16,321 +16,39 @@
|
||||
|
||||
package org.springframework.session.data.redis;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.reactivestreams.Publisher;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import org.springframework.data.redis.core.ReactiveRedisOperations;
|
||||
import org.springframework.session.MapSession;
|
||||
import org.springframework.session.ReactiveSessionRepository;
|
||||
import org.springframework.session.Session;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* A {@link ReactiveSessionRepository} that is implemented using Spring Data's
|
||||
* {@link ReactiveRedisOperations}.
|
||||
* This {@link ReactiveSessionRepository} implementation is kept in order to support
|
||||
* migration to {@link ReactiveRedisSessionRepository} in a backwards compatible manner.
|
||||
*
|
||||
* @author Vedran Pavic
|
||||
* @since 2.0
|
||||
* @since 2.0.0
|
||||
* @deprecated since 2.2.0 in favor of {@link ReactiveRedisSessionRepository}
|
||||
*/
|
||||
public class ReactiveRedisOperationsSessionRepository implements
|
||||
ReactiveSessionRepository<ReactiveRedisOperationsSessionRepository.RedisSession> {
|
||||
@Deprecated
|
||||
public class ReactiveRedisOperationsSessionRepository extends ReactiveRedisSessionRepository {
|
||||
|
||||
/**
|
||||
* The default namespace for each key and channel in Redis used by Spring Session.
|
||||
* Create a new {@link ReactiveRedisOperationsSessionRepository} instance.
|
||||
* @param sessionRedisOperations the {@link ReactiveRedisOperations} to use for
|
||||
* managing sessions
|
||||
* @see ReactiveRedisSessionRepository#ReactiveRedisSessionRepository(ReactiveRedisOperations)
|
||||
*/
|
||||
public static final String DEFAULT_NAMESPACE = "spring:session";
|
||||
|
||||
private final ReactiveRedisOperations<String, Object> sessionRedisOperations;
|
||||
|
||||
/**
|
||||
* The namespace for every key used by Spring Session in Redis.
|
||||
*/
|
||||
private String namespace = DEFAULT_NAMESPACE + ":";
|
||||
|
||||
/**
|
||||
* If non-null, this value is used to override the default value for
|
||||
* {@link RedisSession#setMaxInactiveInterval(Duration)}.
|
||||
*/
|
||||
private Integer defaultMaxInactiveInterval;
|
||||
|
||||
private RedisFlushMode redisFlushMode = RedisFlushMode.ON_SAVE;
|
||||
|
||||
public ReactiveRedisOperationsSessionRepository(
|
||||
ReactiveRedisOperations<String, Object> sessionRedisOperations) {
|
||||
Assert.notNull(sessionRedisOperations, "sessionRedisOperations cannot be null");
|
||||
this.sessionRedisOperations = sessionRedisOperations;
|
||||
}
|
||||
|
||||
public void setRedisKeyNamespace(String namespace) {
|
||||
Assert.hasText(namespace, "namespace cannot be null or empty");
|
||||
this.namespace = namespace.trim() + ":";
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the maximum inactive interval in seconds between requests before newly created
|
||||
* sessions will be invalidated. A negative time indicates that the session will never
|
||||
* timeout. The default is 1800 (30 minutes).
|
||||
*
|
||||
* @param defaultMaxInactiveInterval the number of seconds that the {@link Session}
|
||||
* should be kept alive between client requests.
|
||||
*/
|
||||
public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) {
|
||||
this.defaultMaxInactiveInterval = defaultMaxInactiveInterval;
|
||||
public ReactiveRedisOperationsSessionRepository(ReactiveRedisOperations<String, Object> sessionRedisOperations) {
|
||||
super(sessionRedisOperations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the redis flush mode. Default flush mode is {@link RedisFlushMode#ON_SAVE}.
|
||||
*
|
||||
* @param redisFlushMode the new redis flush mode
|
||||
* @deprecated since 2.2.0 as support {@code IMMEDIATE} is removed
|
||||
*/
|
||||
@Deprecated
|
||||
public void setRedisFlushMode(RedisFlushMode redisFlushMode) {
|
||||
Assert.notNull(redisFlushMode, "redisFlushMode cannot be null");
|
||||
this.redisFlushMode = redisFlushMode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the {@link ReactiveRedisOperations} used for sessions.
|
||||
* @return the {@link ReactiveRedisOperations} used for sessions
|
||||
* @since 2.1.0
|
||||
*/
|
||||
public ReactiveRedisOperations<String, Object> getSessionRedisOperations() {
|
||||
return this.sessionRedisOperations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<RedisSession> createSession() {
|
||||
return Mono.defer(() -> {
|
||||
RedisSession session = new RedisSession();
|
||||
|
||||
if (this.defaultMaxInactiveInterval != null) {
|
||||
session.setMaxInactiveInterval(
|
||||
Duration.ofSeconds(this.defaultMaxInactiveInterval));
|
||||
}
|
||||
|
||||
return Mono.just(session);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> save(RedisSession session) {
|
||||
if (session.isNew) {
|
||||
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
|
||||
public Mono<RedisSession> findById(String id) {
|
||||
String sessionKey = getSessionKey(id);
|
||||
|
||||
// @formatter:off
|
||||
return this.sessionRedisOperations.opsForHash().entries(sessionKey)
|
||||
.collectMap((e) -> e.getKey().toString(), Map.Entry::getValue)
|
||||
.filter((map) -> !map.isEmpty())
|
||||
.map(new RedisSessionMapper(id))
|
||||
.filter((session) -> !session.isExpired())
|
||||
.map(RedisSession::new)
|
||||
.switchIfEmpty(Mono.defer(() -> deleteById(id).then(Mono.empty())));
|
||||
// @formatter:on
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Void> deleteById(String id) {
|
||||
String sessionKey = getSessionKey(id);
|
||||
|
||||
return this.sessionRedisOperations.delete(sessionKey).then();
|
||||
}
|
||||
|
||||
private static String getAttributeKey(String attributeName) {
|
||||
return RedisSessionMapper.ATTRIBUTE_PREFIX + attributeName;
|
||||
}
|
||||
|
||||
private String getSessionKey(String sessionId) {
|
||||
return this.namespace + "sessions:" + sessionId;
|
||||
}
|
||||
|
||||
/**
|
||||
* A custom implementation of {@link Session} that uses a {@link MapSession} as the
|
||||
* basis for its mapping. It keeps track of any attributes that have changed. When
|
||||
* {@link RedisSession#saveDelta()} is invoked all the attributes that have been
|
||||
* changed will be persisted.
|
||||
*/
|
||||
final class RedisSession implements Session {
|
||||
|
||||
private final MapSession cached;
|
||||
|
||||
private final Map<String, Object> delta = new HashMap<>();
|
||||
|
||||
private boolean isNew;
|
||||
|
||||
private String originalSessionId;
|
||||
|
||||
/**
|
||||
* Creates a new instance ensuring to mark all of the new attributes to be
|
||||
* persisted in the next save operation.
|
||||
*/
|
||||
RedisSession() {
|
||||
this(new MapSession());
|
||||
this.delta.put(RedisSessionMapper.CREATION_TIME_KEY,
|
||||
getCreationTime().toEpochMilli());
|
||||
this.delta.put(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) getMaxInactiveInterval().getSeconds());
|
||||
this.delta.put(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
getLastAccessedTime().toEpochMilli());
|
||||
this.isNew = true;
|
||||
this.flushImmediateIfNecessary();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new instance from the provided {@link MapSession}.
|
||||
*
|
||||
* @param mapSession the {@link MapSession} that represents the persisted session
|
||||
* that was retrieved. Cannot be null.
|
||||
*/
|
||||
RedisSession(MapSession mapSession) {
|
||||
Assert.notNull(mapSession, "mapSession cannot be null");
|
||||
this.cached = mapSession;
|
||||
this.originalSessionId = mapSession.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return this.cached.getId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String changeSessionId() {
|
||||
return this.cached.changeSessionId();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T getAttribute(String attributeName) {
|
||||
return this.cached.getAttribute(attributeName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getAttributeNames() {
|
||||
return this.cached.getAttributeNames();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setAttribute(String attributeName, Object attributeValue) {
|
||||
this.cached.setAttribute(attributeName, attributeValue);
|
||||
putAndFlush(getAttributeKey(attributeName), attributeValue);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeAttribute(String attributeName) {
|
||||
this.cached.removeAttribute(attributeName);
|
||||
putAndFlush(getAttributeKey(attributeName), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getCreationTime() {
|
||||
return this.cached.getCreationTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLastAccessedTime(Instant lastAccessedTime) {
|
||||
this.cached.setLastAccessedTime(lastAccessedTime);
|
||||
putAndFlush(RedisSessionMapper.LAST_ACCESSED_TIME_KEY,
|
||||
getLastAccessedTime().toEpochMilli());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getLastAccessedTime() {
|
||||
return this.cached.getLastAccessedTime();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setMaxInactiveInterval(Duration interval) {
|
||||
this.cached.setMaxInactiveInterval(interval);
|
||||
putAndFlush(RedisSessionMapper.MAX_INACTIVE_INTERVAL_KEY,
|
||||
(int) getMaxInactiveInterval().getSeconds());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getMaxInactiveInterval() {
|
||||
return this.cached.getMaxInactiveInterval();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isExpired() {
|
||||
return this.cached.isExpired();
|
||||
}
|
||||
|
||||
private boolean hasChangedSessionId() {
|
||||
return !getId().equals(this.originalSessionId);
|
||||
}
|
||||
|
||||
private void flushImmediateIfNecessary() {
|
||||
if (ReactiveRedisOperationsSessionRepository.this.redisFlushMode == RedisFlushMode.IMMEDIATE) {
|
||||
save();
|
||||
}
|
||||
}
|
||||
|
||||
private void putAndFlush(String a, Object v) {
|
||||
this.delta.put(a, v);
|
||||
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();
|
||||
}
|
||||
|
||||
String sessionKey = getSessionKey(getId());
|
||||
Mono<Boolean> update = ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.opsForHash().putAll(sessionKey, new HashMap<>(this.delta));
|
||||
Mono<Boolean> setTtl = ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.expire(sessionKey, getMaxInactiveInterval());
|
||||
|
||||
return update.and(setTtl).and((s) -> {
|
||||
this.delta.clear();
|
||||
s.onComplete();
|
||||
}).then();
|
||||
}
|
||||
|
||||
private Mono<Void> saveChangeSessionId() {
|
||||
if (!hasChangedSessionId()) {
|
||||
return Mono.empty();
|
||||
}
|
||||
|
||||
String sessionId = getId();
|
||||
|
||||
Publisher<Void> replaceSessionId = (s) -> {
|
||||
this.originalSessionId = sessionId;
|
||||
s.onComplete();
|
||||
};
|
||||
|
||||
if (this.isNew) {
|
||||
return Mono.from(replaceSessionId);
|
||||
}
|
||||
else {
|
||||
String originalSessionKey = getSessionKey(this.originalSessionId);
|
||||
String sessionKey = getSessionKey(sessionId);
|
||||
|
||||
return ReactiveRedisOperationsSessionRepository.this.sessionRedisOperations
|
||||
.rename(originalSessionKey, sessionKey).and(replaceSessionId);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user