Compare commits

..

489 Commits

Author SHA1 Message Date
Eleftheria Stein
b1d68c0731 Release 2.5.0 2021-05-19 00:13:33 +02:00
Eleftheria Stein
7ec5add1bd Configure user name for Gradle CI builds
This reverts commit e41ebd8a77.
2021-05-19 00:13:17 +02:00
Eleftheria Stein
05e103d9c5 Use GPG_PRIVATE_KEY_NO_HEADER secret in CI
Issue gh-1812
2021-05-19 00:09:26 +02:00
Eleftheria Stein
8190072d3f Revert "Release 2.5.0"
This reverts commit ce16374c15.
2021-05-19 00:08:02 +02:00
Eleftheria Stein
ce16374c15 Release 2.5.0 2021-05-18 22:24:46 +02:00
Eleftheria Stein
e41ebd8a77 Revert "Configure user name for Gradle CI builds"
This reverts commit ce938fd2fe.
2021-05-18 22:22:37 +02:00
Eleftheria Stein
8550aeca5c Revert "Release 2.5.0"
This reverts commit 5cb8a6b79a.
2021-05-18 22:22:21 +02:00
Eleftheria Stein
5cb8a6b79a Release 2.5.0 2021-05-18 13:28:56 +02:00
Eleftheria Stein
5b48e7e8e7 Upgrade Spring Security to 5.5.0
Closes gh-1856
2021-05-18 10:00:37 +02:00
Eleftheria Stein
9e2b729d62 Upgrade test dependencies 2021-05-17 17:45:47 +02:00
Eleftheria Stein
524ee0d9bc Upgrade samples to Spring Boot 2.4.5
Closes gh-1855
2021-05-17 17:20:46 +02:00
Eleftheria Stein
26be3218fb Upgrade Spring Framework to 5.3.7
Closes gh-1853
2021-05-17 17:12:53 +02:00
Eleftheria Stein
8d4fd80add Upgrade Spring Data to 2021.0.1
Closes gh-1854
2021-05-17 17:12:25 +02:00
Eleftheria Stein
6969ea0049 Upgrade Reactor to 2020.0.7
Closes gh-1852
2021-05-17 17:11:01 +02:00
Eleftheria Stein
ce938fd2fe Configure user name for Gradle CI builds
Closes gh-1851
2021-05-14 12:32:29 +02:00
weix sun
98d7448b40 Fix broken Framework link in reference docs 2021-05-11 11:18:52 +02:00
Eleftheria Stein
4bb2bd6fda JDBC session with negative timeout should never expire
Closes gh-1847
2021-05-10 16:38:30 +02:00
Eleftheria Stein
0e5dd1863f Rename master branch to main
Closes gh-1846
2021-04-28 17:19:52 +02:00
Eleftheria Stein
548b58ee55 Next development version 2021-04-13 12:43:12 +02:00
Eleftheria Stein
bb28af9934 Release 2.5.0-RC1 2021-04-13 12:28:27 +02:00
Eleftheria Stein
dee8402473 Upgrade test dependencies 2021-04-13 12:12:17 +02:00
Eleftheria Stein
7bd0b45f29 Upgrade samples to Spring Boot 2.4.4
Closes gh-1822
2021-04-13 12:01:37 +02:00
Eleftheria Stein
b42b01af9b Upgrade Hazelcast 4 to 4.2
Closes gh-1821
2021-04-13 11:31:58 +02:00
Eleftheria Stein
6744fee3cb Upgrade Hazelcast to 3.12.12
Closes gh-1820
2021-04-13 11:22:00 +02:00
Eleftheria Stein
6811f25565 Upgrade Spring Security to 5.5.0-RC1
Closes gh-1819
2021-04-13 11:21:10 +02:00
Eleftheria Stein
47817c46e1 Upgrade Spring Data to 2021.0.0-RC1
Closes gh-1818
2021-04-13 11:20:20 +02:00
Eleftheria Stein
4f7c6406ad Upgrade Spring Framework to 5.3.5
Closes gh-1817
2021-04-13 11:19:27 +02:00
Eleftheria Stein
34cc1d1171 Upgrade Reactor to 2020.0.6
Closes gh-1816
2021-04-13 11:18:29 +02:00
Josh Cummings
9e7d9912e5 Change to GPG_PRIVATE_KEY_NO_HEADER
Closes gh-1812
2021-03-30 13:32:28 -06:00
Eleftheria Stein
d2960b570f Polish gh-1798
- Should throw IllegalStateException
2021-03-25 09:55:32 +02:00
Eleftheria Stein
8bd4374909 Throw exception if session created after response
Closes gh-1798
2021-03-25 09:27:27 +02:00
Eleftheria Stein
15f29f8adf Fix README formatting 2021-03-22 12:48:34 +02:00
Eleftheria Stein
74d53e8bfc Add additional information to README 2021-03-22 12:45:51 +02:00
Eleftheria Stein
77deb63373 Fix SessionRepositoryFilter Javadoc 2021-03-17 16:39:45 +01:00
Stefan Wurzinger
69285f2a9a Fix Redis session expiration entry deletion
Closes gh-585
2021-03-12 16:24:48 +01:00
Eleftheria Stein
c93513f18f Fix typo in reference docs 2021-02-09 16:12:51 +01:00
Eleftheria Stein
27044c8766 Make Hazelcast tests independent of ordering
Closes gh-1787
2021-02-02 13:24:24 +01:00
Eleftheria Stein
b198844671 Use io.spring.gradle-enterprise-conventions
Adds support for build cache and build scans

Closes gh-1713
2021-02-01 18:14:28 +01:00
Eleftheria Stein
0f27bbaff7 Update to gradle 6.8.1
Closes gh-1785
2021-02-01 17:32:09 +01:00
Eleftheria Stein
62ad3e1bab Replace deprecated verifyZeroInteractions in tests 2021-01-29 17:00:03 +01:00
Eleftheria Stein
7eed8427a5 Use spring-build-conventions:0.0.37 2021-01-27 11:09:43 +01:00
Eleftheria Stein
4cbb253c11 Resolve artifacts from Maven Central first
- Use spring-build-conventions:0.0.36
- Add https://repo.spring.io/release to reference

Closes gh-1778
2021-01-22 15:27:06 +01:00
Eleftheria Stein
3fe03c60f3 Add manual trigger to CI workflow
Closes gh-1777
2021-01-19 17:37:18 +01:00
Eleftheria Stein
d95652dcb3 Next development version 2021-01-19 14:19:49 +01:00
Eleftheria Stein
cfc1a1e7ce Release 2.5.0-M1 2021-01-19 13:55:51 +01:00
Eleftheria Stein
e17d0cc1d9 Upgrade test dependencies 2021-01-18 12:54:54 +01:00
Eleftheria Stein
0a0766e4a8 Upgrade Hazelcast 4 to 4.1.1
Closes gh-1761
2021-01-18 12:43:34 +01:00
Eleftheria Stein
4108c77797 Upgrade Hazelcast to 3.12.11
Closes gh-1760
2021-01-18 12:41:02 +01:00
Eleftheria Stein
c015a69a4a Upgrade Spring Data to 2021.0.0-M2
Closes gh-1759
2021-01-18 12:39:30 +01:00
Eleftheria Stein
293cf3f730 Upgrade Spring Security to 5.5.0-M1
Closes gh-1758
2021-01-18 12:37:49 +01:00
Eleftheria Stein
6f79e87c8f Upgrade Spring Framework to 5.3.3
Closes gh-1757
2021-01-18 12:35:29 +01:00
Eleftheria Stein
d74c5b1445 Upgrade Reactor to 2020.0.3
Closes gh-1755
2021-01-18 12:34:01 +01:00
Eleftheria Stein
6075089691 Upgrade samples to Spring Boot 2.4.2
Closes gh-1756
2021-01-18 12:31:54 +01:00
Eleftheria Stein
e7a0924904 Upgrade test dependencies 2021-01-12 13:34:47 +01:00
daisuzz
319f0a97ad Fix example in RedisIndexedSessionRepository and Storage Details section
* Fix example in JavaDocs of RedisIndexedSessionRepository

* Fix example in Storage Details section of documentation
2021-01-04 09:32:44 +01:00
Eleftheria Stein
95de199aa4 Upgrade samples to Spring Boot 2.4.1
Closes gh-1744
2020-12-14 09:56:17 +01:00
Eleftheria Stein
db589b7c29 Update community extensions section of reference manual
Closes gh-1736
2020-12-09 13:02:30 +01:00
Vedran Pavic
2aae51b1a1 Rationalize JDBC integration tests
This commit reduces the JDBC integration tests to only single (latest) version per RDBMS vendor, due to a growing number of integration tests. Additionally, the configuration of most containers is simplified due to improved defaults within the Testcontainers library.
2020-11-28 00:26:17 +01:00
Vedran Pavic
e721efeb85 Optimize insert attribute statement in JdbcIndexedSessionRepository
At present, the SQL statement used to insert a session attribute record contains a nested select statement that verifies the existence of parent record in the session table. Such approach can be susceptible to deadlocks on certain RDMBSs.

This commit optimizes the SQL statement used to insert session attribute so that it doesn't perform a nested select statement.

Closes: #1550
2020-11-28 00:26:17 +01:00
Vedran Pavic
0111c6e686 Provide database specific JdbcIndexedSessionRepository customizers
This commit provides JdbcIndexedSessionRepository customizers for the following SQL dialects:

- PostgreSQL
- MySQL (also used by MariaDB)
- SQL Server
- IBM DB2
- Oracle

These customizers are intended to address the concurrency issues occurring on insert of new session attribute by applying SQL dialect specific SQL upsert/merge statement instead of a generic insert.

Closes: #1213
2020-11-27 23:54:03 +01:00
Eleftheria Stein
07058c0cdf Add artifactory credentials to build 2020-11-17 13:59:06 +01:00
Thomas Heigl
5f5168814d Delay allocating Strings for message channel and body 2020-11-10 08:03:57 -05:00
Vedran Pavic
55502f336d Harmonize Redis key namespace configurations
At present, the RedisSessionRepository#setKeyNamespace expects users to provide the trailing colon (:) character that is used as separator between namespace segments. This is unlike RedisIndexedSessionRepository and ReactiveRedisSessionRepository that apply the separator implicitly in their respective #setRedisKeyNamespace methods.

This commit harmonizes the Redis key namespaces configurations across all Redis-backed session repository implementations.
2020-11-10 06:55:19 -05:00
Eleftheria Stein
0e83e3f1e0 Next development version 2020-11-10 11:48:27 +01:00
Eleftheria Stein
34876397a0 Next development version 2020-11-09 16:49:29 +01:00
Eleftheria Stein
faee8f1bdb Release 2.4.1 2020-11-09 15:40:43 +01:00
Eleftheria Stein
859784fe9e Use secrets from GitHub Actions workflow 2020-11-09 15:39:54 +01:00
Eleftheria Stein
4dd2db32d2 Revert "Release 2.4.1"
This reverts commit ae86831821.
2020-11-09 15:39:20 +01:00
Eleftheria Stein
ae86831821 Release 2.4.1 2020-11-04 17:36:47 +01:00
Eleftheria Stein
b722b12327 Fix formatting
Issue gh-1654
2020-10-30 14:34:37 +01:00
Kohei Tamura
29ff2e47fb Add try-with-resources to methods to insert BLOB 2020-10-30 08:45:52 -04:00
Eleftheria Stein
dc9da1d5bf Use OSSRH token credentials in workflow
Closes gh-1725
2020-10-30 13:42:36 +01:00
Eleftheria Stein
5a52df37ba Next development version 2020-10-28 23:36:40 +01:00
Eleftheria Stein
6d161575d5 Release 2.4.0wq 2020-10-28 22:48:46 +01:00
Eleftheria Stein
1cd8849eb9 Revert "Delete Jenkinsfile"
This reverts commit 68f867b60b.
2020-10-28 22:42:47 +01:00
Eleftheria Stein
cb3894614a Revert "Release 2.4.0"
This reverts commit 82e71d834b.
2020-10-28 22:42:06 +01:00
Eleftheria Stein
82e71d834b Release 2.4.0 2020-10-28 18:40:09 +01:00
Eleftheria Stein
81a9e71a5b Upgrade test and sample dependencies
This is needed in order for them to work with Spring Data 2020.0.0
2020-10-28 18:18:45 +01:00
Eleftheria Stein
298f0d59a0 Upgrade Spring Data to 2020.0.0
Closes gh-1721
2020-10-28 18:18:15 +01:00
Eleftheria Stein
c354284616 Upgrade samples to Spring Boot 2.4.0-M4
Closes gh-1722
2020-10-28 18:17:54 +01:00
Eleftheria Stein
4086044c2f Upgrade Spring Framework to 5.3.0
Closes gh-1720
2020-10-28 09:51:48 +01:00
Eleftheria Stein
e663401ecb Upgrade Hazelcast to 3.12.10
Closes gh-1718
2020-10-27 15:50:35 +01:00
Eleftheria Stein
60151c9e7d Upgrade Spring Security to 5.4.1
Closes gh-1717
2020-10-27 15:50:16 +01:00
Eleftheria Stein
18052460c6 Upgrade Reactor to 2020.0.0
Closes gh-1716
2020-10-27 15:49:49 +01:00
Eleftheria Stein
5092e86306 Upgrade samples to Spring Boot 2.3.4.RELEASE
Closes gh-1719
2020-10-27 15:49:19 +01:00
Eleftheria Stein
6de6df6dab Upgrade test dependencies 2020-10-27 15:15:30 +01:00
Vedran Pavic
301e65c2b9 Remove unnecessary Redis commands in RedisIndexedSessionRepository#save
See: #1331
2020-10-12 10:13:38 -04:00
Vedran Pavic
090a10fb10 Improve RedisSessionRepository-based sample configuration 2020-10-12 03:23:21 -04:00
Eleftheria Stein
235801487e Hazelcast4SessionUpdateEntryProcessor does not implement Offloadable
Closes gh-1707
2020-09-25 10:31:54 +02:00
Eleftheria Stein
e6e02de210 Upgrade Hazelcast 4 to 4.0.3
Closes gh-1706
2020-09-22 11:12:58 +02:00
Eleftheria Stein
b3b46fd8eb Upgrade Hazelcast to 3.12.9
Closes gh-1705
2020-09-22 10:46:15 +02:00
Eleftheria Stein
e46610f53a Next development version 2020-09-16 18:39:21 +02:00
Eleftheria Stein
e8c6b8db7b Release 2.4.0-RC1 2020-09-16 18:21:15 +02:00
Eleftheria Stein
486d00e5da Upgrade Spring Data to 2020.0.0-RC1
Closes gh-1704
2020-09-16 18:00:54 +02:00
Eleftheria Stein
0ab781e537 Consolidate Hazelcast configurations
Issue gh-1584
2020-09-16 16:35:03 +02:00
Eleftheria Stein
849b353cec Disable parallel deployment in CI build
Closes gh-1699
2020-09-16 09:59:38 +02:00
Eleftheria Stein
b262c9a3fd Upgrade Spring Framework to 5.3.0-RC1
Closes gh-1698
2020-09-15 17:18:35 +02:00
Eleftheria Stein
5d9e7caff0 Upgrade samples to Spring Boot 2.3.3.RELEASE
Closes gh-1683
2020-09-14 20:06:59 +02:00
Eleftheria Stein
dd348bc7b8 Upgrade test dependencies 2020-09-14 20:06:50 +02:00
Eleftheria Stein
9372986f84 Upgrade Spring Security to 5.4.0
Closes gh-1682
2020-09-14 19:41:49 +02:00
Eleftheria Stein
657c6a63e1 Upgrade Reactor to 2020.0.0-RC1
Closes gh-1681
2020-09-14 19:41:03 +02:00
Eleftheria Stein
a9c2336482 Use controller in Spring Boot sample
Issue gh-1647
2020-09-14 19:04:54 +02:00
Eleftheria Stein
068ed8d355 Ensure Hazelcast 4 compatibility with Java 9+ 2020-09-14 18:25:36 +02:00
Eleftheria Stein
2b6489c2bd Add support for Hazelcast 4
Closes gh-1584
2020-09-14 17:59:35 +02:00
Eleftheria Stein
c0c672b9f8 Update samples module link
Closes gh-1680
2020-09-09 17:04:37 +02:00
Ellie Bahadori
46d1205ff9 Create sample Spring Boot / Hazelcast project
Closes gh-1647
2020-09-09 15:44:31 +02:00
Enes Ozcan
cc85e927cd Add optional Hazelcast session serializer
Issue gh-1131
2020-09-08 07:31:32 -04:00
Ellie Bahadori
0819988a15 Move Gradle enterprise cache secrets to top level of CI build 2020-09-07 07:43:20 -04:00
Ellie Bahadori
0f3ea33b50 Fix indentation for cron job 2020-08-06 04:41:52 -04:00
Ellie Bahadori
0205c318d1 Remove placeholder comment from pipeline file 2020-08-04 05:18:40 -04:00
Ellie Bahadori
13bc1a5d24 Merge pull request #1663 from spring-projects/deploy-pipeline-test
Deploy pipeline test
2020-07-30 16:09:13 -07:00
Ellie Bahadori
8d2ec1ea44 Bring back master branch in preparation for merge
This reverts commit b54fb41952.
2020-07-30 14:53:18 -07:00
Ellie Bahadori
729ce13390 Add Gradle enterprise cache values to build steps 2020-07-30 14:34:37 -07:00
Ellie Bahadori
b54fb41952 Temporarily revert branch name changes to test artifact output
This reverts commit cf911322c2.
2020-07-30 14:10:10 -07:00
Ellie Bahadori
cf911322c2 Update badge to point to master and trigger builds on push to master branch 2020-07-28 11:46:38 -07:00
Ellie Bahadori
6bce5ddf7f Bump spring-build-conventions version and add README badge 2020-07-28 11:43:49 -07:00
Ellie Bahadori
7384504871 Fix YAML spacing issue 2020-07-27 12:14:12 -07:00
Ellie Bahadori
c21fff1a00 Add cron job back in 2020-07-27 11:57:36 -07:00
Ellie Bahadori
d602880a58 Re-introduce JDK matrix for CI pipeline 2020-07-27 11:00:01 -07:00
Ellie Bahadori
2a2c430793 Add URL for maven snapshots 2020-07-27 09:44:26 -07:00
Ellie Bahadori
6080611d1d Bump back up to 0.0.34.BUILD-SNAPSHOT 2020-07-27 09:44:26 -07:00
Ellie Bahadori
38adaeca94 Rev spring build conventions down to 0.0.33.RELEASE 2020-07-27 09:44:26 -07:00
Ellie Bahadori
6a791651e0 Bump spring build conventions version to 0.0.34.BUILD-SNAPSHOT 2020-07-27 09:44:26 -07:00
Ellie Bahadori
dfd6a0bc1b Add in deploy artifacts and docs steps 2020-07-27 09:44:26 -07:00
Ellie Bahadori
805820eeea Remove JDK version matrix for now 2020-07-27 09:44:26 -07:00
Ellie Bahadori
68f867b60b Delete Jenkinsfile 2020-07-27 09:44:26 -07:00
Ellie Bahadori
1044621caf Setup initial CI pipeline file 2020-07-27 09:44:26 -07:00
Eleftheria Stein-Kousathana
13f5cb4bac Document @SpringSessionDataSource in reference docs
Issue gh-1011
2020-07-27 12:14:41 +02:00
Thanh Nhan
5c05970b86 Update OncePerRequestFilter to match with spring-web
Closes gh-1658
2020-07-27 03:58:21 -04:00
Eleftheria Stein-Kousathana
0cd0bfb32f Remove attribute key and value from Redis
Closes gh-1331
2020-07-24 12:55:26 +02:00
Ellie Bahadori
b219806d8e Set up Github Actions pipeline for PRs 2020-07-23 04:01:58 -04:00
Eleftheria Stein
0f2a331ea3 Remove JDK 9 and 10 from Jenkins build
Closes gh-1659
2020-07-16 10:44:26 +02:00
Jay Bryant
ef8f667e35 Wording changes
Replacing some terms
2020-07-16 04:21:23 -04:00
Eleftheria Stein
4599e75c3a Next development version 2020-06-26 18:49:34 +02:00
Eleftheria Stein
8a971b9ce1 Release 2.4.0-M1 2020-06-26 18:25:57 +02:00
Eleftheria Stein
56e9dcfe20 Upgrade Spring Data to 2020.0.0-M1
Closes gh-1648
2020-06-26 11:45:17 -04:00
Eleftheria Stein
59e2cdb74f Upgrade Spring Framework to 5.3.0-M1
Closes gh-1649
2020-06-26 11:45:17 -04:00
Eleftheria Stein
847433562e Upgrade samples to Spring Boot 2.3.1.RELEASE
Closes gh-1650
2020-06-25 21:47:59 +02:00
Eleftheria Stein
55a6967331 Upgrade sample dependencies 2020-06-25 21:13:55 +02:00
Eleftheria Stein
2c8ce67ffc Upgrade Spring Security to 5.3.3.RELEASE
Closes gh-1651
2020-06-25 16:16:57 +02:00
Eleftheria Stein
076ed5cd71 Upgrade Reactor to Dysprosium-SR9
Closes gh-1652
2020-06-25 16:14:49 +02:00
Eleftheria Stein
f1ea71e55e Upgrade test dependencies 2020-06-25 15:41:39 +02:00
Eleftheria Stein
5acb307a54 Upgrade documentation styling
Resolves gh-1640
2020-05-14 16:12:06 -04:00
Eleftheria Stein
f921c4f527 Next development build 2020-05-12 14:41:38 -04:00
Eleftheria Stein
12dc76ec36 Release 2.3.0.RELEASE 2020-05-12 13:05:08 -04:00
Eleftheria Stein
7be3d30981 Upgrade Spring Security to 5.3.2.RELEASE
Resolves gh-1625
2020-05-12 12:58:59 -04:00
Eleftheria Stein
9c8fe23789 Upgrade Spring Data to Neumann-RELEASE
Resolves gh-1623
2020-05-12 12:58:12 -04:00
Eleftheria Stein
3114ef51ec Upgrade samples to Spring Boot 2.2.7
Resolves gh-1624
2020-05-12 12:54:19 -04:00
Kacper
9e7736bf7f Complete Javadoc description of setCookieMaxAge
Issue: gh-1627
2020-05-11 15:16:40 -04:00
Eleftheria Stein
6c5e335568 Upgrade Reactor to Dysprosium-SR7
Resolves gh-1626
2020-05-05 11:19:49 -04:00
Eleftheria Stein
1deedad3b9 Upgrade Spring Framework to 5.2.6.RELEASE
Resolves gh-1622
2020-05-05 11:17:34 -04:00
Eleftheria Stein
e4a8a6aa5c Upgrade test dependencies 2020-05-01 16:46:06 -04:00
Eleftheria Stein
49375a28fa Add guide for customizing cookie in WebFlux
Resolves gh-1614
2020-04-28 16:25:40 -04:00
Eleftheria Stein
5375f51bca Fix broken links in guides
Resolves gh-1621
2020-04-28 14:25:47 -04:00
Eleftheria Stein
29af9d3a4d WebFlux custom cookie sample
Resolves gh-1620
2020-04-22 12:40:40 -04:00
Eleftheria Stein
997ff56c63 Update gitignore 2020-04-22 12:40:40 -04:00
Rob Winch
06d8031211 Add status: waiting-for-triage to issue templates 2020-04-16 16:07:46 -05:00
Rob Winch
904369ac29 Revert PULL_REQUEST_TEMPLATE
Issue gh-1618
2020-04-15 20:34:52 -05:00
Rob Winch
266854a0be Add GitHub Issue Templates
Closes gh-1618
2020-04-15 20:22:29 -05:00
Rob Winch
8f02c83e06 Use GitHub default community health files
Closes gh-1617
2020-04-15 20:22:29 -05:00
Jay Bryant
570a7686b1 Fix a bad typo
Caught an egregious typing error from my own earlier work.
2020-04-15 16:38:40 -04:00
Rob Winch
fed318abc7 Find by Username Sample switch from DELETE to POST
Spring Boot 2.2 no longer adds HiddenHttpMethodFilter by default See
https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.2-Release-Notes#httphiddenmethodfilter-disabled-by-default
This means that trying to map DELETE requests using _method variable
does not work.

This changes the mapping to use a POST which doesn't require the
HiddenHttpMethodFilter which might expose the application to unnecessary
security risk by allowing the HTTP method to be overridden.

Closes gh-1613
2020-04-13 09:41:02 -05:00
Eleftheria Stein
a824edd1c3 Mention Spring Boot implementation detection in docs
Resolves: gh-1610
2020-03-30 13:54:07 -04:00
慕华
aa4f783b45 Update boot-redis.adoc
on-save -> on_save
2020-03-16 08:08:14 -05:00
Eleftheria Stein
11fb68444f Fix invalid reference in docs 2020-03-13 11:04:12 -04:00
Eleftheria Stein
00026a30f4 Fix PDF docs
Resolves: #1603
2020-03-13 10:59:40 -04:00
Eleftheria Stein
c007437bd3 Next Development Build 2020-03-02 17:24:40 -05:00
Eleftheria Stein
dda13b5619 Release 2.3.0.RC1 2020-03-02 17:02:13 -05:00
Eleftheria Stein
366f13bd25 Upgrade Hazelcast to 3.12.6
Resolves: #1591
2020-03-02 16:29:04 -05:00
Eleftheria Stein
3535137c47 Upgrade test dependencies 2020-03-02 16:28:51 -05:00
Eleftheria Stein
a9bca9088f Upgrade Reactor to Dysprosium-SR5
Resolves: #1590
2020-03-02 16:14:41 -05:00
Eleftheria Stein
31de86ecef Upgrade samples to Spring Boot 2.2.5
Resolves: #1589
2020-03-02 15:46:30 -05:00
Eleftheria Stein
d123960f89 Upgrade Spring Data to Neumann-M3
Resolves: #1588
2020-03-02 15:45:19 -05:00
Eleftheria Stein
16d2923efd Upgrade Spring Security to 5.3.0.RC1
Resolves: #1587
2020-03-02 15:44:49 -05:00
Eleftheria Stein
24015d0854 Upgrade Spring Framework to 5.2.4.RELEASE
Resolves: #1586
2020-03-02 15:43:43 -05:00
Eleftheria Stein
d8f160c178 Update documentation styling
Upgrade spring-build-conventions to 0.0.28.RELEASE

Resolves: #1585
2020-03-02 15:30:29 -05:00
Eleftheria Stein
0318f6e2c1 Fix asciidoctor warnings
Invalid references and mismatched nesting blocks
2020-03-02 09:13:17 -05:00
Eleftheria Stein
43dd571345 Fix typo in Javadoc 2020-02-27 16:32:29 -05:00
Adam Kucera
e7fb9fce47 Fix examples in JavaDocs of classes which use SessionRepositories
The examples in JavaDocs of @EnableSpringHttpSession, SpringHttpSessionConfiguration and @EnableSpringWebSession were creating MapSessionRepository / ReactiveMapSessionRepository
using a constructor, which no longer exists in the classes. This should allow the example
to be used out of the box.
2020-02-20 15:25:46 -05:00
Eleftheria Stein
f13eb8d73e Use Spring Security lambda DSL in samples
Fixes: gh-1580
2020-02-19 12:36:51 +01:00
Jivko Vantchev
1a07ba5114 Fixes the duplicate index name in the example SQL script
The change is in the comments for the JdbcIndexedSessionRepository.
2020-02-14 12:03:24 +01:00
Eleftheria Stein
7125aac567 Next Development Build 2020-01-29 22:18:06 +01:00
Eleftheria Stein
3cbd3a9e25 Release 2.3.0.M1 2020-01-29 21:54:34 +01:00
Eleftheria Stein
4c914d46c9 Upgrade Spring Framework to 5.2.3.RELEASE
Resolves: #1575
2020-01-29 21:47:32 +01:00
Eleftheria Stein
adf411ecc3 Upgrade Spring Security to 5.3.0.M1
Resolves: #1568
2020-01-29 21:12:50 +01:00
Eleftheria Stein
95b39a203f Upgrade Spring Data to Neumann-M2
Resolves: #1567
2020-01-29 21:12:06 +01:00
Eleftheria Stein
3d653b3b50 Next Development Build 2020-01-29 21:08:14 +01:00
Eleftheria Stein
938fd3c2e5 Next Development Build 2020-01-29 20:55:04 +01:00
Eleftheria Stein
45bb0f9b0c Run deployArtifacts before finalizeDeployArtifacts in build
This commit is needed to fix the release

Resolves: #1574
2020-01-29 16:39:07 +01:00
Eleftheria Stein
cddd84d564 Release 2.2.1.RELEASE 2020-01-28 10:57:10 +01:00
Eleftheria Stein
6931d40e6e Upgrade samples to Spring Boot 2.2.4.RELEASE
Resolves: #1563
2020-01-28 10:26:32 +01:00
Eleftheria Stein
3b672787f3 Upgrade Spring Data to Moore-SR4
Resolves: #1564
2020-01-28 10:22:14 +01:00
Eleftheria Stein
c0ee52b33b Upgrade Reactor to Dysprosium-SR4
Resolves: #1565
2020-01-28 10:21:32 +01:00
Eleftheria Stein
68f8641233 Upgrade Spring Security to 5.2.1.RELEASE
Resolves: #1566
2020-01-28 10:20:48 +01:00
Eleftheria Stein
e7b2af47e1 Upgrade Hazelcast to 3.12.5
Resolves: #1569
2020-01-28 10:19:16 +01:00
Eleftheria Stein
1ad6cbd7f8 Update note in custom-cookie index page
Resolves: gh-1559
2020-01-13 11:57:20 +01:00
Rob Winch
195af52d0b Upgrade to Spring Framework 5.2.2.RELEASE
Fixes gh-1548
2019-12-13 07:06:19 -06:00
Vedran Pavic
bc9d5f1299 Start building against Spring Framework 5.2.2.RELEASE snapshots
See: #1548
2019-11-16 10:20:11 +01:00
Vedran Pavic
3a4345eb6a Upgrade Gradle to 5.6.4 2019-11-15 22:23:23 +01:00
Vedran Pavic
6c41dea893 Polish contribution
Resolves: #1543
2019-11-15 22:10:35 +01:00
Eleftheria Stein
ee1d5b3b3c Document support for SameSite cookie directive
See: #1543
2019-11-15 22:06:13 +01:00
Christoph Dreis
89a4255679 Parse expression only once in PrincipalNameIndexResolver
Resolves: #1539
2019-11-15 12:13:42 +01:00
Rob Winch
6d2e51a0b9 Next Development Build 2019-10-15 15:32:01 -05:00
Rob Winch
798d398d9b Release 2.2.0.RELEASE 2019-10-15 15:31:21 -05:00
Vedran Pavic
085554f56b Polish DefaultCookieSerializer
See: #1514
2019-10-09 08:58:42 +02:00
Vedran Pavic
45b3b35db7 Update Travis CI config 2019-10-08 12:28:42 +02:00
Vedran Pavic
2d06e1159c Improve Hazelcast integration tests
Resolves: #1534
2019-10-08 12:04:42 +02:00
Vedran Pavic
927008bdc8 Ensure session cookie's expires directive uses GMT format
Resolves: #1514
2019-10-07 21:54:00 +02:00
Vedran Pavic
30588dc3c8 Improve Hazelcast client-server topology integration tests
Resolves: #1527
2019-10-06 15:54:02 +02:00
Vedran Pavic
2f79da00dc Upgrade Hazelcast to 3.12.3
Resolves: #1525
2019-10-06 11:41:03 +02:00
Vedran Pavic
e2abe36fa8 Upgrade samples to Spring Boot 2.2.0.RC1
Resolves: #1521
2019-10-03 17:16:59 +02:00
Vedran Pavic
456fd3adb4 Next development version 2019-10-01 06:26:41 +02:00
Vedran Pavic
bd0f474b5b Release 2.2.0.RC1 2019-10-01 06:25:43 +02:00
Vedran Pavic
e5a3933cb6 Upgrade spring-build-conventions to 0.0.27.RELEASE 2019-10-01 06:09:41 +02:00
Vedran Pavic
71e5cc857a Use Jackson 2.10.0 in samples
See: #1508
2019-10-01 00:28:34 +02:00
Vedran Pavic
df455ddc89 Upgrade Spring Security to 5.2.0.RELEASE
Resolves: #1508
2019-09-30 23:55:50 +02:00
Vedran Pavic
eceeaa665d Use Reactor Dysprosium-RELEASE in samples
See: #1509
2019-09-30 21:47:08 +02:00
Vedran Pavic
e6c54d8a75 Upgrade Spring Data to Moore-RELEASE
Resolves: #1507
2019-09-30 21:42:47 +02:00
Vedran Pavic
c88456a183 Rework scheduling configurers into nested configuration
This commit extracts scheduling configurers that are used in Redis and JDBC configurations into nested configuration classes in order to avoid bean method references.

Resolves: #1516
2019-09-30 16:08:55 +02:00
Vedran Pavic
f5abd55394 Ensure proxyBeanMethods is set to false everywhere
This commit sets proxyBeanMethods to false on all @Enable*Session annotations since they are meta-annotated with @Configuration.

See: #1516
2019-09-30 16:08:55 +02:00
Vedran Pavic
b9fd3666b5 Update integration tests 2019-09-30 16:08:20 +02:00
Vedran Pavic
e06ea36ad5 Upgrade test dependencies 2019-09-30 16:08:18 +02:00
Vedran Pavic
0a1701233e Upgrade Spring Framework to 5.2.0.RELEASE
Resolves: #1506
2019-09-30 09:55:05 +02:00
Vedran Pavic
47a4873199 Align TransactionOperations usage with Spring Framework 5.2.0.RELEASE
See: #1506
2019-09-29 22:12:30 +02:00
Vedran Pavic
bd36e115a8 Align with spring-javaformat 0.0.15 2019-09-29 16:16:36 +02:00
Vedran Pavic
ec82336477 Parallelize JDBC integration tests
See: #1505
2019-09-27 07:14:23 +02:00
Vedran Pavic
feaf8780a8 Add support for configuring custom IndexResolver
See: #1467
2019-09-26 22:18:37 +02:00
Vedran Pavic
b357a76ce3 Align Spring Data Redis dependency excludes with Moore-RELEASE
See: #1507
2019-09-26 14:42:22 +02:00
Vedran Pavic
2c6f22afb0 Upgrade Reactor to Dysprosium-RELEASE
Resolves: #1509
2019-09-25 00:30:42 +02:00
Vedran Pavic
34306fd3a0 Fix Gradle dependency caching configuration
See: #1505
2019-09-24 20:50:58 +02:00
Vedran Pavic
a6c1d8eb1d Tweak Gradle JVM memory settings
See: #1505
2019-09-23 22:35:34 +02:00
Vedran Pavic
e48b46a2d5 Improve support for Oracle integration tests
Resolves: #1510
2019-09-23 22:35:33 +02:00
Vedran Pavic
8cc8fbb7fd Harmonize naming of session repositories
Resolves: #1455
2019-09-22 21:47:53 +02:00
Vedran Pavic
96715e04f2 Start building against Reactor Dysprosium-RELEASE snapshots
See: #1509
2019-09-17 22:12:04 +02:00
Vedran Pavic
121a633a40 Optimize project build
This commit optimizes build by:
- configuring Gradle JVM memory settings
- configuring parallel execution
- disabling caching of snapshots

Resolves: #1505
2019-09-17 22:07:44 +02:00
Vedran Pavic
bf31a9b04b Start building against Spring Security 5.2.0.RELEASE snapshots
See: #1508
2019-09-12 22:47:01 +02:00
Vedran Pavic
a209d436d1 Start building against Spring Data Moore-RELEASE snapshots
See: #1507
2019-09-12 22:46:18 +02:00
Vedran Pavic
6c76a1ccdd Start building against Spring Framework 5.2.0.RELEASE snapshots
See: #1506
2019-09-12 22:45:33 +02:00
Vedran Pavic
c974eeb188 Upgrade samples to Spring Boot 2.2.0.M6
Resolves: #1504
2019-09-11 22:38:38 +02:00
Rob Winch
3b5dadb07f Next Development Version 2019-09-06 11:54:55 -05:00
Rob Winch
3e6b3fda0f Release 2.2.0.M4 2019-09-06 11:36:11 -05:00
Rob Winch
840da7fb5a Update to Spring Security 5.2.0.RC1
Fixes gh-1487
2019-09-06 09:31:24 -05:00
Vedran Pavic
560ee5ff4f Upgrade Spring Data to Moore-RC3
Resolves: #1486
2019-09-06 13:17:30 +02:00
Vedran Pavic
072348e28f Upgrade Gradle to 5.6.2 2019-09-05 22:19:39 +02:00
Vedran Pavic
99dfdda7b7 Upgrade Spring Framework to 5.2.0.RC2
Resolves: #1485
2019-09-05 13:12:34 +02:00
Vedran Pavic
18b097d9c7 Upgrade Reactor to Dysprosium-RC1
Resolves: #1498
2019-09-04 07:12:21 +02:00
Vedran Pavic
702a35fac6 Update integration tests 2019-09-03 22:54:57 +02:00
Vedran Pavic
df3e4c5bc1 Add support for customizing session repository before initialization
This commit adds support for customizing session repository implementations (both SessionRepository and ReactiveSessionRepository) before initialization by introducing SessionRepositoryCustomizer and ReactiveSessionRepositoryCustomizer strategies.

Resolves: #1499
2019-09-03 22:17:36 +02:00
Lars Grefer
f746233255 Upgrade Gradle to 5.6.1
Resolves: #1496
2019-08-30 22:44:42 +02:00
Vedran Pavic
f6c82f1eee Improve support for customizing JDBC session store transaction behavior
Resolves: #1469
2019-08-23 23:26:11 +02:00
Josh Cummings
bcdd05a0bc Add OnCommittedResponseWrapper.setContentLengthLong
Add setContentLengthLong tracking to OnCommittedResponseWrapper in
order to detect commits on servlets that use setContentLengthLong to
announce the entity size they are about to write (as used in the
Apache Tomcat's DefaultServlet).

Fixes gh-1489
2019-08-20 13:29:52 -06:00
Vedran Pavic
5d26ab4df4 Add support for AuthenticatedPrincipal in SpringSessionBackedSessionRegistry
Resolves: #1488
2019-08-10 11:23:25 +02:00
Vedran Pavic
e55d86f5e2 Start building against Spring Security 5.2.0.RC1 snapshots
See: #1487
2019-08-07 21:21:34 +02:00
Vedran Pavic
fe480b338c Start building against Spring Data Moore-RC3 snapshots
See: #1486
2019-08-07 21:13:03 +02:00
Vedran Pavic
4b13392430 Start building against Spring Framework 5.2.0.RC2 snapshots
See: #1485
2019-08-07 21:11:34 +02:00
Vedran Pavic
e5d9ce6ead Upgrade samples to Spring Boot 2.2.0.M5
Resolves: #1484
2019-08-06 18:07:18 +02:00
Vedran Pavic
bc1ef4359a Next development version 2019-08-05 22:18:02 +02:00
Vedran Pavic
98fa5ed52d Release 2.2.0.M3 2019-08-05 22:16:41 +02:00
Vedran Pavic
44468134aa Upgrade samples to Spring Framework 5.2.0.RC1
See: #1460
2019-08-05 21:58:23 +02:00
Vedran Pavic
c14c621da6 Remove Spring Framework snapshot dependency from samples
See: #1460
2019-08-05 21:43:53 +02:00
Vedran Pavic
6ceca18248 Revert to development version 2019-08-05 21:23:54 +02:00
Vedran Pavic
229ca09f10 Release 2.2.0.M3 2019-08-05 21:12:00 +02:00
Vedran Pavic
36b82d52f8 Upgrade Spring Security to 5.2.0.M4
Resolves: #1462
2019-08-05 20:49:04 +02:00
Vedran Pavic
dbeb33fd9d Add flush mode support for JDBC sessions
Resolves: #1468
2019-08-05 18:58:29 +02:00
Vedran Pavic
23bf92a086 Upgrade Spring Data to Moore-RC2
Resolves: #1461
2019-08-05 16:04:58 +02:00
Vedran Pavic
2e0c347a3a Update integration tests 2019-08-05 13:26:34 +02:00
Vedran Pavic
972537a3d5 Upgrade test dependencies 2019-08-05 13:25:15 +02:00
Vedran Pavic
99c4f5bc32 Upgrade Spring Framework to 5.2.0.RC1
Resolves: #1460
2019-08-05 12:53:10 +02:00
Vedran Pavic
89f8127763 Upgrade test dependencies 2019-08-02 22:43:08 +02:00
Vedran Pavic
63f1013a07 Upgrade Hazelcast to 3.12.2
Resolves: #1483
2019-08-02 22:39:28 +02:00
Vedran Pavic
a988b062c3 Add IBM DB2 integration tests
Resolves: #1482
2019-08-02 01:11:02 +02:00
Vedran Pavic
09368243aa Update integration tests 2019-07-30 23:28:54 +02:00
Vedran Pavic
903fa10861 Polish 2019-07-30 23:08:13 +02:00
Vedran Pavic
a883e2ee77 Upgrade test dependencies 2019-07-30 20:00:37 +02:00
Vedran Pavic
f68e569bec Upgrade Reactor to Dysprosium-M3
Resolves: #1474
2019-07-30 19:40:58 +02:00
Vedran Pavic
593c126c03 Filtering for nested ERROR dispatch
Resolves: #1470
See: spring-projects/spring-framework#23196
2019-07-19 20:38:30 +02:00
Vedran Pavic
033d6eecae Add support for session save mode
This commit introduces SaveMode enum that individual SessionRepository implementations use to allow customization of the way they handle save operation in terms of tracking delta of changes.

Resolves: #1466
2019-07-14 10:35:05 +02:00
Vedran Pavic
24b9d24e18 Upgrade Gradle to 5.5.1 2019-07-12 17:40:31 +02:00
Vedran Pavic
46bc4b0957 Use no-op TransactionOperations 2019-07-07 13:40:59 +02:00
Vedran Pavic
8cb85618c2 Polish 2019-07-02 23:19:11 +02:00
Vedran Pavic
1ca9daccb4 Remove unnecessary throws declaration 2019-07-02 19:23:35 +02:00
Vedran Pavic
0731e7f2d0 Upgrade Gradle to 5.5 2019-07-02 18:50:52 +02:00
Vedran Pavic
8d0d757e46 Polish 2019-06-25 22:11:29 +02:00
Vedran Pavic
e2f1fe5446 Add missing deprecation
See: #1465
2019-06-25 21:50:03 +02:00
Vedran Pavic
07b9433540 Add common flush mode support
Resolves: #1465
2019-06-24 19:11:12 +02:00
Vedran Pavic
a6f6042831 Introduce IndexResolver
This commit introduces IndexResolver as a strategy interface for resolving index values in FindByIndexNameSessionRepository implementations.

Resolves: #557
2019-06-24 12:01:26 +02:00
Vedran Pavic
099be441dd Fix copyright dates
See: #1441
2019-06-21 15:52:26 +02:00
Rob Winch
17d029d34d Add spring-session label to Jenkins check node
Try and troubleshoot failures in Jenkins
2019-06-20 13:16:17 -05:00
Vedran Pavic
aab9b39a6b Remove immediate flush mode support for reactive Redis sessions
Resolves: #1441
2019-06-20 10:44:22 +02:00
Vedran Pavic
090d882f98 Start building against Spring Security 5.2 snapshots
See: #1462
2019-06-19 16:55:26 +02:00
Vedran Pavic
d91d09567f Start building against Spring Data Moore snapshots
See: #1461
2019-06-19 16:54:55 +02:00
Vedran Pavic
ab5b0e3a32 Start building against Spring Framework 5.2 snapshots
See: #1460
2019-06-19 16:54:31 +02:00
Vedran Pavic
549a2b7f0b Upgrade samples to Spring Boot 2.2.0.M4
Resolves: #1459
2019-06-19 16:51:12 +02:00
Craig Andrews
050ff7538b In Oracle ignore non-existant tables when dropping
If tables don't exist, ignore that error when dropping.

This aligns Oracle with the existing mysql, postgresql, h2, and hsqldb behavior.
2019-06-19 08:25:44 -05:00
Vedran Pavic
e8e65ac09f Add IntelliJ IDEA specific config
See: #1450
2019-06-18 22:48:25 +02:00
Vedran Pavic
822db7fbbf Use spring-javaformat to format and check code
Resolves: #1450
2019-06-17 23:54:41 +02:00
Vedran Pavic
0eaeb98b0c Next development version 2019-06-14 23:27:58 +02:00
Vedran Pavic
546febd959 Release 2.2.0.M2 2019-06-14 23:26:47 +02:00
Vedran Pavic
ea857025bc Upgrade Spring Security to 5.2.0.M3
Resolves: #1437
2019-06-14 23:04:55 +02:00
Vedran Pavic
782167b306 Add SimpleRedisOperationsSessionRepository sample
Resolves: #1408
2019-06-14 22:55:38 +02:00
Vedran Pavic
17005c51a7 Add simple Redis SessionRepository implementation
See: #1408
2019-06-14 22:55:21 +02:00
Vedran Pavic
54859070f3 Extract RedisSessionMapper
See: #1408
2019-06-14 22:55:11 +02:00
Vedran Pavic
3d03c02924 Upgrade Spring Data to Moore-RC1
Resolves: #1436
2019-06-14 15:38:52 +02:00
Vedran Pavic
4f9d55feec Update integration tests 2019-06-13 18:36:49 +02:00
Vedran Pavic
7e7d08a99f Upgrade test dependencies 2019-06-13 18:32:27 +02:00
Vedran Pavic
f6a5bdacb8 Upgrade Hazelcast to 3.12.1
Resolves: #1452
2019-06-13 18:17:59 +02:00
Vedran Pavic
79de4f9a0d Upgrade Spring Framework to 5.2.0.M3
Resolves: #1414
2019-06-13 18:15:47 +02:00
Vedran Pavic
9a379fd5bc Upgrade Reactor to Dysprosium-M2
Resolves: #1416
2019-06-11 11:25:10 +02:00
Vedran Pavic
be58c00838 Separate "filtered" attribute for ERROR dispatch
Resolves: #1308
See: spring-projects/spring-framework#22989
2019-06-11 07:27:25 +02:00
Vedran Pavic
3475043bf0 Polish build
See: spring-projects/spring-security#6200
2019-06-11 07:27:25 +02:00
Rob Winch
c6470c6f48 Jenkinsfile performs git clean 2019-06-10 16:50:35 -05:00
Rob Winch
6faa67a64e Add nohttp 2019-06-10 14:55:06 -05:00
Vedran Pavic
340b614860 Upgrade samples to Spring Boot 2.2.0.M2
Resolves: #1445
2019-06-10 09:14:05 +02:00
Vedran Pavic
79b092d8f0 Align Selenium version used in samples with Spring Boot 2.2
See: #1445
2019-06-09 15:44:40 +02:00
Vedran Pavic
2e91024a56 Fix integration tests
See: #1033
2019-06-09 10:54:28 +02:00
Vedran Pavic
e359468abc Fix broken documentation links
See: #1447
2019-06-09 10:52:45 +02:00
Vedran Pavic
4ec6a9a08b Upgrade samples to Spring Boot 2.2.0.M3
Resolves: #1445
2019-06-06 21:55:07 +02:00
Vedran Pavic
084d1c7286 Simplify project structure
- harmonize module and directory names
- optimize Gradle settings
- remove unused Grails sample

Resolves: #1447
2019-06-06 21:12:30 +02:00
Vedran Pavic
a4ff3682f6 Migrate tests to JUnit 5
Resolves: #1033
2019-06-06 20:57:45 +02:00
Vedran Pavic
35f09d0da7 Start building against Reactor Dysprosium snapshots
See: #1416
2019-06-04 21:56:29 +02:00
Vedran Pavic
566b388b2f Align Checkstyle config with Spring Boot 2019-06-03 16:49:08 +02:00
Vedran Pavic
78b72f2d1b Save reactive Redis session on subscribe
This commit ensures ReactiveRedisOperationsSessionRepository#save does work only after subscribe. Without this, multiple invocations of #save over the course of same request can lead to race condition situations.

Resolves: #1399
2019-06-02 19:02:13 +02:00
Vedran Pavic
52f59a83e4 Update integration tests 2019-05-31 23:31:01 +02:00
Vedran Pavic
6809168541 Upgrade test dependencies 2019-05-31 23:13:28 +02:00
Vedran Pavic
02bb998f97 Start building against Spring Security 5.2 snapshots
See: #1437
2019-05-31 23:07:10 +02:00
Vedran Pavic
57ffb90a0c Start building against Spring Data Moore snapshots
See: #1436
2019-05-31 23:06:33 +02:00
Vedran Pavic
402272d5aa Start building against Spring Framework 5.2 snapshots
See: #1414
2019-05-31 23:05:38 +02:00
Vedran Pavic
1dbaffef5e Update Jenkinsfile 2019-05-27 20:28:34 +02:00
Vedran Pavic
8ae0e0b314 Update Jenkinsfile to use explicit JAVA_HOME 2019-05-27 07:27:34 +02:00
Rob Winch
d94d58d96b Redis save uses then
We need to ensure that the session id is changed before we save the
changes. Otherwise the rename of the session id will override the
changes we just made.

Fixes: gh-1428
2019-05-16 15:51:51 -05:00
Vedran Pavic
cc41ea5271 Ensure Redis session with immediate flush respects defaultMaxInactiveInterval
Resolves: #1409
2019-05-13 19:08:03 +02:00
Vedran Pavic
e6a88ccf4c Add Java 12 CI build
Resolves: #1422
2019-05-10 22:18:59 +02:00
Vedran Pavic
36f1cd5302 Revert "Add Java 12 CI build"
See: #1422
2019-05-10 09:39:24 +02:00
Vedran Pavic
3bd892ec16 Upgrade Gradle to 5.4.1 2019-05-10 09:25:46 +02:00
Vedran Pavic
dcd5342204 Add Java 12 CI build
Resolves: #1422
2019-05-10 09:24:29 +02:00
Vedran Pavic
48c32228de Upgrade Spring Framework to 5.2.0.M1
Resolves: #1414
2019-05-09 19:05:56 +02:00
Vedran Pavic
ec8ef595a2 Upgrade Reactor to Dysprosium-M1
Resolves: #1416
2019-05-09 18:49:24 +02:00
Vedran Pavic
b98c5216b4 Update configuration classes to use proxyBeanMethods=false
Resolves: #1345
2019-05-09 18:10:57 +02:00
Vedran Pavic
eb0f89a18a Start building against Spring Framework 5.2 snapshots
See: #1414
2019-05-09 18:03:56 +02:00
Vedran Pavic
83e0f4f24a Fix JdbcOperationsSessionRepository lazy deserialization
Resolves: #1411
2019-05-06 23:37:08 +02:00
Vedran Pavic
397d4e5ca1 Next development version 2019-04-12 20:51:00 +02:00
Vedran Pavic
f7b7737896 Release 2.2.0.M1 2019-04-12 20:38:14 +02:00
Vedran Pavic
2a5b221d70 Update integration tests 2019-04-12 20:14:12 +02:00
Vedran Pavic
5a462b3594 Resolve indexes for Hazelcast session on write
Resolves: #1145
2019-04-12 20:08:54 +02:00
Vedran Pavic
c252c00a85 Upgrade Spring Data to Moore-M3
Resolves: #1317
2019-04-11 15:49:31 +02:00
Vedran Pavic
2a7b6ec4f7 Upgrade Spring Security to 5.2.0.M1
Resolves: #1318
2019-04-11 07:39:26 +02:00
Vedran Pavic
044e5bbe3c Upgrade Spring Framework to 5.2.0.M1
Resolves: #1348
2019-04-10 16:05:35 +02:00
Vedran Pavic
f247a78c32 Revert Derby dependency upgrade 2019-04-10 09:23:02 +02:00
Vedran Pavic
c0f708d0b3 Upgrade Reactor to Californium-SR6 2019-04-09 21:31:58 +02:00
Vedran Pavic
c2a3ffdb00 Upgrade Hazelcast to 3.12
Resolves: #1403
2019-04-09 21:28:45 +02:00
Vedran Pavic
856a9b2c51 Update integration tests 2019-04-09 21:24:55 +02:00
Vedran Pavic
0d24033749 Upgrade test dependencies 2019-04-09 21:19:01 +02:00
Vedran Pavic
7a5f9bc29e Polish 2019-03-29 21:41:09 +01:00
Vedran Pavic
094ffe8a60 Avoid conflicts with user provided RedisMessageListenerContainer
Resolves: #1252
2019-03-29 21:27:56 +01:00
Vedran Pavic
55102aa8bb Update to latest Checkstyle DTDs 2019-03-29 21:27:56 +01:00
Vedran Pavic
f2e9634789 Fix Checkstyle config 2019-03-29 21:27:56 +01:00
Vedran Pavic
7dccade893 Upgrade spring-build-conventions to 0.0.25.RELEASE 2019-03-29 21:27:54 +01:00
Vedran Pavic
39408ff42a Upgrade Gradle to 5.3.1 2019-03-29 17:54:09 +01:00
Spring Operator
a5a3bc5d0b URL Cleanup
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended.

* [ ] http://www.ultraq.net.nz/thymeleaf/layout (302) with 12 occurrences migrated to:
  https://github.com/ultraq/thymeleaf-layout-dialect ([https](https://www.ultraq.net.nz/thymeleaf/layout) result ConnectTimeoutException).
* [ ] http://192.168.1.100:8080/ (AnnotatedConnectException) with 1 occurrences migrated to:
  https://192.168.1.100:8080/ ([https](https://192.168.1.100:8080/) result ConnectTimeoutException).

These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* [ ] http://docs.hazelcast.org/docs/ with 8 occurrences migrated to:
  https://docs.hazelcast.org/docs/ ([https](https://docs.hazelcast.org/docs/) result 200).
* [ ] http://docs.spring.io/spring-data/data-redis/docs/current/reference/html/ with 1 occurrences migrated to:
  https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/ ([https](https://docs.spring.io/spring-data/data-redis/docs/current/reference/html/) result 200).
* [ ] http://docs.spring.io/spring-session/docs/current/reference/html5/ with 1 occurrences migrated to:
  https://docs.spring.io/spring-session/docs/current/reference/html5/ ([https](https://docs.spring.io/spring-session/docs/current/reference/html5/) result 200).
* [ ] http://infinispan.org/docs/dev/user_guide/user_guide.html with 1 occurrences migrated to:
  https://infinispan.org/docs/dev/user_guide/user_guide.html ([https](https://infinispan.org/docs/dev/user_guide/user_guide.html) result 200).
* [ ] http://logback.qos.ch/manual/groovy.html with 1 occurrences migrated to:
  https://logback.qos.ch/manual/groovy.html ([https](https://logback.qos.ch/manual/groovy.html) result 200).
* [ ] http://projects.spring.io/spring-session/ with 1 occurrences migrated to:
  https://projects.spring.io/spring-session/ ([https](https://projects.spring.io/spring-session/) result 200).
* [ ] http://redis.io/commands/expire with 1 occurrences migrated to:
  https://redis.io/commands/expire ([https](https://redis.io/commands/expire) result 200).
* [ ] http://redis.io/commands/hmset with 1 occurrences migrated to:
  https://redis.io/commands/hmset ([https](https://redis.io/commands/hmset) result 200).
* [ ] http://redis.io/topics/data-types with 1 occurrences migrated to:
  https://redis.io/topics/data-types ([https](https://redis.io/topics/data-types) result 200).
* [ ] http://redis.io/topics/notifications with 2 occurrences migrated to:
  https://redis.io/topics/notifications ([https](https://redis.io/topics/notifications) result 200).
* [ ] http://stackoverflow.com with 1 occurrences migrated to:
  https://stackoverflow.com ([https](https://stackoverflow.com) result 200).
* [ ] http://stackoverflow.com/tags/spring-session with 1 occurrences migrated to:
  https://stackoverflow.com/tags/spring-session ([https](https://stackoverflow.com/tags/spring-session) result 200).
* [ ] http://www.thymeleaf.org with 12 occurrences migrated to:
  https://www.thymeleaf.org ([https](https://www.thymeleaf.org) result 200).
* [ ] http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-3.dtd with 5 occurrences migrated to:
  https://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-3.dtd ([https](https://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-3.dtd) result 200).
* [ ] http://contributor-covenant.org with 1 occurrences migrated to:
  https://contributor-covenant.org ([https](https://contributor-covenant.org) result 301).
* [ ] http://contributor-covenant.org/version/1/3/0/ with 1 occurrences migrated to:
  https://contributor-covenant.org/version/1/3/0/ ([https](https://contributor-covenant.org/version/1/3/0/) result 301).
* [ ] http://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-data-tier.html with 2 occurrences migrated to:
  https://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-data-tier.html ([https](https://docs.spring.io/spring/docs/current/spring-framework-reference/html/spring-data-tier.html) result 301).
* [ ] http://www.maxmind.com with 2 occurrences migrated to:
  https://www.maxmind.com ([https](https://www.maxmind.com) result 302).

These URLs were intentionally ignored.

* http://java.sun.com/jsp/jstl/core with 8 occurrences
* http://localhost with 15 occurrences
* http://localhost:8080/ with 31 occurrences
* http://localhost:8080/h2-console/ with 3 occurrences
* http://localhost:8080/logout with 1 occurrences
* http://localhost:8080/test/index with 2 occurrences
* http://localhost:xxxxx/hazelcast/rest/maps/spring:session:sessions/7e8383a4-082c-4ffe-a4bc-c40fd3363c5e with 1 occurrences
* http://www.w3.org/1999/xhtml with 5 occurrences
* http://www.webjars.org/tags with 8 occurrences

Fixes gh-1375
2019-03-22 10:24:07 -04:00
Spring Operator
90c08340fa URL Cleanup
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended.

* http://www.puppycrawl.com/dtds/configuration_1_3.dtd (404) with 1 occurrences migrated to:
  https://www.puppycrawl.com/dtds/configuration_1_3.dtd ([https](https://www.puppycrawl.com/dtds/configuration_1_3.dtd) result 404).
* http://www.puppycrawl.com/dtds/suppressions_1_1.dtd (404) with 1 occurrences migrated to:
  https://www.puppycrawl.com/dtds/suppressions_1_1.dtd ([https](https://www.puppycrawl.com/dtds/suppressions_1_1.dtd) result 404).

These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* http://www.hazelcast.com/schema/config/hazelcast-config-3.11.xsd with 3 occurrences migrated to:
  https://www.hazelcast.com/schema/config/hazelcast-config-3.11.xsd ([https](https://www.hazelcast.com/schema/config/hazelcast-config-3.11.xsd) result 200).
* http://www.springframework.org/schema/beans/spring-beans.xsd with 9 occurrences migrated to:
  https://www.springframework.org/schema/beans/spring-beans.xsd ([https](https://www.springframework.org/schema/beans/spring-beans.xsd) result 200).
* http://www.springframework.org/schema/context/spring-context.xsd with 7 occurrences migrated to:
  https://www.springframework.org/schema/context/spring-context.xsd ([https](https://www.springframework.org/schema/context/spring-context.xsd) result 200).
* http://www.springframework.org/schema/jdbc/spring-jdbc.xsd with 1 occurrences migrated to:
  https://www.springframework.org/schema/jdbc/spring-jdbc.xsd ([https](https://www.springframework.org/schema/jdbc/spring-jdbc.xsd) result 200).
* http://www.springframework.org/schema/security/spring-security.xsd with 2 occurrences migrated to:
  https://www.springframework.org/schema/security/spring-security.xsd ([https](https://www.springframework.org/schema/security/spring-security.xsd) result 200).
* http://www.springframework.org/schema/util/spring-util-4.1.xsd with 2 occurrences migrated to:
  https://www.springframework.org/schema/util/spring-util-4.1.xsd ([https](https://www.springframework.org/schema/util/spring-util-4.1.xsd) result 200).
* http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd with 2 occurrences migrated to:
  https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd ([https](https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd) result 302).

These URLs were intentionally ignored.

* http://java.sun.com/xml/ns/javaee with 4 occurrences
* http://www.hazelcast.com/schema/config with 6 occurrences
* http://www.springframework.org/schema/beans with 18 occurrences
* http://www.springframework.org/schema/context with 14 occurrences
* http://www.springframework.org/schema/jdbc with 2 occurrences
* http://www.springframework.org/schema/p with 5 occurrences
* http://www.springframework.org/schema/security with 4 occurrences
* http://www.springframework.org/schema/util with 4 occurrences
* http://www.w3.org/2001/XMLSchema-instance with 14 occurrences

Fixes gh-1374
2019-03-21 16:59:05 -04:00
Rob Winch
13208dd3b5 Update Checkstyle to https Apache 2 License
Issue gh-1369
2019-03-14 22:27:27 -05:00
Spring Operator
0975d4d47e URL Cleanup
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# Fixed URLs

## Fixed Success
These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* http://www.apache.org/licenses/ with 1 occurrences migrated to:
  https://www.apache.org/licenses/ ([https](https://www.apache.org/licenses/) result 200).
* http://www.apache.org/licenses/LICENSE-2.0 with 269 occurrences migrated to:
  https://www.apache.org/licenses/LICENSE-2.0 ([https](https://www.apache.org/licenses/LICENSE-2.0) result 200).
* http://www.apache.org/licenses/LICENSE-2.0.html with 1 occurrences migrated to:
  https://www.apache.org/licenses/LICENSE-2.0.html ([https](https://www.apache.org/licenses/LICENSE-2.0.html) result 200).
2019-03-14 20:39:41 -05:00
Vedran Pavic
0c0bfa4414 Remove special handling for Servlet 3.0 and below
Closes: #1363
2019-03-14 21:59:45 +01:00
Vedran Pavic
8b40e8cce8 Rework RedisHttpSessionConfiguration to bean method invocations
Closes: #1362
2019-03-14 21:34:53 +01:00
Vedran Pavic
408f2da108 Start building against Spring Data Moore snapshots
See: #1317
2019-03-13 18:18:16 +01:00
Vedran Pavic
3b7bb7ec12 Start building against Spring Framework 5.2 snapshots
See: #1348
2019-03-13 18:18:16 +01:00
Vedran Pavic
4c849caccd Next development version 2019-03-13 18:09:34 +01:00
Vedran Pavic
ea84b8bd22 Upgrade samples to Spring Boot 2.1.3.RELEASE
Resolves: #1357
2019-03-12 18:29:26 +01:00
Jay Bryant
0c9fbedd05 Editing pass
I edited for spelling, grammar, punctuation, usage, and corporate voice, with the goal of making this content be consistent with our other content.
2019-02-15 13:33:51 -06:00
Rob Winch
08495b1321 Next Development Version 2019-02-13 19:55:46 -06:00
Rob Winch
60cd6d8be6 Release 2.1.4.RELEASE 2019-02-13 15:55:29 -06:00
Rob Winch
5503057523 Update to Spring Security 5.1.4
Fixes: gh-1329
2019-02-13 15:54:46 -06:00
Vedran Pavic
8fc2f1130a Update integration tests 2019-02-13 19:36:48 +01:00
Vedran Pavic
f5d63efcf1 Upgrade test dependencies 2019-02-13 19:32:40 +01:00
Vedran Pavic
ed76514f30 Upgrade spring-build-conventions to 0.0.23.RELEASE 2019-02-13 19:26:19 +01:00
Vedran Pavic
e1c0d62d33 Upgrade Reactor to Californium-SR5
Resolves: #1326
2019-02-13 19:24:42 +01:00
Vedran Pavic
8041358d18 Upgrade Spring Data to Lovelace-SR5
Resolves: #1325
2019-02-13 19:24:09 +01:00
Vedran Pavic
cdd85cb349 Upgrade Spring Framework to 5.1.5.RELEASE
Resolves: #1324
2019-02-13 19:23:46 +01:00
Vedran Pavic
381a07cb8c Ignore failed rename operation for deleted session
In scenario with concurrent requests attempting to change session id, the "ERR no such key" error will occur for a thread that comes in second. This commit addresses the problem by ignoring the aforementioned error.

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

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

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

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

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

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

Resolves: #1203
See also: #1031
2018-09-25 18:45:02 +02:00
Vedran Pavic
3df3b30117 Upgrade Testcontainers to 1.9.1 2018-09-25 18:31:52 +02:00
Vedran Pavic
5fb0c4dd35 Improve JDBC integration tests 2018-09-24 06:30:47 +02:00
Vedran Pavic
6fbce6e3e8 Next development version 2018-09-21 21:27:42 +02:00
Vedran Pavic
a3fd05326a Release 2.1.0.RC1 2018-09-21 21:26:28 +02:00
Vedran Pavic
4c6dc976b3 Upgrade Testcontainers to 1.9.0-rc2 2018-09-21 19:22:12 +02:00
Vedran Pavic
58ae28b0a0 Fix SpringSessionRememberMeServices documentation example
Resolves: #1157
2018-09-21 19:05:33 +02:00
Vedran Pavic
3e98ecf234 Upgrade Spring Security to 5.1.0.RELEASE
Resolves: #1188
2018-09-21 19:01:15 +02:00
Vedran Pavic
41ed429f98 Upgrade Spring Data to Lovelace-RELEASE
Resolves: #1190
2018-09-21 19:00:38 +02:00
Vedran Pavic
def15b05ca Upgrade Spring Framework to 5.1.0.RELEASE
Resolves: #1187
2018-09-21 11:10:33 +02:00
Vedran Pavic
eae8592f2b Upgrade integration tests 2018-09-20 19:48:33 +02:00
Vedran Pavic
81460ede09 Make SessionUpdateEntryProcessor implement Offloadable
Resolves: #1204
2018-09-20 19:31:55 +02:00
Vedran Pavic
ca4ec9a557 Upgrade test dependencies 2018-09-20 19:23:24 +02:00
Vedran Pavic
fd2165f471 Upgrade Hazelcast to 3.10.5
Resolves: #1206
2018-09-20 19:23:24 +02:00
Vedran Pavic
ad1e57a1fe Upgrade Gradle to 4.10.2 2018-09-20 19:15:26 +02:00
Vedran Pavic
0ffcaa2d35 Upgrade Reactor to Californium-RELEASE
Resolves: #1189
2018-09-20 11:45:33 +02:00
Vedran Pavic
b61937def7 Polish contribution
Resolves: #1133
2018-09-19 23:53:38 +02:00
Craig Andrews
c523fb591d Deserialize attributes lazily in JdbcOperationsSessionRepository
Instead of deserializing all of the session attributes as they are read from the database, deserialize as #getAttribute requests them.

See: #1133
2018-09-19 23:48:15 +02:00
Vedran Pavic
227fab2e42 Adjust CI build timeouts 2018-09-19 00:45:20 +02:00
Vedran Pavic
7f7815d80c Upgrade spring-build-conventions to 0.0.19.RELEASE 2018-09-19 00:01:06 +02:00
Vedran Pavic
002136bad4 Align WebSession#save implementations with API
Closes gh-1135
2018-09-18 23:58:59 +02:00
Vedran Pavic
1085661984 Enable integration tests for JDK 10 and 11 builds
See: #1196, #1197
2018-09-18 20:04:23 +02:00
Vedran Pavic
12bb0741bb Add Java 11 CI build
Closes gh-1197
2018-09-17 18:02:07 +02:00
Vedran Pavic
eecdcb49d9 Remove node designation from JDK 10 build
See gh-1196
2018-09-17 17:59:40 +02:00
Vedran Pavic
3e1a22102d Ensure compatibility with Java 9 and 10
Closes gh-1196
2018-09-16 22:13:56 +02:00
Vedran Pavic
9f6e791e5d Upgrade samples to Spring Boot 2.1.0.M3
Closes gh-1195
2018-09-13 21:04:43 +02:00
Vedran Pavic
efc35eddad Upgrade Gradle to 4.10.1 2018-09-13 20:59:49 +02:00
Vedran Pavic
4c37ec9f4a Update Jenkinsfile to specify node label 2018-09-13 18:08:17 +02:00
Vedran Pavic
1a3da5944d Polish
See gh-1128
2018-09-13 08:55:13 +02:00
Vedran Pavic
5d0775b802 Ensure RedisHttpSessionConfiguration handles events for configured database
At present, RedisHttpSessionConfiguration doesn't take into account database index when handlng events. In situations where multiple apps use Spring Session with same Redis instance, but different database, this results in invalid session events.

This commits improves event handling in RedisHttpSessionConfiguration to ensure currently used database is considered.

Closes gh-1128
2018-09-12 23:07:52 +02:00
Vedran Pavic
603a258172 Upgrade Testcontainers to 1.9.0-rc1 2018-09-11 23:06:10 +02:00
Vedran Pavic
22ebe65931 Next development version 2018-09-10 22:42:32 +02:00
Vedran Pavic
55033bcb64 Release 2.1.0.M3 2018-09-10 22:40:21 +02:00
Vedran Pavic
57955b7d7b Polish
See gh-1111
2018-09-10 17:03:10 +02:00
Vedran Pavic
d5da38f2e0 Upgrade test dependencies 2018-09-10 16:56:08 +02:00
Vedran Pavic
6cc4bcd13d Verify session existence before update in ReactiveRedisOperationsSessionRepository
Currently, ReactiveRedisOperationsSessionRepository#save does not ensure session's existence before executing update. This can result in an invalid session record in Redis, since write use only delta, and in turn to error while retrieving the invalid session record.

This commit adds check for session existence if session is being updated.

Closes gh-1111
2018-09-09 23:55:27 +02:00
Vedran Pavic
dc43f5bd2d Upgrade Spring Security to 5.1.0.RC2
Closes gh-1171
2018-09-07 23:48:18 +02:00
Vedran Pavic
7584cbd54c Upgrade Spring Framework to 5.1.0.RC3
Closes gh-1170
2018-09-07 17:40:18 +02:00
Vedran Pavic
0db1160dc4 Upgrade Reactor to Californium-RC1
Closes gh-1172
2018-09-07 07:48:08 +02:00
Vedran Pavic
10a18366f9 Update integration tests 2018-09-07 07:46:10 +02:00
Vedran Pavic
7ea5e2f3ee Upgrade test dependencies 2018-09-06 21:15:47 +02:00
Vedran Pavic
d3134ad065 Ignore failed rename operation for deleted session
Attempting to change session id for a deleted session currently results in "ERR no such key" error on rename operation of expired key. This commit addressed the problem by ignoring the aforementioned error.

Closes #1137
2018-09-04 23:07:27 +02:00
Vedran Pavic
6208d0298d Upgrade Gradle to 4.10 2018-09-04 21:57:04 +02:00
Vedran Pavic
c031ee278d Add javadoc for RedisOperationsSessionRepository#getSessionRedisOperations
Closes #1175
2018-09-03 23:29:50 +02:00
Vedran Pavic
8267a90fcc Polish contribution
See #1173
2018-09-03 23:28:14 +02:00
Johnny Lim
2113b330a7 Add @since for ReactiveRedisOperationsSR.getSessionRedisOperations() 2018-08-31 10:29:09 -05:00
Vedran Pavic
c4ac68b777 Fix Jenkinsfile 2018-08-27 09:26:55 +02:00
Vedran Pavic
0be2759e68 Fix Jenkinsfile 2018-08-27 08:24:36 +02:00
Vedran Pavic
1181e52bb0 Upgrade spring-build-conventions to 0.0.18.RELEASE 2018-08-24 23:50:23 +02:00
Vedran Pavic
5277d945ed Upgrade samples to Spring Boot 2.1.0.M2
Closes gh-1168
2018-08-22 18:31:30 +02:00
Rob Winch
1fc0162fe9 Fix settings.gradle on Windows
Fixes: gh-1167
2018-08-22 10:23:29 -05:00
Vedran Pavic
9df259b1ae Next development version 2018-08-21 06:34:09 +02:00
563 changed files with 21317 additions and 14969 deletions

View File

@@ -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
View 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
View 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

View 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?
-->

View 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
View 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
View File

@@ -13,3 +13,4 @@ out
.checkstyle
!etc/eclipse/.checkstyle
!**/src/**/build
.DS_Store

View File

@@ -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

View File

@@ -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
http://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at
http://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]

View File

@@ -3,15 +3,22 @@
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
We use GitHub issues to track bugs and enhancements. If you have a general usage question
please ask on http://stackoverflow.com[Stack Overflow]. The Spring Session team and the
broader community monitor the http://stackoverflow.com/tags/spring-session[`spring-session`]
please ask on https://stackoverflow.com[Stack Overflow]. The Spring Session team and the
broader community monitor the https://stackoverflow.com/tags/spring-session[`spring-session`]
tag.
If you are reporting a bug, please help to speed up problem diagnosis by providing as much
@@ -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].

95
Jenkinsfile vendored
View File

@@ -1,95 +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: 30, unit: 'MINUTES') {
node {
checkout scm
try {
sh './gradlew clean check --no-daemon --refresh-dependencies'
}
catch (e) {
currentBuild.result = 'FAILED: check'
throw e
}
finally {
junit '**/build/*-results/*.xml'
}
}
}
}
}
if (currentBuild.result == 'SUCCESS') {
parallel artifacts: {
stage('Deploy Artifacts') {
node {
checkout scm
try {
withCredentials([file(credentialsId: 'spring-signing-secring.gpg', variable: 'SIGNING_KEYRING_FILE')]) {
withCredentials([string(credentialsId: 'spring-gpg-passphrase', variable: 'SIGNING_PASSWORD')]) {
withCredentials([usernamePassword(credentialsId: 'oss-token', passwordVariable: 'OSSRH_PASSWORD', usernameVariable: 'OSSRH_USERNAME')]) {
withCredentials([usernamePassword(credentialsId: '02bd1690-b54f-4c9f-819d-a77cb7a9822c', usernameVariable: 'ARTIFACTORY_USERNAME', passwordVariable: 'ARTIFACTORY_PASSWORD')]) {
sh './gradlew deployArtifacts finalizeDeployArtifacts --stacktrace --no-daemon --refresh-dependencies -Psigning.secretKeyRingFile=$SIGNING_KEYRING_FILE -Psigning.keyId=$SPRING_SIGNING_KEYID -Psigning.password=$SIGNING_PASSWORD -PossrhUsername=$OSSRH_USERNAME -PossrhPassword=$OSSRH_PASSWORD -PartifactoryUsername=$ARTIFACTORY_USERNAME -PartifactoryPassword=$ARTIFACTORY_PASSWORD'
}
}
}
}
}
catch (e) {
currentBuild.result = 'FAILED: artifacts'
throw e
}
}
}
},
docs: {
stage('Deploy Docs') {
node {
checkout scm
try {
withCredentials([file(credentialsId: 'docs.spring.io-jenkins_private_ssh_key', variable: 'DEPLOY_SSH_KEY')]) {
sh './gradlew deployDocs --stacktrace --no-daemon --refresh-dependencies -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME'
}
}
catch (e) {
currentBuild.result = 'FAILED: docs'
throw e
}
}
}
}
}
}
finally {
def buildStatus = currentBuild.result
def buildNotSuccess = !SUCCESS.equals(buildStatus)
def lastBuildNotSuccess = !SUCCESS.equals(currentBuild.previousBuild?.result)
if (buildNotSuccess || lastBuildNotSuccess) {
stage('Notify') {
node {
final def RECIPIENTS = [[$class: 'DevelopersRecipientProvider'], [$class: 'RequesterRecipientProvider']]
def subject = "${buildStatus}: Build ${env.JOB_NAME} ${env.BUILD_NUMBER} status is now ${buildStatus}"
def details = "The build status changed to ${buildStatus}. For details see ${env.BUILD_URL}"
emailext(
subject: subject,
body: details,
recipientProviders: RECIPIENTS,
to: "$SPRING_SESSION_TEAM_EMAILS"
)
}
}
}
}

View File

@@ -1,7 +1,7 @@
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
@@ -193,7 +193,7 @@
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
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,

View File

@@ -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,22 +13,62 @@ 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 http://projects.spring.io/spring-session/
Please see our https://github.com/spring-projects/.github/blob/main/CODE_OF_CONDUCT.md[code of conduct].
== License
Spring Session is Open Source software released under the http://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].
Spring Session is Open Source software released under the https://www.apache.org/licenses/LICENSE-2.0.html[Apache 2.0 license].

View File

@@ -1,20 +1,45 @@
buildscript {
ext {
releaseBuild = version.endsWith('RELEASE')
snapshotBuild = version.endsWith('SNAPSHOT')
milestoneBuild = !(releaseBuild || snapshotBuild)
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.17.RELEASE'
classpath 'io.spring.gradle:spring-build-conventions:0.0.37'
classpath "org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion"
}
repositories {
maven { url 'https://repo.spring.io/plugins-release' }
}
}
apply plugin: 'io.spring.convention.root'
group = 'org.springframework.session'
description = 'Spring Session'
subprojects {
apply plugin: 'io.spring.javaformat'
ext.releaseBuild = version.endsWith('RELEASE')
ext.snapshotBuild = version.endsWith('SNAPSHOT')
ext.milestoneBuild = !(releaseBuild || snapshotBuild)
plugins.withType(JavaPlugin) {
sourceCompatibility = JavaVersion.VERSION_1_8
}
tasks.withType(Test) {
useJUnitPlatform()
}
}

View File

@@ -1,140 +0,0 @@
= Spring Session - find by username
Rob Winch
:toc:
This guide describes how to use Spring Session to find sessions by username.
NOTE: The completed guide can be found in the <<findbyusername-sample, findbyusername application>>.
[[findbyusername-assumptions]]
== Assumptions
The guide assumes you have already added Spring Session using the built in Redis configuration support to your application.
The guide also assumes you have already applied Spring Security to your application.
However, we the guide will be somewhat general purpose and can be applied to any technology with minimal changes we will discuss.
[NOTE]
====
If you need to learn how to add Spring Session to your project, please refer to the listing of link:../#samples[samples and guides]
====
== About the Sample
Our sample is using this feature to invalidate the users session that might have been compromised.
Consider the following scenario:
* User goes to library and authenticates to the application
* User goes home and realizes they forgot to log out
* User can log in and terminate the session from the library using clues like the location, created time, last accessed time, etc.
Wouldn't it be nice if we could allow the user to invalidate the session at the library from any device they authenticate with?
This sample demonstrates how this is possible.
[[findbyindexnamesessionrepository]]
== FindByIndexNameSessionRepository
In order to look up a user by their username, you must first choose a `SessionRepository` that implements link:../#api-findbyindexnamesessionrepository[FindByIndexNameSessionRepository].
Our sample application assumes that the Redis support is already setup, so we are ready to go.
== Mapping the username
`FindByIndexNameSessionRepository` can only find a session by the username, if the developer instructs Spring Session what user is associated with the `Session`.
This is done by ensuring that the session attribute with the name `FindByUsernameSessionRepository.PRINCIPAL_NAME_INDEX_NAME` is populated with the username.
Generally, speaking this can be done with the following code immediately after the user authenticates:
[source,java,indent=0]
----
include::{docs-test-dir}docs/FindByIndexNameSessionRepositoryTests.java[tags=set-username]
----
== Mapping the username with Spring Security
Since we are using Spring Security, the user name is automatically indexed for us.
This means we will not have to perform any steps to ensure the user name is indexed.
== Adding Additional Data to Session
It may be nice to associate additional information (i.e. IP Address, the browser, location, etc) to the session.
This makes it easier for the user to know which session they are looking at.
To do this simply determine which session attribute you want to use and what information you wish to provide.
Then create a Java bean that is added as a session attribute.
For example, our sample application includes the location and access type of the session
[source,java,indent=0]
----
include::{samples-dir}boot/findbyusername/src/main/java/sample/session/SessionDetails.java[tags=class]
----
We then inject that information into the session on each HTTP request using a `SessionDetailsFilter`.
For example:
[source,java,indent=0]
----
include::{samples-dir}boot/findbyusername/src/main/java/sample/session/SessionDetailsFilter.java[tags=dofilterinternal]
----
We obtain the information we want and then set the `SessionDetails` as an attribute in the `Session`.
When we retrieve the `Session` by username, we can then use the session to access our `SessionDetails` just like any other session attribute.
[NOTE]
====
You might be wondering at this point why Spring Session does not provide `SessionDetails` functionality out of the box.
The reason, is twofold.
The first is that it is very trivial for applications to implement this themselves.
The second reason is that the information that is populated in the session (and how frequently that information is updated) is highly application dependent.
====
== Finding sessions for a specific user
We can now find all the sessions for a specific user.
[source,java,indent=0]
----
include::{samples-dir}boot/findbyusername/src/main/java/sample/mvc/IndexController.java[tags=findbyusername]
----
In our instance, we find all sessions for the currently logged in user.
However, this could easily be modified for an administrator to use a form to specify which user to look up.
[[findbyusername-sample]]
== findbyusername Sample Application
=== Running the findbyusername Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
[NOTE]
====
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
----
$ ./gradlew :spring-session-sample-boot-findbyusername:bootRun
----
You should now be able to access the application at http://localhost:8080/
=== Exploring the security Sample Application
Try using the application. Enter the following to log in:
* **Username** _user_
* **Password** _password_
Now click the **Login** button.
You should now see a message indicating your are logged in with the user entered previously.
You should also see a listing of active sessions for the currently logged in user.
Let's emulate the flow we discussed in the <<About the Sample>> section
* Open a new incognito window and navigate to http://localhost:8080/
* Enter the following to log in:
** **Username** _user_
** **Password** _password_
* Terminate your original session
* Refresh the original window and see you are logged out

View File

@@ -1,127 +0,0 @@
= Spring Session - Spring Boot
Rob Winch, Vedran Pavić
:toc:
This guide describes how to use Spring Session to transparently leverage a relational database to back a web application's `HttpSession` when using Spring Boot.
NOTE: The completed guide can be found in the <<httpsession-jdbc-boot-sample, httpsession-jdbc-boot sample application>>.
== Updating Dependencies
Before you use Spring Session, you must ensure to update your dependencies.
We assume you are working with a working Spring Boot web application.
If you are using Maven, ensure to add the following dependencies:
.pom.xml
[source,xml]
[subs="verbatim,attributes"]
----
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
</dependency>
</dependencies>
----
Spring Boot provides dependency management for Spring Session modules, so there's no need to explicitly declare dependency version.
// tag::config[]
[[httpsession-jdbc-boot-spring-configuration]]
== Spring Boot Configuration
After adding the required dependencies, we can create our Spring Boot configuration.
Thanks to first-class auto configuration support, setting up Spring Session backed by a relational database is as simple as adding a single configuration property to your `application.properties`:
.src/main/resources/application.properties
----
spring.session.store-type=jdbc # Session store type.
----
Under the hood, Spring Boot will apply configuration that is equivalent to manually adding `@EnableJdbcHttpSession` annotation.
This creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.
The filter is what is in charge of replacing the `HttpSession` implementation to be backed by Spring Session.
Further customization is possible using `application.properties`:
.src/main/resources/application.properties
----
server.servlet.session.timeout= # Session timeout. If a duration suffix is not specified, seconds will be used.
spring.session.jdbc.initialize-schema=embedded # Database schema initialization mode.
spring.session.jdbc.schema=classpath:org/springframework/session/jdbc/schema-@@platform@@.sql # Path to the SQL file to use to initialize the database schema.
spring.session.jdbc.table-name=SPRING_SESSION # Name of the database table used to store sessions.
----
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-session[Spring Session] portion of the Spring Boot documentation.
[[httpsession-jdbc-boot-configuration]]
== Configuring the DataSource
Spring Boot automatically creates a `DataSource` that connects Spring Session to an embedded instance of H2 database.
In a production environment you need to ensure to update your configuration to point to your relational database.
For example, you can include the following in your *application.properties*
.src/main/resources/application.properties
----
spring.datasource.url= # JDBC URL of the database.
spring.datasource.username= # Login username of the database.
spring.datasource.password= # Login password of the database.
----
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-configure-datasource[Configure a DataSource] portion of the Spring Boot documentation.
[[httpsession-jdbc-boot-servlet-configuration]]
== Servlet Container Initialization
Our <<httpsession-jdbc-boot-spring-configuration,Spring Boot Configuration>> created a Spring Bean named `springSessionRepositoryFilter` that implements `Filter`.
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.
In order for our `Filter` to do its magic, Spring needs to load our `Config` class.
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
Fortunately, Spring Boot takes care of both of these steps for us.
// end::config[]
[[httpsession-jdbc-boot-sample]]
== httpsession-jdbc-boot Sample Application
The httpsession-jdbc-boot Sample Application demonstrates how to use Spring Session to transparently leverage H2 database to back a web application's `HttpSession` when using Spring Boot.
[[httpsession-jdbc-boot-running]]
=== Running the httpsession-jdbc-boot Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
----
$ ./gradlew :spring-session-sample-boot-jdbc:bootRun
----
You should now be able to access the application at http://localhost:8080/
[[httpsession-jdbc-boot-explore]]
=== Exploring the security Sample Application
Try using the application. Enter the following to log in:
* **Username** _user_
* **Password** _password_
Now click the **Login** button.
You should now see a message indicating your are logged in with the user entered previously.
The user's information is stored in H2 database rather than Tomcat's `HttpSession` implementation.
[[httpsession-jdbc-boot-how]]
=== How does it work?
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in H2 database.
Spring Session replaces the `HttpSession` with an implementation that is backed by a relational database.
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into H2 database.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using H2 web console available at: http://localhost:8080/h2-console/ (use `jdbc:h2:mem:testdb` for JDBC URL)
Now visit the application at http://localhost:8080/ and observe that we are no longer authenticated.

View File

@@ -1,138 +0,0 @@
= Spring Session - WebSocket
Rob Winch
:toc:
:websocketdoc-test-dir: {docs-test-dir}docs/websocket/
This guide describes how to use Spring Session to ensure that WebSocket messages keep your HttpSession alive.
// tag::disclaimer[]
NOTE: Spring Session's WebSocket support only works with Spring's WebSocket support.
Specifically it does not work with using https://www.jcp.org/en/jsr/detail?id=356[JSR-356] directly.
This is due to the fact that JSR-356 does not have a mechanism for intercepting incoming WebSocket messages.
// end::disclaimer[]
== HttpSession Setup
The first step is to integrate Spring Session with the HttpSession. These steps are already outlined in the link:httpsession.html[HttpSession Guide].
Please make sure you have already integrated Spring Session with the HttpSession before proceeding.
// tag::config[]
[[websocket-spring-configuration]]
== Spring Configuration
In a typical Spring WebSocket application users would implement `WebSocketMessageBrokerConfigurer`.
For example, the configuration might look something like the following:
[source,java]
----
include::{websocketdoc-test-dir}WebSocketConfig.java[tags=class]
----
We can easily update our configuration to use Spring Session's WebSocket support.
For example:
.src/main/java/samples/config/WebSocketConfig.java
[source,java]
----
include::{samples-dir}boot/websocket/src/main/java/sample/config/WebSocketConfig.java[tags=class]
----
To hook in the Spring Session support we only need to change two things:
<1> Instead of implementing `WebSocketMessageBrokerConfigurer` we extend `AbstractSessionWebSocketMessageBrokerConfigurer`
<2> We rename the `registerStompEndpoints` method to `configureStompEndpoints`
What does `AbstractSessionWebSocketMessageBrokerConfigurer` do behind the scenes?
* `WebSocketConnectHandlerDecoratorFactory` is added as a `WebSocketHandlerDecoratorFactory` to `WebSocketTransportRegistration`.
This ensures a custom `SessionConnectEvent` is fired that contains the `WebSocketSession`.
The `WebSocketSession` is necessary to terminate any WebSocket connections that are still open when a Spring Session is terminated.
* `SessionRepositoryMessageInterceptor` is added as a `HandshakeInterceptor` to every `StompWebSocketEndpointRegistration`.
This ensures that the Session is added to the WebSocket properties to enable updating the last accessed time.
* `SessionRepositoryMessageInterceptor` is added as a `ChannelInterceptor` to our inbound `ChannelRegistration`.
This ensures that every time an inbound message is received, that the last accessed time of our Spring Session is updated.
* `WebSocketRegistryListener` is created as a Spring Bean.
This ensures that we have a mapping of all of the Session id to the corresponding WebSocket connections.
By maintaining this mapping, we can close all the WebSocket connections when a Spring Session (HttpSession) is terminated.
// end::config[]
[[websocket-sample]]
== websocket Sample Application
The websocket sample application demonstrates how to use Spring Session with WebSockets.
=== Running the websocket Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
[TIP]
====
For the purposes of testing session expiration, you may want to change the session expiration to be 1 minute (default is 30 minutes) by adding the following configuration property starting before the application:
.src/main/resources/application.properties
----
server.servlet.session.timeout=1m # Session timeout. If a duration suffix is not specified, seconds will be used.
----
====
[NOTE]
====
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
----
$ ./gradlew :spring-session-sample-boot-websocket:bootRun
----
You should now be able to access the application at http://localhost:8080/
=== Exploring the websocket Sample Application
Try using the application. Authenticate with the following information:
* **Username** _rob_
* **Password** _password_
Now click the **Login** button. You should now be authenticated as the user **rob**.
Open an incognito window and access http://localhost:8080/
You will be prompted with a log in form. Authenticate with the following information:
* **Username** _luke_
* **Password** _password_
Now send a message from *rob* to *luke*. The message should appear.
Wait for two minutes and try sending a message from *rob* to *luke* again.
You will see that the message is no longer sent.
[NOTE]
.Why two minutes?
====
Spring Session will expire in 60 seconds, but the notification from Redis is not guaranteed to happen within 60 seconds.
To ensure the socket is closed in a reasonable amount of time, Spring Session runs a background task every minute at 00 seconds that forcibly cleans up any expired sessions.
This means you will need to wait at most two minutes before the WebSocket connection is terminated.
====
Try accessing http://localhost:8080/
You will be prompted to authenticate again.
This demonstrates that the session properly expires.
Now repeat the same exercise, but instead of waiting two minutes send a message from *each* of the users every 30 seconds.
You will see that the messages continue to be sent.
Try accessing http://localhost:8080/
You will not be prompted to authenticate again.
This demonstrates the session is kept alive.
NOTE: Only messages sent from a user keep the session alive.
This is because only messages coming from a user imply user activity.
Messages received do not imply activity and thus do not renew the session expiration.

View File

@@ -1,133 +0,0 @@
= Spring Session - Grails
Eric Helgeson
:toc:
This guide describes how to use Spring Session to transparently leverage Redis to back a web application's `HttpSession` when using Grails 3.1
NOTE: Grails 3.1 is based off spring boot 1.3 so much of the advanced configuration and options can be found in the boot docs as well.
NOTE: The completed guide can be found in the <<grails3-sample, Grails 3 sample application>>.
== Updating Dependencies
Before you use Spring Session, you must ensure to update your dependencies.
We assume you are working with a working Grails 3.1 web profile.
Add the following dependencies:
.build.gradle
[source,groovy]
[subs="verbatim,attributes"]
----
dependencies {
compile 'org.springframework.boot:spring-boot-starter-redis'
compile 'org.springframework.session:spring-session:{spring-session-version}'
}
----
ifeval::["{version-snapshot}" == "true"]
Since We are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
Ensure you have the following in your pom.xml:
.build.gradle
[source,groovy]
----
repositories {
maven {
url 'https://repo.spring.io/libs-snapshot'
}
}
----
endif::[]
ifeval::["{version-milestone}" == "true"]
Since We are using a Milestone version, we need to ensure to add the Spring Milestone Maven Repository.
Ensure you have the following in your pom.xml:
.build.gradle
[source,groovy]
----
repositories {
maven {
url 'https://repo.spring.io/libs-milestone'
}
}
----
endif::[]
[[grails3-redis-configuration]]
== Configuring the Redis Connection
Spring Boot automatically creates a `RedisConnectionFactory` that connects Spring Session to a Redis Server on localhost on port 6379 (default port).
In a production environment you need to ensure to update your configuration to point to your Redis server.
For example, you can include the following in your *application.yml*
.grails-app/conf/application.yml
[source,yml]
----
spring:
redis:
host: localhost
password: secret
port: 6397
----
For more information, refer to https://docs.spring.io/spring-boot/docs/{spring-boot-version}/reference/htmlsingle/#boot-features-connecting-to-redis[Connecting to Redis] portion of the Spring Boot documentation.
[[grails3-sample]]
== Grails 3 Sample Application
The Grails 3 Sample Application demonstrates how to use Spring Session to transparently leverage Redis to back a web application's `HttpSession` when using Grails.
[[grails3-running]]
=== Running the Grails 3 Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
[NOTE]
====
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
----
$ ./gradlew :spring-session-sample-misc-grails3:bootRun
----
You should now be able to access the application at http://localhost:8080/test/index
[[grails3-explore]]
=== Exploring the security Sample Application
Try using the application. Enter the following to log in:
* **Username** _user_
* **Password** _password_
Now click the **Login** button.
You should now see a message indicating your are logged in with the user entered previously.
The user's information is stored in Redis rather than Tomcat's `HttpSession` implementation.
[[grails3-how]]
=== How does it work?
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in Redis.
Spring Session replaces the `HttpSession` with an implementation that is backed by Redis.
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Redis.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using redis-cli. For example, on a Linux based system you can type:
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:
$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
Now visit the application at http://localhost:8080/test/index and observe that we are no longer authenticated.
NOTE: Spring Session will not work with grails flash scope without additional work. +
See this answer for an explanation: https://stackoverflow.com/a/43311427

View File

@@ -1,102 +0,0 @@
= Spring Session - Custom Cookie
Rob Winch
:toc:
This guide describes how to configure Spring Session to use custom cookies with Java Configuration.
The guide assumes you have already link:./httpsession.html[setup Spring Session in your project].
NOTE: The completed guide can be found in the <<custom-cookie-sample, Custom Cookie sample application>>.
[[custom-cookie-spring-configuration]]
== Spring Java Configuration
Once you have setup Spring Session you can easily customize how the session cookie is written by exposing a `CookieSerializer` as a Spring Bean.
Out of the box, Spring Session comes with `DefaultCookieSerializer`.
Simply exposing the `DefaultCookieSerializer` as a Spring Bean will augment the existing configuration when using configurations like `@EnableRedisHttpSession`.
You can find an example of customizing Spring Session's cookie below:
[source,java]
----
include::{samples-dir}javaconfig/custom-cookie/src/main/java/sample/Config.java[tags=cookie-serializer]
----
<1> We customize the name of the cookie to be JSESSIONID
<2> We customize the path of the cookie to be "/" (rather than the default of the context root)
<3> We customize the domain name pattern (a regular expression) to be `^.+?\\.(\\w+\\.[a-z]+)$`
This allows sharing a session across domains and applications.
If the regular expression does not match, no domain is set and the existing domain will be used.
If the regular expression matches, the first https://docs.oracle.com/javase/tutorial/essential/regex/groups.html[grouping] will be used as the domain.
This means that a request to https://child.example.com will set the domain to example.com.
However, a request to http://localhost:8080/ or http://192.168.1.100:8080/ will leave the cookie unset and thus still work in development without any changes necessary for production.
[WARNING]
====
It is important to note that users should only match on valid domain characters since the domain name is reflected in the response.
This is prevent a malicious user from performing attacks like https://en.wikipedia.org/wiki/HTTP_response_splitting[HTTP Response Splitting].
====
[[custom-cookie-options]]
== Configuration Options
The configuration options available are:
* `cookieName` - the name of the cookie to use
Default "SESSION"
* `useSecureCookie` - specify if a secure cookie be used
Default use value of `HttpServletRequest.isSecure()` at the time of creation.
* `cookiePath` - the path of the cookie
Default is context root
* `cookieMaxAge` - specifies the max age of the cookie to be set at the time the session is created.
Default is -1 which indicates the cookie will be removed when the browser is closed.
* `jvmRoute` - specifies a suffix to be appended to the session id and included in the cookie.
Used to identify which JVM to route to for session affinity.
With some implementations (i.e. Redis) this provides no performance benefit.
However, this can help with tracing logs of a particular user.
* `domainName` - allows specifying a specific domain name to be used for the cookie.
This option is simple to understand, but will likely require a different configuration between development and production environments.
See domainNamePattern as an alternative.
* `domainNamePattern` - a case insensitive pattern used to extract the domain name from the `HttpServletRequest#getServerName()`.
The pattern should provide a single grouping used to extract the value of the cookie domain.
If the regular expression does not match, no domain is set and the existing domain will be used.
If the regular expression matches, the first https://docs.oracle.com/javase/tutorial/essential/regex/groups.html[grouping] will be used as the domain.
[WARNING]
====
It is important to note that users should only match on valid domain characters since the domain name is reflected in the response.
This is prevent a malicious user from performing attacks like https://en.wikipedia.org/wiki/HTTP_response_splitting[HTTP Response Splitting].
====
[[custom-cookie-sample]]
== custom-cookie Sample Application
=== Running the custom-cookie Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
[NOTE]
====
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
----
$ ./gradlew :spring-session-sample-javaconfig-custom-cookie:tomcatRun
----
You should now be able to access the application at http://localhost:8080/
=== Exploring the custom-cookie Sample Application
Try using the application. Fill out the form with the following information:
* **Attribute Name:** _username_
* **Attribute Value:** _rob_
Now click the **Set Attribute** button.
You should now see the values displayed in the table.
If you look at the cookies for the application, you can see the cookie is saved to the custom name of JSESSIONID

View File

@@ -1,195 +0,0 @@
= Spring Session and Spring Security with Hazelcast
Tommy Ludwig; Rob Winch
:toc:
This guide describes how to use Spring Session along with Spring Security using Hazelcast as your data store.
It assumes you have already applied Spring Security to your application.
NOTE: The completed guide can be found in the <<hazelcast-spring-security-sample, Hazelcast Spring Security sample application>>.
== Updating Dependencies
Before you use Spring Session, you must ensure to update your dependencies.
If you are using Maven, ensure to add the following dependencies:
.pom.xml
[source,xml]
[subs="verbatim,attributes"]
----
<dependencies>
<!-- ... -->
<dependency>
<groupId>com.hazelcast</groupId>
<artifactId>hazelcast</artifactId>
<version>{hazelcast-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
ifeval::["{version-snapshot}" == "true"]
Since We are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repositories>
<!-- ... -->
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
----
endif::[]
ifeval::["{version-milestone}" == "true"]
Since We are using a Milestone version, we need to ensure to add the Spring Milestone Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</repository>
----
endif::[]
// tag::config[]
[[security-spring-configuration]]
== Spring Configuration
After adding the required dependencies, we can create our Spring configuration.
The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` implementation with an implementation backed by Spring Session.
Add the following Spring Configuration:
[source,java]
----
include::{docs-test-dir}docs/http/HazelcastHttpSessionConfig.java[tags=config]
----
<1> The `@EnableHazelcastHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.
The filter is what is in charge of replacing the `HttpSession` implementation to be backed by Spring Session.
In this instance Spring Session is backed by Hazelcast.
<2> In order to support retrieval of sessions by principal name index, appropriate `ValueExtractor` needs to be registered.
Spring Session provides `PrincipalNameExtractor` for this purpose.
<3> We create a `HazelcastInstance` that connects Spring Session to Hazelcast.
By default, an embedded instance of Hazelcast is started and connected to by the application.
For more information on configuring Hazelcast, refer to the http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-configuration[reference documentation].
== Servlet Container Initialization
Our <<security-spring-configuration,Spring Configuration>> created a Spring Bean named `springSessionRepositoryFilter` that implements `Filter`.
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.
In order for our `Filter` to do its magic, Spring needs to load our `SessionConfig` class.
Since our application is already loading Spring configuration using our `SecurityInitializer` class, we can simply add our `SessionConfig` class to it.
.src/main/java/sample/SecurityInitializer.java
[source,java]
----
include::{samples-dir}javaconfig/hazelcast/src/main/java/sample/SecurityInitializer.java[tags=class]
----
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
It is extremely important that Spring Session's `springSessionRepositoryFilter` is invoked before Spring Security's `springSecurityFilterChain`.
This ensures that the `HttpSession` that Spring Security uses is backed by Spring Session.
Fortunately, Spring Session provides a utility class named `AbstractHttpSessionApplicationInitializer` that makes this extremely easy.
You can find an example below:
.src/main/java/sample/Initializer.java
[source,java]
----
include::{samples-dir}javaconfig/hazelcast/src/main/java/sample/Initializer.java[tags=class]
----
NOTE: The name of our class (Initializer) does not matter. What is important is that we extend `AbstractHttpSessionApplicationInitializer`.
By extending `AbstractHttpSessionApplicationInitializer` we ensure that the Spring Bean by the name `springSessionRepositoryFilter` is registered with our Servlet Container for every request before Spring Security's `springSecurityFilterChain`.
// end::config[]
[[hazelcast-spring-security-sample]]
== Hazelcast Spring Security Sample Application
=== Running the Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
[NOTE]
====
Hazelcast will run in embedded mode with your application by default, but if you want to connect
to a stand alone instance instead, you can configure it by following the instructions in the
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-configuration[reference documentation].
====
----
$ ./gradlew :spring-session-sample-javaconfig-hazelcast:tomcatRun
----
You should now be able to access the application at http://localhost:8080/
=== Exploring the security Sample Application
Try using the application. Enter the following to log in:
* **Username** _user_
* **Password** _password_
Now click the **Login** button.
You should now see a message indicating your are logged in with the user entered previously.
The user's information is stored in Hazelcast rather than Tomcat's `HttpSession` implementation.
=== How does it work?
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in Hazelcast.
Spring Session replaces the `HttpSession` with an implementation that is backed by a `Map` in Hazelcast.
When Spring Security's `SecurityContextPersistenceFilter` saves the `SecurityContext` to the `HttpSession` it is then persisted into Hazelcast.
When a new `HttpSession` is created, Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
=== Interact with the data store
If you like, you can remove the session using http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#hazelcast-java-client[a Java client],
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#other-client-implementations[one of the other clients], or the
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#management-center[management center].
==== Using the console
For example, using the management center console after connecting to your Hazelcast node:
default> ns spring:session:sessions
spring:session:sessions> m.clear
TIP: The Hazelcast documentation has instructions for http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#executing-console-commands[the console].
Alternatively, you can also delete the explicit key. Enter the following into the console ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:
spring:session:sessions> m.remove 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
Now visit the application at http://localhost:8080/ and observe that we are no longer authenticated.
==== Using the REST API
As described in the other clients section of the documentation, there is a
http://docs.hazelcast.org/docs/{hazelcast-version}/manual/html-single/index.html#rest-client[REST API]
provided by the Hazelcast node(s).
For example, you could delete an individual key as follows (replacing `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie):
$ curl -v -X DELETE http://localhost:xxxxx/hazelcast/rest/maps/spring:session:sessions/7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
TIP: The port number of the Hazelcast node will be printed to the console on startup. Replace `xxxxx` above with the port number.
Now observe that you are no longer authenticated with this session.

View File

@@ -1,152 +0,0 @@
= Spring Session - HttpSession (Quick Start)
Rob Winch, Vedran Pavić
:toc:
This guide describes how to use Spring Session to transparently leverage a relational database to back a web application's `HttpSession` with Java Configuration.
NOTE: The completed guide can be found in the <<httpsession-jdbc-sample, httpsession-jdbc sample application>>.
== Updating Dependencies
Before you use Spring Session, you must ensure to update your dependencies.
If you are using Maven, ensure to add the following dependencies:
.pom.xml
[source,xml]
[subs="verbatim,attributes"]
----
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
<version>{spring-session-version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repositories>
<!-- ... -->
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
----
endif::[]
ifeval::["{version-milestone}" == "true"]
Since We are using a Milestone version, we need to ensure to add the Spring Milestone Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</repository>
----
endif::[]
// tag::config[]
[[httpsession-jdbc-spring-configuration]]
== Spring Java Configuration
After adding the required dependencies, we can create our Spring configuration.
The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` implementation with an implementation backed by Spring Session.
Add the following Spring Configuration:
[source,java]
----
include::{samples-dir}javaconfig/jdbc/src/main/java/sample/Config.java[tags=class]
----
<1> The `@EnableJdbcHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.
The filter is what is in charge of replacing the `HttpSession` implementation to be backed by Spring Session.
In this instance Spring Session is backed by a relational database.
<2> We create a `dataSource` that connects Spring Session to an embedded instance of H2 database.
We configure the H2 database to create database tables using the SQL script which is included in Spring Session.
<3> We create a `transactionManager` that manages transactions for previously configured `dataSource`.
For additional information on how to configure data access related concerns, please refer to the https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/data-access.html[Spring Framework Reference Documentation].
== Java Servlet Container Initialization
Our <<httpsession-spring-configuration,Spring Configuration>> created a Spring Bean named `springSessionRepositoryFilter` that implements `Filter`.
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.
In order for our `Filter` to do its magic, Spring needs to load our `Config` class.
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
Fortunately, Spring Session provides a utility class named `AbstractHttpSessionApplicationInitializer` both of these steps extremely easy.
You can find an example below:
.src/main/java/sample/Initializer.java
[source,java]
----
include::{samples-dir}javaconfig/jdbc/src/main/java/sample/Initializer.java[tags=class]
----
NOTE: The name of our class (Initializer) does not matter. What is important is that we extend `AbstractHttpSessionApplicationInitializer`.
<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`.
This ensures that the Spring Bean by the name `springSessionRepositoryFilter` is registered with our Servlet Container for every request.
<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily ensure Spring loads our `Config`.
// end::config[]
[[httpsession-jdbc-sample]]
== httpsession-jdbc Sample Application
=== Running the httpsession-jdbc Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
----
$ ./gradlew :spring-session-sample-javaconfig-jdbc:tomcatRun
----
You should now be able to access the application at http://localhost:8080/
=== Exploring the httpsession-jdbc Sample Application
Try using the application. Fill out the form with the following information:
* **Attribute Name:** _username_
* **Attribute Value:** _rob_
Now click the **Set Attribute** button. You should now see the values displayed in the table.
=== How does it work?
We interact with the standard `HttpSession` in the `SessionServlet` shown below:
.src/main/java/sample/SessionServlet.java
[source,java]
----
include::{samples-dir}javaconfig/jdbc/src/main/java/sample/SessionServlet.java[tags=class]
----
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in H2 database.
Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using H2 web console available at: http://localhost:8080/h2-console/ (use `jdbc:h2:mem:testdb` for JDBC URL)
Now visit the application at http://localhost:8080/ and observe that the attribute we added is no longer displayed.

View File

@@ -1,220 +0,0 @@
= Spring Session - REST
Rob Winch
:toc:
This guide describes how to use Spring Session to transparently leverage Redis to back a web application's `HttpSession` when using REST endpoints.
NOTE: The completed guide can be found in the <<rest-sample, rest sample application>>.
== Updating Dependencies
Before you use Spring Session, you must ensure to update your dependencies.
If you are using Maven, ensure to add the following dependencies:
.pom.xml
[source,xml]
[subs="verbatim,attributes"]
----
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
<version>{spring-session-version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>io.lettuce</groupId>
<artifactId>lettuce-core</artifactId>
<version>{lettuce-version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
ifeval::["{version-snapshot}" == "true"]
Since We are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repositories>
<!-- ... -->
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
----
endif::[]
ifeval::["{version-milestone}" == "true"]
Since We are using a Milestone version, we need to ensure to add the Spring Milestone Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</repository>
----
endif::[]
// tag::config[]
[[rest-spring-configuration]]
== Spring Configuration
After adding the required dependencies, we can create our Spring configuration.
The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` implementation with an implementation backed by Spring Session.
Add the following Spring Configuration:
[source,java]
----
include::{samples-dir}javaconfig/rest/src/main/java/sample/HttpSessionConfig.java[tags=class]
----
<1> The `@EnableRedisHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements `Filter`.
The filter is what is in charge of replacing the `HttpSession` implementation to be backed by Spring Session.
In this instance Spring Session is backed by Redis.
<2> We create a `RedisConnectionFactory` that connects Spring Session to the Redis Server.
We configure the connection to connect to localhost on the default port (6379)
For more information on configuring Spring Data Redis, refer to the https://docs.spring.io/spring-data/data-redis/docs/{spring-data-redis-version}/reference/html/[reference documentation].
<3> We customize Spring Session's HttpSession integration to use HTTP headers to convey the current session information instead of cookies.
== Servlet Container Initialization
Our <<rest-spring-configuration,Spring Configuration>> created a Spring Bean named `springSessionRepositoryFilter` that implements `Filter`.
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.
In order for our `Filter` to do its magic, Spring needs to load our `Config` class. We provide the configuration in our Spring `MvcInitializer` as shown below:
.src/main/java/sample/mvc/MvcInitializer.java
[source,java,indent=0]
----
include::{samples-dir}javaconfig/rest/src/main/java/sample/mvc/MvcInitializer.java[tags=config]
----
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
Fortunately, Spring Session provides a utility class named `AbstractHttpSessionApplicationInitializer` that makes this extremely easy. Simply extend the class with the default constructor as shown below:
.src/main/java/sample/Initializer.java
[source,java]
----
include::{samples-dir}javaconfig/rest/src/main/java/sample/Initializer.java[tags=class]
----
NOTE: The name of our class (Initializer) does not matter. What is important is that we extend `AbstractHttpSessionApplicationInitializer`.
// end::config[]
[[rest-sample]]
== rest Sample Application
=== Running the rest Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
[NOTE]
====
For the sample to work, you must https://redis.io/download[install Redis 2.8+] on localhost and run it with the default port (6379).
Alternatively, you can update the `RedisConnectionFactory` to point to a Redis server.
Another option is to use https://www.docker.com/[Docker] to run Redis on localhost. See https://hub.docker.com/_/redis/[Docker Redis repository] for detailed instructions.
====
----
$ ./gradlew :spring-session-sample-javaconfig-rest:tomcatRun
----
You should now be able to access the application at http://localhost:8080/
=== Exploring the rest Sample Application
Try using the application. Use your favorite REST client to request http://localhost:8080/
$ curl -v http://localhost:8080/
Observe that we are prompted for basic authentication. Provide the following information for the username and password:
* **Username** *user*
* **Password** *password*
$ curl -v http://localhost:8080/ -u user:password
In the output you will notice the following:
----
HTTP/1.1 200 OK
...
X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3
{"username":"user"}
----
Specifically, we notice the following things about our response:
* The HTTP Status is now a 200
* We have a header with the name of *X-Auth-Token* which contains a new session id
* The current username is displayed
We can now use the *X-Auth-Token* to make another request without providing the username and password again. For example, the following outputs the username just as before:
$ curl -v http://localhost:8080/ -H "X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3"
The only difference is that the session id is not provided in the response headers because we are reusing an existing session.
If we invalidate the session, then the X-Auth-Token is displayed in the response with an empty value. For example, the following will invalidate our session:
$ curl -v http://localhost:8080/logout -H "X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3"
You will see in the output that the X-Auth-Token provides an empty String indicating that the previous session was invalidated.
----
HTTP/1.1 204 No Content
...
X-Auth-Token:
----
=== How does it work?
Spring Security interacts with the standard `HttpSession` in `SecurityContextPersistenceFilter`.
Instead of using Tomcat's `HttpSession`, Spring Security is now persisting the values in Redis.
Spring Session creates a header named X-Auth-Token in your browser that contains the id of your session.
If you like, you can easily see that the session is created in Redis. First create a session using the following:
$ curl -v http://localhost:8080/ -u user:password
In the output you will notice the following:
----
HTTP/1.1 200 OK
...
X-Auth-Token: 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
{"username":"user"}
----
Now remove the session using redis-cli. For example, on a Linux based system you can type:
$ redis-cli keys '*' | xargs redis-cli del
TIP: The Redis documentation has instructions for https://redis.io/topics/quickstart[installing redis-cli].
Alternatively, you can also delete the explicit key. Enter the following into your terminal ensuring to replace `7e8383a4-082c-4ffe-a4bc-c40fd3363c5e` with the value of your SESSION cookie:
$ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e
We can now use the *X-Auth-Token* to make another request with the session we deleted and observe we are prompted for a authentication. For example, the following returns an HTTP 401:
$ curl -v http://localhost:8080/ -H "X-Auth-Token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3"

View File

@@ -1,162 +0,0 @@
= Spring Session - HttpSession (Quick Start)
Rob Winch, Vedran Pavić
:toc:
This guide describes how to use Spring Session to transparently leverage a relational to back a web application's `HttpSession` with XML based configuration.
NOTE: The completed guide can be found in the <<httpsession-jdbc-xml-sample, httpsession-jdbc-xml sample application>>.
== Updating Dependencies
Before you use Spring Session, you must ensure to update your dependencies.
If you are using Maven, ensure to add the following dependencies:
.pom.xml
[source,xml]
[subs="verbatim,attributes"]
----
<dependencies>
<!-- ... -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-jdbc</artifactId>
<version>{spring-session-version}</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>{spring-framework-version}</version>
</dependency>
</dependencies>
----
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to ensure to add the Spring Snapshot Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repositories>
<!-- ... -->
<repository>
<id>spring-snapshot</id>
<url>https://repo.spring.io/libs-snapshot</url>
</repository>
</repositories>
----
endif::[]
ifeval::["{version-milestone}" == "true"]
Since We are using a Milestone version, we need to ensure to add the Spring Milestone Maven Repository.
Ensure you have the following in your pom.xml:
.pom.xml
[source,xml]
----
<repository>
<id>spring-milestone</id>
<url>https://repo.spring.io/libs-milestone</url>
</repository>
----
endif::[]
// tag::config[]
[[httpsession-jdbc-xml-spring-configuration]]
== Spring XML Configuration
After adding the required dependencies, we can create our Spring configuration.
The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` implementation with an implementation backed by Spring Session.
Add the following Spring Configuration:
.src/main/webapp/WEB-INF/spring/session.xml
[source,xml,indent=0]
----
include::{samples-dir}xml/jdbc/src/main/webapp/WEB-INF/spring/session.xml[tags=beans]
----
<1> We use the combination of `<context:annotation-config/>` and `JdbcHttpSessionConfiguration` because Spring Session does not yet provide XML Namespace support (see https://github.com/spring-projects/spring-session/issues/104[gh-104]).
This creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter.
The filter is what is in charge of replacing the `HttpSession` implementation to be backed by Spring Session.
In this instance Spring Session is backed by a relational database.
<2> We create a `dataSource` that connects Spring Session to an embedded instance of H2 database.
We configure the H2 database to create database tables using the SQL script which is included in Spring Session.
<3> We create a `transactionManager` that manages transactions for previously configured `dataSource`.
For additional information on how to configure data access related concerns, please refer to the https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/data-access.html[Spring Framework Reference Documentation].
== XML Servlet Container Initialization
Our <<httpsession-xml-spring-configuration,Spring Configuration>> created a Spring Bean named `springSessionRepositoryFilter` that implements `Filter`.
The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with a custom implementation that is backed by Spring Session.
In order for our `Filter` to do its magic, we need to instruct Spring to load our `session.xml` configuration.
We do this with the following configuration:
.src/main/webapp/WEB-INF/web.xml
[source,xml,indent=0]
----
include::{samples-dir}xml/jdbc/src/main/webapp/WEB-INF/web.xml[tags=context-param]
include::{samples-dir}xml/jdbc/src/main/webapp/WEB-INF/web.xml[tags=listeners]
----
The https://docs.spring.io/spring/docs/{spring-framework-version}/spring-framework-reference/core.html#context-create[ContextLoaderListener] reads the contextConfigLocation and picks up our session.xml configuration.
Last we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
The following snippet performs this last step for us:
.src/main/webapp/WEB-INF/web.xml
[source,xml,indent=0]
----
include::{samples-dir}xml/jdbc/src/main/webapp/WEB-INF/web.xml[tags=springSessionRepositoryFilter]
----
The https://docs.spring.io/spring-framework/docs/{spring-framework-version}/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html[DelegatingFilterProxy] will look up a Bean by the name of `springSessionRepositoryFilter` and cast it to a `Filter`.
For every request that `DelegatingFilterProxy` is invoked, the `springSessionRepositoryFilter` will be invoked.
// end::config[]
[[httpsession-jdbc-xml-sample]]
== httpsession-jdbc-xml Sample Application
=== Running the httpsession-jdbc-xml Sample Application
You can run the sample by obtaining the {download-url}[source code] and invoking the following command:
----
$ ./gradlew :spring-session-sample-xml-jdbc:tomcatRun
----
You should now be able to access the application at http://localhost:8080/
=== Exploring the httpsession-jdbc-xml Sample Application
Try using the application. Fill out the form with the following information:
* **Attribute Name:** _username_
* **Attribute Value:** _rob_
Now click the **Set Attribute** button. You should now see the values displayed in the table.
=== How does it work?
We interact with the standard `HttpSession` in the `SessionServlet` shown below:
.src/main/java/sample/SessionServlet.java
[source,java]
----
include::{samples-dir}xml/jdbc/src/main/java/sample/SessionServlet.java[tags=class]
----
Instead of using Tomcat's `HttpSession`, we are actually persisting the values in H2 database.
Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developers.google.com/web/tools/chrome-devtools/manage-data/cookies[Chrome] or https://developer.mozilla.org/en-US/docs/Tools/Storage_Inspector[Firefox]).
If you like, you can easily remove the session using H2 web console available at: http://localhost:8080/h2-console/ (use `jdbc:h2:mem:testdb` for JDBC URL)
Now visit the application at http://localhost:8080/ and observe that the attribute we added is no longer displayed.

File diff suppressed because it is too large Load Diff

View File

@@ -1,12 +1,39 @@
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<!DOCTYPE module PUBLIC "-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
"https://checkstyle.org/dtds/configuration_1_3.dtd">
<module name="Checker">
<!-- Supressions -->
<module name="SuppressionFilter">
<property name="file" value="${configDir}/suppressions.xml"/>
<property name="file" value="${config_loc}/suppressions.xml"/>
</module>
<!-- Root Checks -->
<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"
value="^sun.*, ^org\.apache\.commons\.(?!compress|dbcp2|lang|lang3|logging|pool2).*, ^com\.google\.common.*, ^org\.flywaydb\.core\.internal.*, ^org\.testcontainers\.shaded.*"/>
<property name="illegalClasses"
value="^reactor\.core\.support\.Assert, ^org\.junit\.rules\.ExpectedException, ^org\.slf4j\.LoggerFactory"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="maximum" value="0"/>
<property name="format" value="org\.junit\.Assert\.assert"/>
<property name="message" value="Please use AssertJ imports."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="maximum" value="0"/>
<property name="format"
value="assertThatExceptionOfType\((NullPointerException|IllegalArgumentException|IOException|IllegalStateException)\.class\)"/>
<property name="message" value="Please use specialized AssertJ assertThat*Exception method."/>
<property name="ignoreComments" value="true"/>
</module>
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
<property name="maximum" value="0"/>
<property name="format" value="org\.mockito\.Mockito\.(when|doThrow|doAnswer)"/>
<property name="message" value="Please use BDDMockito imports."/>
<property name="ignoreComments" value="true"/>
</module>
</module>
</module>

View File

@@ -1,16 +0,0 @@
^\Q/*\E$
^\Q * Copyright 2014-\E20\d\d\Q the original author or authors.\E$
^\Q *\E$
^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$
^\Q * you may not use this file except in compliance with the License.\E$
^\Q * You may obtain a copy of the License at\E$
^\Q *\E$
^\Q * http://www.apache.org/licenses/LICENSE-2.0\E$
^\Q *\E$
^\Q * Unless required by applicable law or agreed to in writing, software\E$
^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$
^\Q * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\E$
^\Q * See the License for the specific language governing permissions and\E$
^\Q * limitations under the License.\E$
^\Q */\E$
^.*$

View File

@@ -1,16 +1,11 @@
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC "-//Puppy Crawl//DTD Suppressions 1.1//EN"
"http://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<!DOCTYPE suppressions PUBLIC "-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
<suppressions>
<!-- global -->
<suppress files="[\\/]src[\\/]integration-test[\\/]java[\\/]" checks="Javadoc*"/>
<!-- docs -->
<suppress files="[\\/]docs[\\/]" checks="Javadoc*"/>
<suppress files="[\\/]docs[\\/]" checks="AvoidStaticImport"/>
<suppress files="[\\/]docs[\\/]" checks="InnerTypeLast"/>
<!-- samples -->
<suppress files="[\\/]samples[\\/]" checks="Javadoc*"/>
<suppress files="[\\/]samples[\\/].+Application\.java" checks="HideUtilityClassConstructor"/>
<suppress files="[\\/]spring-session-docs[\\/]" checks="Javadoc*"/>
<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="CookieSerializer\.java" checks="SpringMethodVisibility"/>
</suppressions>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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

View 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>

View File

@@ -1,2 +1,3 @@
springBootVersion=2.1.0.M1
version=2.1.0.M2
org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
org.gradle.parallel=true
version=2.5.0

View File

@@ -1,32 +1,36 @@
dependencyManagement {
imports {
mavenBom 'com.fasterxml.jackson:jackson-bom:2.9.6'
mavenBom 'io.projectreactor:reactor-bom:Californium-M2'
mavenBom 'org.springframework:spring-framework-bom:5.1.0.RC2'
mavenBom 'org.springframework.data:spring-data-releasetrain:Lovelace-RC2'
mavenBom 'org.springframework.security:spring-security-bom:5.1.0.RC1'
mavenBom 'org.testcontainers:testcontainers-bom:1.8.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.10.4') {
dependencySet(group: 'com.hazelcast', version: '3.12.12') {
entry 'hazelcast'
entry 'hazelcast-client'
}
dependency 'com.h2database:h2:1.4.197'
dependency 'com.microsoft.sqlserver:mssql-jdbc:7.0.0.jre8'
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.0.M1'
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 'junit:junit:4.12'
dependency 'mysql:mysql-connector-java:8.0.12'
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.11.0'
dependency 'org.hsqldb:hsqldb:2.4.1'
dependency 'org.mariadb.jdbc:mariadb-java-client:2.2.6'
dependency 'org.mockito:mockito-core:2.21.0'
dependency 'org.postgresql:postgresql:42.2.4'
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'
}
}

Binary file not shown.

View File

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

53
gradlew vendored
View File

@@ -1,5 +1,21 @@
#!/usr/bin/env sh
#
# Copyright 2015 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.
#
##############################################################################
##
## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -66,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
@@ -109,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
@@ -138,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
@@ -159,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" "$@"

43
gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@@ -13,15 +29,18 @@ 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=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
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.
@@ -35,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%
@@ -45,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

View File

@@ -1,21 +0,0 @@
ext['spring.version'] = '5.1.0.RC2'
dependencyManagement {
dependencies {
dependency 'ch.qos.logback:logback-classic:1.2.3'
dependency 'com.maxmind.geoip2:geoip2:2.3.1'
dependency 'javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:1.2.1'
dependency 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.2-b02'
dependency 'org.apache.taglibs:taglibs-standard-jstlel:1.2.5'
dependency 'org.seleniumhq.selenium:htmlunit-driver:2.32.0'
dependency 'org.slf4j:jcl-over-slf4j:1.7.25'
dependency 'org.slf4j:log4j-over-slf4j:1.7.25'
dependency 'org.webjars:bootstrap:2.3.2'
dependency 'org.webjars:html5shiv:3.7.3'
dependency 'org.webjars:jquery:1.12.4'
dependency 'org.webjars:knockout:2.3.0'
dependency 'org.webjars:sockjs-client:0.3.4'
dependency 'org.webjars:stomp-websocket:2.3.0'
dependency 'org.webjars:webjars-taglib:0.3'
}
}

View File

@@ -1,67 +0,0 @@
/*
* Copyright 2014-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import com.hazelcast.nio.ObjectDataInput;
import com.hazelcast.nio.ObjectDataOutput;
import com.hazelcast.nio.serialization.StreamSerializer;
/**
* A {@link StreamSerializer} that uses Java serialization to persist the session. This is
* certainly not the most efficient way to persist sessions, but the example is intended
* to demonstrate using minimal dependencies. For better serialization methods try using
* <a href="https://github.com/EsotericSoftware/kryo">Kryo</a>.
*
* @author Rob Winch
*
*/
public class ObjectStreamSerializer implements StreamSerializer<Object> {
@Override
public int getTypeId() {
return 2;
}
@Override
public void write(ObjectDataOutput objectDataOutput, Object object)
throws IOException {
ObjectOutputStream out = new ObjectOutputStream((OutputStream) objectDataOutput);
out.writeObject(object);
out.flush();
}
@Override
public Object read(ObjectDataInput objectDataInput) throws IOException {
ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput);
try {
return in.readObject();
}
catch (ClassNotFoundException ex) {
throw new IOException(ex);
}
}
@Override
public void destroy() {
}
}

View File

@@ -1,41 +0,0 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
// tag::class[]
@WebServlet("/session")
public class SessionServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String attributeName = req.getParameter("attributeName");
String attributeValue = req.getParameter("attributeValue");
req.getSession().setAttribute(attributeName, attributeValue);
resp.sendRedirect(req.getContextPath() + "/");
}
private static final long serialVersionUID = 2878267318695777395L;
}
// tag::end[]

View File

@@ -1 +0,0 @@
grailsVersion=3.1.4

View File

@@ -1,28 +0,0 @@
// Added by the Spring Security Core plugin:
grails.plugin.springsecurity.userLookup.userDomainClassName = 'grails3.redis.session.User'
grails.plugin.springsecurity.userLookup.authorityJoinClassName = 'grails3.redis.session.UserRole'
grails.plugin.springsecurity.authority.className = 'grails3.redis.session.Role'
grails.plugin.springsecurity.controllerAnnotations.staticRules = [
[pattern: '/', access: ['permitAll']],
[pattern: '/error', access: ['permitAll']],
[pattern: '/index', access: ['permitAll']],
[pattern: '/index.gsp', access: ['permitAll']],
[pattern: '/shutdown', access: ['permitAll']],
[pattern: '/assets/**', access: ['permitAll']],
[pattern: '/**/js/**', access: ['permitAll']],
[pattern: '/**/css/**', access: ['permitAll']],
[pattern: '/**/images/**', access: ['permitAll']],
[pattern: '/**/favicon.ico', access: ['permitAll']]
]
grails.plugin.springsecurity.filterChain.chainMap = [
[pattern: '/assets/**', filters: 'none'],
[pattern: '/**/js/**', filters: 'none'],
[pattern: '/**/css/**', filters: 'none'],
[pattern: '/**/images/**', filters: 'none'],
[pattern: '/**/favicon.ico', filters: 'none'],
[pattern: '/**', filters: 'JOINED_FILTERS']
]

View File

@@ -1,122 +0,0 @@
---
hibernate:
cache:
queries: false
use_second_level_cache: true
use_query_cache: false
region.factory_class: 'org.hibernate.cache.ehcache.EhCacheRegionFactory'
dataSource:
pooled: true
jmxExport: true
driverClassName: org.h2.Driver
username: sa
password:
environments:
development:
dataSource:
dbCreate: create-drop
url: jdbc:h2:mem:devDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
test:
dataSource:
dbCreate: update
url: jdbc:h2:mem:testDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
production:
dataSource:
dbCreate: update
url: jdbc:h2:./prodDb;MVCC=TRUE;LOCK_TIMEOUT=10000;DB_CLOSE_ON_EXIT=FALSE
properties:
jmxEnabled: true
initialSize: 5
maxActive: 50
minIdle: 5
maxIdle: 25
maxWait: 10000
maxAge: 600000
timeBetweenEvictionRunsMillis: 5000
minEvictableIdleTimeMillis: 60000
validationQuery: SELECT 1
validationQueryTimeout: 3
validationInterval: 15000
testOnBorrow: true
testWhileIdle: true
testOnReturn: false
jdbcInterceptors: ConnectionState
defaultTransactionIsolation: 2 # TRANSACTION_READ_COMMITTED
---
---
grails:
profile: web
codegen:
defaultPackage: grails3.redis.session
spring:
transactionManagement:
proxies: false
info:
app:
name: '@info.app.name@'
version: '@info.app.version@'
grailsVersion: '@info.app.grailsVersion@'
spring:
groovy:
template:
check-template-location: false
---
grails:
mime:
disable:
accept:
header:
userAgents:
- Gecko
- WebKit
- Presto
- Trident
types:
all: '*/*'
atom: application/atom+xml
css: text/css
csv: text/csv
form: application/x-www-form-urlencoded
html:
- text/html
- application/xhtml+xml
js: text/javascript
json:
- application/json
- text/json
multipartForm: multipart/form-data
pdf: application/pdf
rss: application/rss+xml
text: text/plain
hal:
- application/hal+json
- application/hal+xml
xml:
- text/xml
- application/xml
urlmapping:
cache:
maxsize: 1000
controllers:
defaultScope: singleton
converters:
encoding: UTF-8
views:
default:
codec: html
gsp:
encoding: UTF-8
htmlcodec: xml
codecs:
expression: html
scriptlets: html
taglib: none
staticparts: none
endpoints:
jmx:
unique-names: true

View File

@@ -1,23 +0,0 @@
import grails.util.BuildSettings
import grails.util.Environment
// See http://logback.qos.ch/manual/groovy.html for details on configuration
appender('STDOUT', ConsoleAppender) {
encoder(PatternLayoutEncoder) {
pattern = "%level %logger - %msg%n"
}
}
root(ERROR, ['STDOUT'])
def targetDir = BuildSettings.TARGET_DIR
if (Environment.isDevelopmentMode() && targetDir) {
appender("FULL_STACKTRACE", FileAppender) {
file = "${targetDir}/stacktrace.log"
append = true
encoder(PatternLayoutEncoder) {
pattern = "%level %logger - %msg%n"
}
}
logger("StackTrace", ERROR, ['FULL_STACKTRACE'], false)
}

View File

@@ -1,3 +0,0 @@
// Place your Spring DSL code here
beans = {
}

View File

@@ -1,8 +0,0 @@
package grails3.redis.session
import grails.plugin.springsecurity.annotation.Secured
class TestController {
@Secured('ROLE_ADMIN')
def index() { } // Renders `test/index.gsp`
}

View File

@@ -1,16 +0,0 @@
package grails3.redis.session
class UrlMappings {
static mappings = {
"/$controller/$action?/$id?(.$format)?"{
constraints {
// apply constraints here
}
}
"/"(view:"/index")
"500"(view:'/error')
"404"(view:'/notFound')
}
}

View File

@@ -1,26 +0,0 @@
package grails3.redis.session
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
@EqualsAndHashCode(includes='authority')
@ToString(includes='authority', includeNames=true, includePackage=false)
class Role implements Serializable {
private static final long serialVersionUID = 1
String authority
Role(String authority) {
this()
this.authority = authority
}
static constraints = {
authority blank: false, unique: true
}
static mapping = {
cache true
}
}

View File

@@ -1,55 +0,0 @@
package grails3.redis.session
import groovy.transform.EqualsAndHashCode
import groovy.transform.ToString
@EqualsAndHashCode(includes='username')
@ToString(includes='username', includeNames=true, includePackage=false)
class User implements Serializable {
private static final long serialVersionUID = 1
transient springSecurityService
String username
String password
boolean enabled = true
boolean accountExpired
boolean accountLocked
boolean passwordExpired
User(String username, String password) {
this()
this.username = username
this.password = password
}
Set<Role> getAuthorities() {
UserRole.findAllByUser(this)*.role
}
def beforeInsert() {
encodePassword()
}
def beforeUpdate() {
if (isDirty('password')) {
encodePassword()
}
}
protected void encodePassword() {
password = springSecurityService?.passwordEncoder ? springSecurityService.encodePassword(password) : password
}
static transients = ['springSecurityService']
static constraints = {
password blank: false, password: true
username blank: false, unique: true
}
static mapping = {
password column: '`password`'
}
}

View File

@@ -1,103 +0,0 @@
package grails3.redis.session
import grails.gorm.DetachedCriteria
import groovy.transform.ToString
import org.apache.commons.lang.builder.HashCodeBuilder
@ToString(cache=true, includeNames=true, includePackage=false)
class UserRole implements Serializable {
private static final long serialVersionUID = 1
User user
Role role
UserRole(User u, Role r) {
this()
user = u
role = r
}
@Override
boolean equals(other) {
if (!(other instanceof UserRole)) {
return false
}
other.user?.id == user?.id && other.role?.id == role?.id
}
@Override
int hashCode() {
def builder = new HashCodeBuilder()
if (user) builder.append(user.id)
if (role) builder.append(role.id)
builder.toHashCode()
}
static UserRole get(long userId, long roleId) {
criteriaFor(userId, roleId).get()
}
static boolean exists(long userId, long roleId) {
criteriaFor(userId, roleId).count()
}
private static DetachedCriteria criteriaFor(long userId, long roleId) {
UserRole.where {
user == User.load(userId) &&
role == Role.load(roleId)
}
}
static UserRole create(User user, Role role, boolean flush = false) {
def instance = new UserRole(user: user, role: role)
instance.save(flush: flush, insert: true)
instance
}
static boolean remove(User u, Role r, boolean flush = false) {
if (u == null || r == null) return false
int rowCount = UserRole.where { user == u && role == r }.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
rowCount
}
static void removeAll(User u, boolean flush = false) {
if (u == null) return
UserRole.where { user == u }.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
}
static void removeAll(Role r, boolean flush = false) {
if (r == null) return
UserRole.where { role == r }.deleteAll()
if (flush) { UserRole.withSession { it.flush() } }
}
static constraints = {
role validator: { Role r, UserRole ur ->
if (ur.user == null || ur.user.id == null) return
boolean existing = false
UserRole.withNewSession {
existing = UserRole.exists(ur.user.id, r.id)
}
if (existing) {
return 'userRole.exists'
}
}
}
static mapping = {
id composite: ['user', 'role']
version false
}
}

View File

@@ -1,56 +0,0 @@
default.doesnt.match.message=Property [{0}] of class [{1}] with value [{2}] does not match the required pattern [{3}]
default.invalid.url.message=Property [{0}] of class [{1}] with value [{2}] is not a valid URL
default.invalid.creditCard.message=Property [{0}] of class [{1}] with value [{2}] is not a valid credit card number
default.invalid.email.message=Property [{0}] of class [{1}] with value [{2}] is not a valid e-mail address
default.invalid.range.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid range from [{3}] to [{4}]
default.invalid.size.message=Property [{0}] of class [{1}] with value [{2}] does not fall within the valid size range from [{3}] to [{4}]
default.invalid.max.message=Property [{0}] of class [{1}] with value [{2}] exceeds maximum value [{3}]
default.invalid.min.message=Property [{0}] of class [{1}] with value [{2}] is less than minimum value [{3}]
default.invalid.max.size.message=Property [{0}] of class [{1}] with value [{2}] exceeds the maximum size of [{3}]
default.invalid.min.size.message=Property [{0}] of class [{1}] with value [{2}] is less than the minimum size of [{3}]
default.invalid.validator.message=Property [{0}] of class [{1}] with value [{2}] does not pass custom validation
default.not.inlist.message=Property [{0}] of class [{1}] with value [{2}] is not contained within the list [{3}]
default.blank.message=Property [{0}] of class [{1}] cannot be blank
default.not.equal.message=Property [{0}] of class [{1}] with value [{2}] cannot equal [{3}]
default.null.message=Property [{0}] of class [{1}] cannot be null
default.not.unique.message=Property [{0}] of class [{1}] with value [{2}] must be unique
default.paginate.prev=Previous
default.paginate.next=Next
default.boolean.true=True
default.boolean.false=False
default.date.format=yyyy-MM-dd HH:mm:ss z
default.number.format=0
default.created.message={0} {1} created
default.updated.message={0} {1} updated
default.deleted.message={0} {1} deleted
default.not.deleted.message={0} {1} could not be deleted
default.not.found.message={0} not found with id {1}
default.optimistic.locking.failure=Another user has updated this {0} while you were editing
default.home.label=Home
default.list.label={0} List
default.add.label=Add {0}
default.new.label=New {0}
default.create.label=Create {0}
default.show.label=Show {0}
default.edit.label=Edit {0}
default.button.create.label=Create
default.button.edit.label=Edit
default.button.update.label=Update
default.button.delete.label=Delete
default.button.delete.confirm.message=Are you sure?
# Data binding errors. Use "typeMismatch.$className.$propertyName to customize (eg typeMismatch.Book.author)
typeMismatch.java.net.URL=Property {0} must be a valid URL
typeMismatch.java.net.URI=Property {0} must be a valid URI
typeMismatch.java.util.Date=Property {0} must be a valid Date
typeMismatch.java.lang.Double=Property {0} must be a valid number
typeMismatch.java.lang.Integer=Property {0} must be a valid number
typeMismatch.java.lang.Long=Property {0} must be a valid number
typeMismatch.java.lang.Short=Property {0} must be a valid number
typeMismatch.java.math.BigDecimal=Property {0} must be a valid number
typeMismatch.java.math.BigInteger=Property {0} must be a valid number
typeMismatch=Property {0} is type-mismatched

View File

@@ -1,24 +0,0 @@
import grails3.redis.session.*
class BootStrap {
def init = { servletContext ->
def adminRole = new Role('ROLE_ADMIN').save()
def userRole = new Role('ROLE_USER').save()
def testUser = new User('user', 'password').save()
UserRole.create testUser, adminRole
UserRole.withSession {
it.flush()
it.clear()
}
assert User.count() == 1
assert Role.count() == 2
assert UserRole.count() == 1
}
def destroy = {
}
}

View File

@@ -1,10 +0,0 @@
package grails3.redis.session
import grails.boot.GrailsApp
import grails.boot.config.GrailsAutoConfiguration
class Application extends GrailsAutoConfiguration {
static void main(String[] args) {
GrailsApp.run(Application, args)
}
}

View File

@@ -1,31 +0,0 @@
<!doctype html>
<html>
<head>
<title><g:if env="development">Grails Runtime Exception</g:if><g:else>Error</g:else></title>
<meta name="layout" content="main">
<g:if env="development"><asset:stylesheet src="errors.css"/></g:if>
</head>
<body>
<g:if env="development">
<g:if test="${Throwable.isInstance(exception)}">
<g:renderException exception="${exception}" />
</g:if>
<g:elseif test="${request.getAttribute('javax.servlet.error.exception')}">
<g:renderException exception="${request.getAttribute('javax.servlet.error.exception')}" />
</g:elseif>
<g:else>
<ul class="errors">
<li>An error has occurred</li>
<li>Exception: ${exception}</li>
<li>Message: ${message}</li>
<li>Path: ${path}</li>
</ul>
</g:else>
</g:if>
<g:else>
<ul class="errors">
<li>An error has occurred</li>
</ul>
</g:else>
</body>
</html>

View File

@@ -1,8 +0,0 @@
<html>
<head>
<title>Index</title>
</head>
<body>
Left blank, goto <a href="/test">test</a>
</body>
</html>

View File

@@ -1,14 +0,0 @@
<!doctype html>
<html>
<head>
<title>Page Not Found</title>
<meta name="layout" content="main">
<g:if env="development"><asset:stylesheet src="errors.css"/></g:if>
</head>
<body>
<ul class="errors">
<li>Error: Page Not Found (404)</li>
<li>Path: ${request.forwardURI}</li>
</ul>
</body>
</html>

View File

@@ -1,16 +0,0 @@
<html>
<head>
<title>Home Page</title>
</head>
<body>
<div id="un">
<sec:loggedInUserInfo field='username'/>
</div>
<div id="session">
${session.id}
</div>
<form action="/logout" method="post">
<input type="submit" value="Log Out"/>
</form>
</body>
</html>

View File

@@ -1,71 +0,0 @@
buildscript {
ext {
grailsVersion = project.grailsVersion
}
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencies {
classpath "org.grails:grails-gradle-plugin:$grailsVersion"
classpath "com.bertramlabs.plugins:asset-pipeline-gradle:2.5.0"
classpath "org.grails.plugins:hibernate4:5.0.2"
}
}
apply plugin: "eclipse"
apply plugin: "idea"
apply plugin: "war"
apply plugin: "org.grails.grails-web"
apply plugin: "org.grails.grails-gsp"
apply plugin: "asset-pipeline"
apply from: SAMPLE_GRADLE
ext {
grailsVersion = project.grailsVersion
}
repositories {
mavenLocal()
maven { url "https://repo.grails.org/grails/core" }
}
dependencyManagement {
imports {
mavenBom "org.grails:grails-bom:$grailsVersion"
}
applyMavenExclusions false
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-logging"
compile "org.springframework.boot:spring-boot-autoconfigure"
compile "org.grails:grails-core"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-tomcat"
compile "org.grails:grails-dependencies"
compile "org.grails:grails-web-boot"
compile "org.grails.plugins:cache"
compile "org.grails.plugins:scaffolding"
compile "org.grails.plugins:hibernate4"
compile "org.hibernate:hibernate-ehcache"
console "org.grails:grails-console"
profile "org.grails.profiles:web:3.1.4"
runtime "org.grails.plugins:asset-pipeline"
runtime "com.h2database:h2"
testCompile "org.grails:grails-plugin-testing"
testCompile "org.grails.plugins:geb"
testCompile "org.assertj:assertj-core"
testCompile "org.seleniumhq.selenium:selenium-htmlunit-driver"
testCompile "net.sourceforge.htmlunit:htmlunit"
compile "org.springframework.boot:spring-boot-starter-redis"
compile 'org.springframework.session:spring-session:1.1.1.RELEASE'
compile 'org.grails.plugins:spring-security-core:3.0.4'
}
assets {
minifyJs = true
minifyCss = true
}

View File

@@ -1,98 +0,0 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample
import grails.test.mixin.integration.Integration
import grails.transaction.Transactional
import org.springframework.boot.test.IntegrationTest
import spock.lang.*
import geb.spock.*
import sample.pages.HomePage
import sample.pages.LoginPage
import sample.pages.IndexPage
import spock.lang.Stepwise
import pages.*
/**
* Functional tests for grails 3 and spring-session
*
* @author Eric Helgeson
*/
@Stepwise
@IntegrationTest("server.port:0")
@Integration(applicationClass=grails3.redis.session.Application)
class HomeSpec extends GebSpec {
def setup() {
}
def cleanup() {
}
void 'Anonymous page not redirected to login'() {
when: 'The index page is visited'
go '/'
then: 'Not redirected'
at IndexPage
}
void 'Unauthenticated user sent to log in page'() {
when: 'The test page is visited'
go '/test/index'
if(title != 'Login') {
println driver.pageSource
}
then: 'The password form is correct'
title == 'Login'
$('#password')
$('#username')
}
void 'Log in views home page'() {
when: 'log in successfully'
to LoginPage
login()
then: 'sent to original page'
at HomePage
and: 'the username is displayed'
username == 'user'
and: 'session id is not blank'
session != ''
and: 'Spring Session Management is being used'
driver.manage().cookies.find { it.name == 'SESSION' }
and: 'Standard Session is NOT being used'
!driver.manage().cookies.find { it.name == 'JSESSIONID' }
}
def 'Log out success'() {
when:
logout()
then:
at IndexPage
}
}

View File

@@ -1,34 +0,0 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.pages
import geb.*
/**
* The home page
*
* @author Rob Winch
*/
class HomePage extends Page {
static url = '/test'
static at = { assert driver.title == 'Home Page'; true}
static content = {
username { $('#un').text() }
session { $('#session').text() }
logout(to:LoginPage) { $('input[type=submit]').click() }
}
}

View File

@@ -1,30 +0,0 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.pages
import geb.*
/**
* The Index page
*
* @author Eric Helgeson
*/
class IndexPage extends Page {
static url = '/'
static at = { assert driver.title == 'Index'; true}
static content = { }
}

View File

@@ -1,38 +0,0 @@
/*
* Copyright 2014-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.pages
import geb.*
/**
* The Login Page
*
* @author Rob Winch
*/
class LoginPage extends Page {
static url = '/login'
static at = { assert driver.title == 'Login'; true}
static content = {
form { $('form') }
submit { $('input[type=submit]') }
login(required:false) { user='user', pass='password' ->
form.username = user
form.password = pass
submit.click()
}
}
}

View File

@@ -1,135 +0,0 @@
/*
* Copyright 2014-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample.pages;
import java.util.ArrayList;
import java.util.List;
import org.openqa.selenium.SearchContext;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Eddú Meléndez
* @author Rob Winch
*/
public class HomePage {
private WebDriver driver;
@FindBy(css = "form")
WebElement form;
@FindBy(css = "table tbody tr")
List<WebElement> trs;
List<Attribute> attributes;
public HomePage(WebDriver driver) {
this.driver = driver;
this.attributes = new ArrayList<>();
}
private static void get(WebDriver driver, String get) {
String baseUrl = "http://localhost:" + System.getProperty("app.port", "8080");
driver.get(baseUrl + get);
}
public static HomePage go(WebDriver driver) {
get(driver, "/");
return PageFactory.initElements(driver, HomePage.class);
}
public void assertAt() {
assertThat(this.driver.getTitle()).isEqualTo("Session Attributes");
}
public List<Attribute> attributes() {
List<Attribute> rows = new ArrayList<>();
for (WebElement tr : this.trs) {
rows.add(new Attribute(tr));
}
this.attributes.addAll(rows);
return this.attributes;
}
public Form form() {
return new Form(this.form);
}
public class Form {
@FindBy(name = "attributeName")
WebElement attributeName;
@FindBy(name = "attributeValue")
WebElement attributeValue;
@FindBy(css = "input[type=\"submit\"]")
WebElement submit;
public Form(SearchContext context) {
PageFactory.initElements(new DefaultElementLocatorFactory(context), this);
}
public Form attributeName(String text) {
this.attributeName.sendKeys(text);
return this;
}
public Form attributeValue(String text) {
this.attributeValue.sendKeys(text);
return this;
}
public <T> T submit(Class<T> page) {
this.submit.click();
return PageFactory.initElements(HomePage.this.driver, page);
}
}
public static class Attribute {
@FindBy(xpath = ".//td[1]")
WebElement attributeName;
@FindBy(xpath = ".//td[2]")
WebElement attributeValue;
public Attribute(SearchContext context) {
PageFactory.initElements(new DefaultElementLocatorFactory(context), this);
}
/**
* @return the attributeName
*/
public String getAttributeName() {
return this.attributeName.getText();
}
/**
* @return the attributeValue
*/
public String getAttributeValue() {
return this.attributeValue.getText();
}
}
}

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2014-2018 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package sample;
import org.testcontainers.containers.GenericContainer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.context.annotation.Profile;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
@Configuration
@Profile("embedded-redis")
public class EmbeddedRedisConfig {
private static final String DOCKER_IMAGE = "redis:4.0.11";
@Bean
public GenericContainer redisContainer() {
GenericContainer redisContainer = new GenericContainer(DOCKER_IMAGE)
.withExposedPorts(6379);
redisContainer.start();
return redisContainer;
}
@Bean
@Primary
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisContainer().getContainerIpAddress(),
redisContainer().getFirstMappedPort());
}
}

View File

@@ -1,14 +0,0 @@
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- <logger name="org.springframework.security" level="DEBUG"/> -->
<root level="INFO">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -1,25 +1,30 @@
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'
FileTree buildFiles = fileTree(rootDir) {
include '**/*.gradle'
exclude '**/gradle', 'settings.gradle', 'buildSrc', '/build.gradle', '.*'
exclude '**/grails3'
include 'spring-session-core'
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
project(":$dir.name").projectDir = dir
}
String rootDirPath = rootDir.absolutePath + File.separator
buildFiles.each { File buildFile ->
if (buildFile.name == 'build.gradle') {
String buildFilePath = buildFile.parentFile.absolutePath
String projectPath = buildFilePath.replace(rootDirPath, '').replaceAll(File.separator, ':')
include projectPath
}
else {
String projectName = buildFile.name.replace('.gradle', '')
String projectPath = ':' + projectName
include projectPath
def project = findProject("${projectPath}")
project.name = projectName
project.projectDir = buildFile.parentFile
project.buildFileName = buildFile.name
}
rootProject.children.each { project ->
project.buildFileName = "${project.name}.gradle"
}

View File

@@ -18,10 +18,13 @@ dependencies {
optional "org.springframework.security:spring-security-web"
testCompile "io.projectreactor:reactor-test"
testCompile "junit:junit"
testCompile "org.mockito:mockito-core"
testCompile "edu.umd.cs.mtc:multithreadedtc"
testCompile "org.springframework:spring-test"
testCompile "org.assertj:assertj-core"
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"
}

View File

@@ -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;
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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,

View File

@@ -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
}

View File

@@ -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);
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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;
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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;
}

View File

@@ -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;
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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);
});

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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.

View File

@@ -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
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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;
}
@@ -81,14 +79,13 @@ public interface Session {
@SuppressWarnings("unchecked")
default <T> T getAttributeOrDefault(String name, T defaultValue) {
T result = getAttribute(name);
return (result != null ? result : defaultValue);
return (result != null) ? result : defaultValue;
}
/**
* 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();

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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);
}

View File

@@ -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();
}
}

View File

@@ -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);
}

View File

@@ -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);
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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 {
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -58,7 +58,7 @@ import org.springframework.util.ObjectUtils;
*
* {@literal @Bean}
* public MapSessionRepository sessionRepository() {
* return new MapSessionRepository();
* return new MapSessionRepository(new ConcurrentHashMap<>());
* }
*
* }
@@ -88,10 +88,9 @@ import org.springframework.util.ObjectUtils;
* @author Rob Winch
* @author Vedran Pavic
* @since 1.1
*
* @see EnableSpringHttpSession
*/
@Configuration
@Configuration(proxyBeanMethods = false)
public class SpringHttpSessionConfiguration implements ApplicationContextAware {
private final Log logger = LogFactory.getLog(getClass());
@@ -110,8 +109,8 @@ public class SpringHttpSessionConfiguration implements ApplicationContextAware {
@PostConstruct
public void init() {
CookieSerializer cookieSerializer = (this.cookieSerializer != null
? this.cookieSerializer : createDefaultCookieSerializer());
CookieSerializer cookieSerializer = (this.cookieSerializer != null) ? this.cookieSerializer
: createDefaultCookieSerializer();
this.defaultHttpSessionIdResolver.setCookieSerializer(cookieSerializer);
}
@@ -123,22 +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.setServletContext(this.servletContext);
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;
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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 {
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -27,15 +27,15 @@ 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
@Configuration(proxyBeanMethods = false)
public class SpringWebSessionConfiguration {
/**
@@ -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;
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,

View File

@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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");
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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();
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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);
}
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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;
}
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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) {

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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() {

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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;
}

View File

@@ -1,11 +1,11 @@
/*
* 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.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -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);
}

Some files were not shown because too many files have changed in this diff Show More