diff --git a/build.gradle b/build.gradle index 71dfd882..614b3efb 100644 --- a/build.gradle +++ b/build.gradle @@ -1,14 +1,14 @@ buildscript { - repositories { - maven { url "https://repo.spring.io/plugins-release" } - } - dependencies { - classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.3") - classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7") - classpath("org.springframework.build.gradle:spring-io-plugin:0.0.3.RELEASE") - classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1') - classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.2' - } + repositories { + maven { url "https://repo.spring.io/plugins-release" } + } + dependencies { + classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.3") + classpath("org.springframework.build.gradle:propdeps-plugin:0.0.7") + classpath("org.springframework.build.gradle:spring-io-plugin:0.0.3.RELEASE") + classpath('me.champeau.gradle:gradle-javadoc-hotfix-plugin:0.1') + classpath 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.2' + } } group = 'org.springframework.session' @@ -27,37 +27,37 @@ apply plugin: 'base' sonarRunner { - sonarProperties { - property "sonar.java.coveragePlugin", "jacoco" - property "sonar.projectName", "Spring Session" - property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec" - property "sonar.links.homepage", 'https://github.com/spring-projects/spring-session' - property "sonar.links.ci", 'https://build.spring.io/browse/SESSION' - property "sonar.links.issue", 'https://github.com/spring-projects/spring-session/issues' - property "sonar.links.scm", 'https://github.com/spring-projects/spring-session' - property "sonar.links.scm_dev", 'https://github.com/spring-projects/spring-session.git' - property "sonar.java.coveragePlugin", "jacoco" - } + sonarProperties { + property "sonar.java.coveragePlugin", "jacoco" + property "sonar.projectName", "Spring Session" + property "sonar.jacoco.reportPath", "${buildDir.name}/jacoco.exec" + property "sonar.links.homepage", 'https://github.com/spring-projects/spring-session' + property "sonar.links.ci", 'https://build.spring.io/browse/SESSION' + property "sonar.links.issue", 'https://github.com/spring-projects/spring-session/issues' + property "sonar.links.scm", 'https://github.com/spring-projects/spring-session' + property "sonar.links.scm_dev", 'https://github.com/spring-projects/spring-session.git' + property "sonar.java.coveragePlugin", "jacoco" + } } task configDocsZip(dependsOn: [':docs:asciidoctor',':spring-session:javadoc']) << { - project.tasks.docsZip.from(project(':docs').asciidoctor) { - into('reference') - } - project.tasks.docsZip.from(project(':spring-session').javadoc) { - into('api') - } + project.tasks.docsZip.from(project(':docs').asciidoctor) { + into('reference') + } + project.tasks.docsZip.from(project(':spring-session').javadoc) { + into('api') + } } task docsZip(type: Zip, dependsOn: 'configDocsZip') { - group = "Distribution" - baseName = "spring-session" - classifier = "docs" - description = "Builds -${classifier} archive containing api and reference " + - "for deployment." + group = "Distribution" + baseName = "spring-session" + classifier = "docs" + description = "Builds -${classifier} archive containing api and reference " + + "for deployment." } artifacts { - archives docsZip + archives docsZip } \ No newline at end of file diff --git a/docs/build.gradle b/docs/build.gradle index 69bc7f44..472a6075 100644 --- a/docs/build.gradle +++ b/docs/build.gradle @@ -8,37 +8,37 @@ asciidoctorj { tasks.findByPath("artifactoryPublish")?.enabled = false dependencies { - testCompile project(':spring-session'), - "org.springframework.data:spring-data-redis:$springDataRedisVersion", - "org.springframework:spring-websocket:${springVersion}", - "org.springframework:spring-messaging:${springVersion}", - 'junit:junit:4.11', - 'org.mockito:mockito-core:1.9.5', - "org.springframework:spring-test:$springVersion", - 'org.easytesting:fest-assert:1.4', - "redis.clients:jedis:2.4.1" + testCompile project(':spring-session'), + "org.springframework.data:spring-data-redis:$springDataRedisVersion", + "org.springframework:spring-websocket:${springVersion}", + "org.springframework:spring-messaging:${springVersion}", + 'junit:junit:4.11', + 'org.mockito:mockito-core:1.9.5', + "org.springframework:spring-test:$springVersion", + 'org.easytesting:fest-assert:1.4', + "redis.clients:jedis:2.4.1" } asciidoctor { - def ghTag = snapshotBuild ? 'master' : project.version - def ghUrl = "https://github.com/spring-projects/spring-session/tree/$ghTag/" - attributes 'version-snapshot': snapshotBuild, - 'version-milestone': milestoneBuild, - 'version-release': releaseBuild, - 'gh-url': ghUrl, - 'gh-samples-url': "$ghUrl/samples/", - 'download-url' : "https://github.com/spring-projects/spring-session/archive/${ghTag}.zip", - 'spring-session-version' : version, - 'spring-version' : springVersion, - 'docs-test-dir' : rootProject.projectDir.path + '/docs/src/test/java/', - 'samples-dir' : rootProject.projectDir.path + '/samples/', + def ghTag = snapshotBuild ? 'master' : project.version + def ghUrl = "https://github.com/spring-projects/spring-session/tree/$ghTag/" + attributes 'version-snapshot': snapshotBuild, + 'version-milestone': milestoneBuild, + 'version-release': releaseBuild, + 'gh-url': ghUrl, + 'gh-samples-url': "$ghUrl/samples/", + 'download-url' : "https://github.com/spring-projects/spring-session/archive/${ghTag}.zip", + 'spring-session-version' : version, + 'spring-version' : springVersion, + 'docs-test-dir' : rootProject.projectDir.path + '/docs/src/test/java/', + 'samples-dir' : rootProject.projectDir.path + '/samples/', - 'source-highlighter' : 'coderay', - 'imagesdir':'./images', - 'icons': 'font', - 'sectanchors':'', - 'idprefix':'', - 'idseparator':'-', - 'docinfo1':'true', - 'revnumber' : project.version + 'source-highlighter' : 'coderay', + 'imagesdir':'./images', + 'icons': 'font', + 'sectanchors':'', + 'idprefix':'', + 'idseparator':'-', + 'docinfo1':'true', + 'revnumber' : project.version } \ No newline at end of file diff --git a/docs/src/docs/asciidoc/guides/boot.adoc b/docs/src/docs/asciidoc/guides/boot.adoc index 3335c22f..87f08bbd 100644 --- a/docs/src/docs/asciidoc/guides/boot.adoc +++ b/docs/src/docs/asciidoc/guides/boot.adoc @@ -16,14 +16,14 @@ If you are using Maven, ensure to add the following dependencies: [subs="verbatim,attributes"] ---- - + - - org.springframework.session - spring-session-data-redis - {spring-session-version} - pom - + + org.springframework.session + spring-session-data-redis + {spring-session-version} + pom + ---- @@ -36,12 +36,12 @@ Ensure you have the following in your pom.xml: ---- - + - - spring-snapshot - https://repo.spring.io/libs-snapshot - + + spring-snapshot + https://repo.spring.io/libs-snapshot + ---- endif::[] @@ -54,8 +54,8 @@ Ensure you have the following in your pom.xml: [source,xml] ---- - spring-milestone - https://repo.spring.io/libs-milestone + spring-milestone + https://repo.spring.io/libs-milestone ---- endif::[] @@ -69,7 +69,7 @@ Add the following Spring Configuration: [source,java] ---- -include::{samples-dir}boot/src/main/java/sample/config/HttpSessionConfig.java[] +include::{samples-dir}boot/src/main/java/sample/config/HttpSessionConfig.java[tags=class] ---- <1> The `@EnableRedisHttpSession` annotation creates a Spring Bean with the name of `springSessionRepositoryFilter` that implements Filter. @@ -111,7 +111,9 @@ The boot Sample Application demonstrates how to use Spring Session to transparen You can run the sample by obtaining the {download-url}[source code] and invoking the following command: - $ ./gradlew :samples:boot:bootRun +---- +$ ./gradlew :samples:boot:bootRun +---- You should now be able to access the application at http://localhost:8080/ @@ -139,12 +141,12 @@ Go ahead and view the cookies (click for help with https://developer.chrome.com/ 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 + $ redis-cli keys '*' | xargs redis-cli del TIP: The Redis documentation has instructions for http://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 + $ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e Now visit the application at http://localhost:8080/ and observe that we are no longer authenticated. diff --git a/docs/src/docs/asciidoc/guides/httpsession.adoc b/docs/src/docs/asciidoc/guides/httpsession.adoc index edae9f6e..9947c4ae 100644 --- a/docs/src/docs/asciidoc/guides/httpsession.adoc +++ b/docs/src/docs/asciidoc/guides/httpsession.adoc @@ -15,19 +15,19 @@ If you are using Maven, ensure to add the following dependencies: [subs="verbatim,attributes"] ---- - + - - org.springframework.session - spring-session-data-redis - {spring-session-version} - pom - - - org.springframework - spring-web - {spring-version} - + + org.springframework.session + spring-session-data-redis + {spring-session-version} + pom + + + org.springframework + spring-web + {spring-version} + ---- @@ -40,12 +40,12 @@ Ensure you have the following in your pom.xml: ---- - + - - spring-snapshot - https://repo.spring.io/libs-snapshot - + + spring-snapshot + https://repo.spring.io/libs-snapshot + ---- endif::[] @@ -58,8 +58,8 @@ Ensure you have the following in your pom.xml: [source,xml] ---- - spring-milestone - https://repo.spring.io/libs-milestone + spring-milestone + https://repo.spring.io/libs-milestone ---- endif::[] @@ -75,7 +75,7 @@ Add the following Spring Configuration: [source,java] ---- -include::{samples-dir}httpsession/src/main/java/sample/Config.java[] +include::{samples-dir}httpsession/src/main/java/sample/Config.java[tags=class] ---- <1> We import an embedded Redis Server so that there is no need to start up Redis external of our application. @@ -100,7 +100,7 @@ You can find an example below: .src/main/java/sample/Initializer.java [source,java] ---- -include::{samples-dir}httpsession/src/main/java/sample/Initializer.java[] +include::{samples-dir}httpsession/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`. @@ -120,7 +120,9 @@ This ensures that the Spring Bean by the name `springSessionRepositoryFilter` is You can run the sample by obtaining the {download-url}[source code] and invoking the following command: - $ ./gradlew :samples:httpsession:tomcatRun +---- +$ ./gradlew :samples:httpsession:tomcatRun +---- You should now be able to access the application at http://localhost:8080/ @@ -140,7 +142,7 @@ We interact with the standard `HttpSession` in the `SessionServlet` shown below: .src/main/java/sample/SessionServlet.java [source,java] ---- -include::{samples-dir}httpsession/src/main/java/sample/SessionServlet.java[] +include::{samples-dir}httpsession/src/main/java/sample/SessionServlet.java[tags=class] ---- Instead of using Tomcat's `HttpSession`, we are actually persisting the values in Redis. @@ -149,12 +151,12 @@ Go ahead and view the cookies (click for help with https://developer.chrome.com/ 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 + $ redis-cli keys '*' | xargs redis-cli del TIP: The Redis documentation has instructions for http://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 + $ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e Now visit the application at http://localhost:8080/ and observe that the attribute we added is no longer displayed. \ No newline at end of file diff --git a/docs/src/docs/asciidoc/guides/rest.adoc b/docs/src/docs/asciidoc/guides/rest.adoc index d69cd5e2..668371d3 100644 --- a/docs/src/docs/asciidoc/guides/rest.adoc +++ b/docs/src/docs/asciidoc/guides/rest.adoc @@ -15,19 +15,19 @@ If you are using Maven, ensure to add the following dependencies: [subs="verbatim,attributes"] ---- - + - - org.springframework.session - spring-session-data-redis - {spring-session-version} - pom - - - org.springframework - spring-web - {spring-version} - + + org.springframework.session + spring-session-data-redis + {spring-session-version} + pom + + + org.springframework + spring-web + {spring-version} + ---- @@ -40,12 +40,12 @@ Ensure you have the following in your pom.xml: ---- - + - - spring-snapshot - https://repo.spring.io/libs-snapshot - + + spring-snapshot + https://repo.spring.io/libs-snapshot + ---- endif::[] @@ -58,8 +58,8 @@ Ensure you have the following in your pom.xml: [source,xml] ---- - spring-milestone - https://repo.spring.io/libs-milestone + spring-milestone + https://repo.spring.io/libs-milestone ---- endif::[] @@ -75,7 +75,7 @@ Add the following Spring Configuration: [source,java] ---- -include::{samples-dir}rest/src/main/java/sample/HttpSessionConfig.java[] +include::{samples-dir}rest/src/main/java/sample/HttpSessionConfig.java[tags=class] ---- <1> We import an embedded Redis Server so that there is no need to start up Redis external of our application. @@ -107,7 +107,7 @@ Fortunately, Spring Session provides a utility class named `AbstractHttpSessionA .src/main/java/sample/Initializer.java [source,java] ---- -include::{samples-dir}rest/src/main/java/sample/Initializer.java[] +include::{samples-dir}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`. @@ -121,7 +121,9 @@ NOTE: The name of our class (Initializer) does not matter. What is important is You can run the sample by obtaining the {download-url}[source code] and invoking the following command: - $ ./gradlew :samples:rest:tomcatRun +---- +$ ./gradlew :samples:rest:tomcatRun +---- You should now be able to access the application at http://localhost:8080/ @@ -129,14 +131,14 @@ You should now be able to access the application at http://localhost:8080/ Try using the application. Use your favorite REST client to request http://localhost:8080/ - $ curl -v 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 +$ curl -v http://localhost:8080/ -u user:password In the output you will notice the following: @@ -156,13 +158,13 @@ Specifically, we notice the following things about our response: 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 the username just as before: - $ curl -v http://localhost:8080/ -H "x-auth-token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3" + $ 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" + $ 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. @@ -181,7 +183,7 @@ Spring Session creates a header named x-auth-token in your browser that contains 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 +$ curl -v http://localhost:8080/ -u user:password In the output you will notice the following: @@ -195,14 +197,14 @@ x-auth-token: 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e Now remove the session using redis-cli. For example, on a Linux based system you can type: - $ redis-cli keys '*' | xargs redis-cli del + $ redis-cli keys '*' | xargs redis-cli del TIP: The Redis documentation has instructions for http://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 + $ 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" + $ curl -v http://localhost:8080/ -H "x-auth-token: 0dc1f6e1-c7f1-41ac-8ce2-32b6b3e57aa3" diff --git a/docs/src/docs/asciidoc/guides/security.adoc b/docs/src/docs/asciidoc/guides/security.adoc index 18729334..ce29d878 100644 --- a/docs/src/docs/asciidoc/guides/security.adoc +++ b/docs/src/docs/asciidoc/guides/security.adoc @@ -16,19 +16,19 @@ If you are using Maven, ensure to add the following dependencies: [subs="verbatim,attributes"] ---- - + - - org.springframework.session - spring-session-data-redis - {spring-session-version} - pom - - - org.springframework - spring-web - {spring-version} - + + org.springframework.session + spring-session-data-redis + {spring-session-version} + pom + + + org.springframework + spring-web + {spring-version} + ---- @@ -41,12 +41,12 @@ Ensure you have the following in your pom.xml: ---- - + - - spring-snapshot - https://repo.spring.io/libs-snapshot - + + spring-snapshot + https://repo.spring.io/libs-snapshot + ---- endif::[] @@ -59,8 +59,8 @@ Ensure you have the following in your pom.xml: [source,xml] ---- - spring-milestone - https://repo.spring.io/libs-milestone +spring-milestone +https://repo.spring.io/libs-milestone ---- endif::[] @@ -74,7 +74,7 @@ Add the following Spring Configuration: [source,java] ---- -include::{samples-dir}security/src/main/java/sample/Config.java[] +include::{samples-dir}security/src/main/java/sample/Config.java[tags=class] ---- <1> We import an embedded Redis Server so that there is no need to start up Redis external of our application. @@ -97,7 +97,7 @@ Since our application is already loading Spring configuration using our `Securit .src/main/java/sample/SecurityInitializer.java [source,java] ---- -include::{samples-dir}security/src/main/java/sample/SecurityInitializer.java[] +include::{samples-dir}security/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. @@ -109,7 +109,7 @@ You can find an example below: .src/main/java/sample/Initializer.java [source,java] ---- -include::{samples-dir}security/src/main/java/sample/Initializer.java[] +include::{samples-dir}security/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`. @@ -125,7 +125,9 @@ By extending `AbstractHttpSessionApplicationInitializer` we ensure that the Spri You can run the sample by obtaining the {download-url}[source code] and invoking the following command: - $ ./gradlew :samples:security:tomcatRun +---- +$ ./gradlew :samples:security:tomcatRun +---- You should now be able to access the application at http://localhost:8080/ @@ -151,12 +153,12 @@ Go ahead and view the cookies (click for help with https://developer.chrome.com/ 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 + $ redis-cli keys '*' | xargs redis-cli del TIP: The Redis documentation has instructions for http://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 + $ redis-cli del spring:session:sessions:7e8383a4-082c-4ffe-a4bc-c40fd3363c5e Now visit the application at http://localhost:8080/ and observe that we are no longer authenticated. \ No newline at end of file diff --git a/docs/src/docs/asciidoc/guides/users.adoc b/docs/src/docs/asciidoc/guides/users.adoc index bfed16a6..e95f49aa 100644 --- a/docs/src/docs/asciidoc/guides/users.adoc +++ b/docs/src/docs/asciidoc/guides/users.adoc @@ -17,7 +17,9 @@ The users application demonstrates how to allow an application to manage multipl You can run the sample by obtaining the {download-url}[source code] and invoking the following command: - $ ./gradlew :samples:users:tomcatRun +---- +$ ./gradlew :samples:users:tomcatRun +---- You should now be able to access the application at http://localhost:8080/ @@ -71,7 +73,7 @@ Let's take a look at how Spring Session keeps track of multiple sessions. Spring Session keeps track of the `HttpSession` by adding a value to a cookie named SESSION. For example, the SESSION cookie might have a value of: - 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e + 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e === Adding a Session @@ -113,7 +115,7 @@ The URL contains a session alias that either points to an existing unauthenticat Now our SESSION cookie looks something like this: - 0 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e 1 1d526d4a-c462-45a4-93d9-84a39b6d44ad + 0 7e8383a4-082c-4ffe-a4bc-c40fd3363c5e 1 1d526d4a-c462-45a4-93d9-84a39b6d44ad Such that: diff --git a/docs/src/docs/asciidoc/guides/websocket.adoc b/docs/src/docs/asciidoc/guides/websocket.adoc index a210df5e..b5a37d17 100644 --- a/docs/src/docs/asciidoc/guides/websocket.adoc +++ b/docs/src/docs/asciidoc/guides/websocket.adoc @@ -82,7 +82,9 @@ include::{samples-dir}websocket/src/main/java/sample/config/WebSecurityConfig.ja ---- ==== - $ ./gradlew :samples:websocket:bootRun +---- +$ ./gradlew :samples:websocket:bootRun +---- You should now be able to access the application at http://localhost:8080/ diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index d9b0ea0f..a451b18c 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -106,19 +106,19 @@ It looks something like the following: ---- public class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper { - public SessionRepositoryRequestWrapper(HttpServletRequest original) { - super(original); - } + public SessionRepositoryRequestWrapper(HttpServletRequest original) { + super(original); + } - public HttpSession getSession() { - return getSession(true); - } + public HttpSession getSession() { + return getSession(true); + } - public HttpSession getSession(boolean createNew) { - // create an HttpSession implementation from Spring Session - } + public HttpSession getSession(boolean createNew) { + // create an HttpSession implementation from Spring Session + } - // ... other methods delegate to the original HttpServletRequest ... + // ... other methods delegate to the original HttpServletRequest ... } ---- @@ -132,15 +132,15 @@ The pseudocode can be found below: ---- public class SessionRepositoryFilter implements Filter { - public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { - HttpServletRequest httpRequest = (HttpServletRequest) request; - SessionRepositoryRequestWrapper customRequest = - new SessionRepositoryRequestWrapper(httpRequest); + public doFilter(ServletRequest request, ServletResponse response, FilterChain chain) { + HttpServletRequest httpRequest = (HttpServletRequest) request; + SessionRepositoryRequestWrapper customRequest = + new SessionRepositoryRequestWrapper(httpRequest); - chain.doFilter(customRequest, response, chain); - } + chain.doFilter(customRequest, response, chain); + } - // ... + // ... } ---- @@ -286,9 +286,9 @@ Each session is stored in Redis as a Hash. Each session is set and updated using the HMSET command. An example of how each session is stored can be seen below. - HMSET spring:session:sessions: creationTime 1404360000000 \ - maxInactiveInterval 1800 lastAccessedTime 1404360000000 \ - sessionAttr: someAttrValue sessionAttr: someAttrValue2 + HMSET spring:session:sessions: creationTime 1404360000000 \ + maxInactiveInterval 1800 lastAccessedTime 1404360000000 \ + sessionAttr: someAttrValue sessionAttr: someAttrValue2 [[api-redisoperationssessionrepository-expiration]] ===== Session Expiration @@ -296,7 +296,7 @@ An example of how each session is stored can be seen below. An expiration is associated to each session using the EXPIRE command based upon the RedisOperationsSessionRepository.RedisSession.getMaxInactiveInterval(). For example: - EXPIRE spring:session:sessions: 1800 + EXPIRE spring:session:sessions: 1800 Spring Session relies on the expired and delete http://redis.io/topics/notifications[keyspace notifications] from Redis to fire a <>. It is the `SessionDestroyedEvent` that ensures resources associated with the Session are cleaned up. @@ -313,8 +313,8 @@ For this reason, each session expiration is also tracked to the nearest minute. This allows a background task to access the potentially expired sessions to ensure that Redis expired events are fired in a more deterministic fashion. For example: - SADD spring:session:expirations: - EXPIRE spring:session:expirations: 1800 +SADD spring:session:expirations: +EXPIRE spring:session:expirations: 1800 The background task will then use these mappings to explicitly request each key. By accessing they key, rather than deleting it, we ensure that Redis deletes the key for us only if the TTL is expired. @@ -331,8 +331,8 @@ This means if an attribute is written once and read many times we only need to w For example, assume the session attribute "sessionAttr2" from earlier was updated. The following would be executed upon saving: - HMSET spring:session:sessions: sessionAttr: newValue - EXPIRE spring:session:sessions: 1800 +HMSET spring:session:sessions: sessionAttr: newValue +EXPIRE spring:session:sessions: 1800 [[api-redisoperationssessionrepository-sessiondestroyedevent]] ==== SessionDestroyedEvent @@ -405,7 +405,7 @@ include::{indexdoc-tests}[tags=new-mapsessionrepository] The <> is a complete application demonstrating using Spring Session with Hazelcast. To run it use the following: - ./gradlew :samples:hazelcast:tomcatRun + ./gradlew :samples:hazelcast:tomcatRun [[community]] == Spring Session Community diff --git a/docs/src/test/java/docs/IndexDocTests.java b/docs/src/test/java/docs/IndexDocTests.java index d0287417..fdf46914 100644 --- a/docs/src/test/java/docs/IndexDocTests.java +++ b/docs/src/test/java/docs/IndexDocTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -26,85 +26,85 @@ import static org.fest.assertions.Assertions.assertThat; * @author Rob Winch */ public class IndexDocTests { - static final String ATTR_USER = "user"; + static final String ATTR_USER = "user"; - @Test - public void repositoryDemo() { - ExpiringRepositoryDemo demo = new ExpiringRepositoryDemo(); - demo.repository = new MapSessionRepository(); + @Test + public void repositoryDemo() { + ExpiringRepositoryDemo demo = new ExpiringRepositoryDemo(); + demo.repository = new MapSessionRepository(); - demo.demo(); - } + demo.demo(); + } - // tag::repository-demo[] - public class RepositoryDemo { - private SessionRepository repository; // <1> + // tag::repository-demo[] + public class RepositoryDemo { + private SessionRepository repository; // <1> - public void demo() { - S toSave = repository.createSession(); // <2> + public void demo() { + S toSave = repository.createSession(); // <2> - // <3> - User rwinch = new User("rwinch"); - toSave.setAttribute(ATTR_USER, rwinch); + // <3> + User rwinch = new User("rwinch"); + toSave.setAttribute(ATTR_USER, rwinch); - repository.save(toSave); // <4> + repository.save(toSave); // <4> - S session = repository.getSession(toSave.getId()); // <5> + S session = repository.getSession(toSave.getId()); // <5> - // <6> - User user = session.getAttribute(ATTR_USER); - assertThat(user).isEqualTo(rwinch); - } + // <6> + User user = session.getAttribute(ATTR_USER); + assertThat(user).isEqualTo(rwinch); + } - // ... setter methods ... - } - // end::repository-demo[] + // ... setter methods ... + } + // end::repository-demo[] - @Test - public void expireRepositoryDemo() { - ExpiringRepositoryDemo demo = new ExpiringRepositoryDemo(); - demo.repository = new MapSessionRepository(); + @Test + public void expireRepositoryDemo() { + ExpiringRepositoryDemo demo = new ExpiringRepositoryDemo(); + demo.repository = new MapSessionRepository(); - demo.demo(); - } + demo.demo(); + } - // tag::expire-repository-demo[] - public class ExpiringRepositoryDemo { - private SessionRepository repository; // <1> + // tag::expire-repository-demo[] + public class ExpiringRepositoryDemo { + private SessionRepository repository; // <1> - public void demo() { - S toSave = repository.createSession(); // <2> - // ... - toSave.setMaxInactiveIntervalInSeconds(30); // <3> + public void demo() { + S toSave = repository.createSession(); // <2> + // ... + toSave.setMaxInactiveIntervalInSeconds(30); // <3> - repository.save(toSave); // <4> + repository.save(toSave); // <4> - S session = repository.getSession(toSave.getId()); // <5> - // ... - } + S session = repository.getSession(toSave.getId()); // <5> + // ... + } - // ... setter methods ... - } - // end::expire-repository-demo[] + // ... setter methods ... + } + // end::expire-repository-demo[] - @Test - public void newRedisOperationsSessionRepository() { - // tag::new-redisoperationssessionrepository[] - JedisConnectionFactory factory = new JedisConnectionFactory(); - SessionRepository repository = - new RedisOperationsSessionRepository(factory); - // end::new-redisoperationssessionrepository[] - } + @Test + public void newRedisOperationsSessionRepository() { + // tag::new-redisoperationssessionrepository[] + JedisConnectionFactory factory = new JedisConnectionFactory(); + SessionRepository repository = + new RedisOperationsSessionRepository(factory); + // end::new-redisoperationssessionrepository[] + } - @Test - public void mapRepository() { - // tag::new-mapsessionrepository[] - SessionRepository repository = new MapSessionRepository(); - // end::new-mapsessionrepository[] - } + @Test + public void mapRepository() { + // tag::new-mapsessionrepository[] + SessionRepository repository = new MapSessionRepository(); + // end::new-mapsessionrepository[] + } - private static class User { - private User(String username) {} - } + private static class User { + private User(String username) {} + } } diff --git a/docs/src/test/java/docs/websocket/WebSocketConfig.java b/docs/src/test/java/docs/websocket/WebSocketConfig.java index acb24de3..46123ad2 100644 --- a/docs/src/test/java/docs/websocket/WebSocketConfig.java +++ b/docs/src/test/java/docs/websocket/WebSocketConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -30,17 +30,17 @@ import org.springframework.web.socket.config.annotation.StompEndpointRegistry; @EnableScheduling @EnableWebSocketMessageBroker public class WebSocketConfig - extends AbstractWebSocketMessageBrokerConfigurer { + extends AbstractWebSocketMessageBrokerConfigurer { - public void registerStompEndpoints(StompEndpointRegistry registry) { - registry.addEndpoint("/messages") - .withSockJS(); - } + public void registerStompEndpoints(StompEndpointRegistry registry) { + registry.addEndpoint("/messages") + .withSockJS(); + } - @Override - public void configureMessageBroker(MessageBrokerRegistry registry) { - registry.enableSimpleBroker("/queue/", "/topic/"); - registry.setApplicationDestinationPrefixes("/app"); - } + @Override + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/queue/", "/topic/"); + registry.setApplicationDestinationPrefixes("/app"); + } } // end::class[] \ No newline at end of file diff --git a/docs/src/test/java/docs/websocket/WebSocketDocTests.java b/docs/src/test/java/docs/websocket/WebSocketDocTests.java deleted file mode 100644 index e1562757..00000000 --- a/docs/src/test/java/docs/websocket/WebSocketDocTests.java +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Copyright 2002-2014 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 docs.websocket; - -import org.springframework.context.annotation.Configuration; -import org.springframework.messaging.simp.config.MessageBrokerRegistry; -import org.springframework.scheduling.annotation.EnableScheduling; -import org.springframework.web.socket.config.annotation.AbstractWebSocketMessageBrokerConfigurer; -import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker; -import org.springframework.web.socket.config.annotation.StompEndpointRegistry; - -/** - * @author Rob Winch - */ -public class WebSocketDocTests { - -} diff --git a/gradle/java.gradle b/gradle/java.gradle index 584ce2d5..43cba5f1 100644 --- a/gradle/java.gradle +++ b/gradle/java.gradle @@ -14,73 +14,73 @@ targetCompatibility = 1.5 ext.springIoVersion = project.hasProperty('platformVersion') ? platformVersion : '1.1.0.BUILD-SNAPSHOT' ext.spockDependencies = [ - dependencies.create("org.spockframework:spock-core:$spockVersion") { - exclude group: 'junit', module: 'junit-dep' - } + dependencies.create("org.spockframework:spock-core:$spockVersion") { + exclude group: 'junit', module: 'junit-dep' + } ] ext.gebDependencies = spockDependencies + [ - "org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion", - "org.gebish:geb-spock:$gebVersion", - 'commons-httpclient:commons-httpclient:3.1', - "org.codehaus.groovy:groovy:$groovyVersion" + "org.seleniumhq.selenium:selenium-htmlunit-driver:$seleniumVersion", + "org.gebish:geb-spock:$gebVersion", + 'commons-httpclient:commons-httpclient:3.1', + "org.codehaus.groovy:groovy:$groovyVersion" ] ext.jstlDependencies = [ - "javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion", - "org.apache.taglibs:taglibs-standard-jstlel:1.2.1" + "javax.servlet.jsp.jstl:javax.servlet.jsp.jstl-api:$jstlVersion", + "org.apache.taglibs:taglibs-standard-jstlel:1.2.1" ] repositories { - mavenCentral() - maven { url 'http://clojars.org/repo' } - maven { url 'https://repo.spring.io/libs-snapshot' } + mavenCentral() + maven { url 'http://clojars.org/repo' } + maven { url 'https://repo.spring.io/libs-snapshot' } } configurations.all { - resolutionStrategy.eachDependency { DependencyResolveDetails details -> - if (details.requested.group == 'org.springframework') { - details.useVersion springVersion - } - } + resolutionStrategy.eachDependency { DependencyResolveDetails details -> + if (details.requested.group == 'org.springframework') { + details.useVersion springVersion + } + } } // Integration test setup configurations { - integrationTestCompile { - extendsFrom testCompile, optional, provided - } - integrationTestRuntime { - extendsFrom integrationTestCompile, testRuntime - } + integrationTestCompile { + extendsFrom testCompile, optional, provided + } + integrationTestRuntime { + extendsFrom integrationTestCompile, testRuntime + } } sourceSets { - integrationTest { - java.srcDir file('src/integration-test/java') - groovy.srcDirs file('src/integration-test/groovy') - resources.srcDir file('src/integration-test/resources') - compileClasspath = sourceSets.main.output + sourceSets.test.output + configurations.integrationTestCompile - runtimeClasspath = output + compileClasspath + configurations.integrationTestRuntime - } + integrationTest { + java.srcDir file('src/integration-test/java') + groovy.srcDirs file('src/integration-test/groovy') + resources.srcDir file('src/integration-test/resources') + compileClasspath = sourceSets.main.output + sourceSets.test.output + configurations.integrationTestCompile + runtimeClasspath = output + compileClasspath + configurations.integrationTestRuntime + } } task integrationTest(type: Test, dependsOn: jar) { - testClassesDir = sourceSets.integrationTest.output.classesDir - logging.captureStandardOutput(LogLevel.INFO) - classpath = sourceSets.integrationTest.runtimeClasspath - maxParallelForks = 1 - reports { - html.destination = project.file("$project.buildDir/reports/integration-tests/") - junitXml.destination = project.file("$project.buildDir/integration-test-results/") - } + testClassesDir = sourceSets.integrationTest.output.classesDir + logging.captureStandardOutput(LogLevel.INFO) + classpath = sourceSets.integrationTest.runtimeClasspath + maxParallelForks = 1 + reports { + html.destination = project.file("$project.buildDir/reports/integration-tests/") + junitXml.destination = project.file("$project.buildDir/integration-test-results/") + } } eclipse { - classpath { - plusConfigurations += [ configurations.integrationTestCompile ] - } + classpath { + plusConfigurations += [ configurations.integrationTestCompile ] + } } project.idea.module { - scopes.TEST.plus += [project.configurations.integrationTestRuntime] + scopes.TEST.plus += [project.configurations.integrationTestRuntime] } \ No newline at end of file diff --git a/gradle/publish-maven.gradle b/gradle/publish-maven.gradle index e5788a12..89fc7673 100644 --- a/gradle/publish-maven.gradle +++ b/gradle/publish-maven.gradle @@ -1,51 +1,51 @@ apply plugin: 'propdeps-maven' install { - repositories.mavenInstaller { - customizePom(pom, project) - } + repositories.mavenInstaller { + customizePom(pom, project) + } } def customizePom(pom, gradleProject) { - pom.whenConfigured { generatedPom -> + pom.whenConfigured { generatedPom -> - // sort to make pom dependencies order consistent to ease comparison of older poms - generatedPom.dependencies = generatedPom.dependencies.sort { dep -> - "$dep.scope:$dep.groupId:$dep.artifactId" - } + // sort to make pom dependencies order consistent to ease comparison of older poms + generatedPom.dependencies = generatedPom.dependencies.sort { dep -> + "$dep.scope:$dep.groupId:$dep.artifactId" + } - // add all items necessary for maven central publication - generatedPom.project { - name = gradleProject.description - description = gradleProject.description - url = "https://github.com/spring-projects/spring-session" - organization { - name = "Spring IO" - url = "http://projects.spring.io/spring-session" - } - licenses { - license { - name "The Apache Software License, Version 2.0" - url "http://www.apache.org/licenses/LICENSE-2.0.txt" - distribution "repo" - } - } - scm { - url = "https://github.com/spring-projects/spring-session" - connection = "scm:git:git://github.com/spring-projects/spring-session" - developerConnection = "scm:git:git://github.com/spring-projects/spring-session" - } - developers { - developer { - id = "rwinch" - name = "Rob Winch" - email = "rwinch@pivotal.io" - } - } - issueManagement { - system = "GitHub" - url = "https://github.com/spring-projects/spring-session/issues" - } - } - } + // add all items necessary for maven central publication + generatedPom.project { + name = gradleProject.description + description = gradleProject.description + url = "https://github.com/spring-projects/spring-session" + organization { + name = "Spring IO" + url = "http://projects.spring.io/spring-session" + } + licenses { + license { + name "The Apache Software License, Version 2.0" + url "http://www.apache.org/licenses/LICENSE-2.0.txt" + distribution "repo" + } + } + scm { + url = "https://github.com/spring-projects/spring-session" + connection = "scm:git:git://github.com/spring-projects/spring-session" + developerConnection = "scm:git:git://github.com/spring-projects/spring-session" + } + developers { + developer { + id = "rwinch" + name = "Rob Winch" + email = "rwinch@pivotal.io" + } + } + issueManagement { + system = "GitHub" + url = "https://github.com/spring-projects/spring-session/issues" + } + } + } } \ No newline at end of file diff --git a/gradle/tomcat.gradle b/gradle/tomcat.gradle index dadb414f..0fb391eb 100644 --- a/gradle/tomcat.gradle +++ b/gradle/tomcat.gradle @@ -1,71 +1,71 @@ buildscript { - repositories { - maven { url "https://repo.spring.io/plugins-release" } - } - dependencies { - classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.3") - } + repositories { + maven { url "https://repo.spring.io/plugins-release" } + } + dependencies { + classpath("org.gradle.api.plugins:gradle-tomcat-plugin:1.2.3") + } } apply plugin: 'war' apply plugin: 'tomcat' dependencies { - def tomcatVersion = '7.0.54' - tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}", - "org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}" - tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") { - exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj' - } + def tomcatVersion = '7.0.54' + tomcat "org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}", + "org.apache.tomcat.embed:tomcat-embed-logging-juli:${tomcatVersion}" + tomcat("org.apache.tomcat.embed:tomcat-embed-jasper:${tomcatVersion}") { + exclude group: 'org.eclipse.jdt.core.compiler', module: 'ecj' + } } [tomcatRun,tomcatRunWar]*.contextPath = '/' task integrationTomcatRun(type: org.gradle.api.plugins.tomcat.tasks.TomcatRun) { - onlyIf { !sourceSets.integrationTest.allSource.empty } - buildscriptClasspath = tomcatRun.buildscriptClasspath - contextPath = tomcatRun.contextPath - daemon = true - tomcatClasspath = tomcatRun.tomcatClasspath - webAppClasspath = tomcatRun.webAppClasspath - webAppSourceDirectory = tomcatRun.webAppSourceDirectory - doFirst { - def mainOutputDir = project.sourceSets.main.output.classesDir - if(mainOutputDir) { - classesDirectory = mainOutputDir - } - // delay reserving ports to ensure they are still available - def ports = reservePorts(3) - httpPort = ports[0] - ajpPort = ports[1] - stopPort = ports[2] - } + onlyIf { !sourceSets.integrationTest.allSource.empty } + buildscriptClasspath = tomcatRun.buildscriptClasspath + contextPath = tomcatRun.contextPath + daemon = true + tomcatClasspath = tomcatRun.tomcatClasspath + webAppClasspath = tomcatRun.webAppClasspath + webAppSourceDirectory = tomcatRun.webAppSourceDirectory + doFirst { + def mainOutputDir = project.sourceSets.main.output.classesDir + if(mainOutputDir) { + classesDirectory = mainOutputDir + } + // delay reserving ports to ensure they are still available + def ports = reservePorts(3) + httpPort = ports[0] + ajpPort = ports[1] + stopPort = ports[2] + } } task integrationTomcatStop(type: org.gradle.api.plugins.tomcat.tasks.TomcatStop) { - onlyIf { !sourceSets.integrationTest.allSource.empty } - doFirst { - stopPort = integrationTomcatRun.stopPort - } + onlyIf { !sourceSets.integrationTest.allSource.empty } + doFirst { + stopPort = integrationTomcatRun.stopPort + } } integrationTest { - dependsOn integrationTomcatRun - doFirst { - def host = 'localhost:' + integrationTomcatRun.httpPort - systemProperties['geb.build.baseUrl'] = 'http://'+host+'/' + integrationTomcatRun.contextPath - systemProperties['geb.build.reportsDir'] = 'build/geb-reports' - } - finalizedBy integrationTomcatStop + dependsOn integrationTomcatRun + doFirst { + def host = 'localhost:' + integrationTomcatRun.httpPort + systemProperties['geb.build.baseUrl'] = 'http://'+host+'/' + integrationTomcatRun.contextPath + systemProperties['geb.build.reportsDir'] = 'build/geb-reports' + } + finalizedBy integrationTomcatStop } def reservePorts(int count) { - def sockets = [] - for(int i in 1..count) { - sockets << new ServerSocket(0) - } - def result = sockets*.localPort - sockets*.close() - result + def sockets = [] + for(int i in 1..count) { + sockets << new ServerSocket(0) + } + def result = sockets*.localPort + sockets*.close() + result } \ No newline at end of file diff --git a/samples/boot/build.gradle b/samples/boot/build.gradle index 3fd1f07f..8309f45b 100644 --- a/samples/boot/build.gradle +++ b/samples/boot/build.gradle @@ -1,10 +1,10 @@ buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion") - } + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion") + } } apply plugin: 'spring-boot' @@ -16,36 +16,36 @@ tasks.findByPath("artifactoryPublish")?.enabled = false group = 'samples' dependencies { - compile project(':spring-session-data-redis'), - "org.springframework.boot:spring-boot-starter-web", - "org.springframework.boot:spring-boot-starter-thymeleaf", - "redis.embedded:embedded-redis:0.2", - "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect", - "org.springframework.security:spring-security-web:$springSecurityVersion", - "org.springframework.security:spring-security-config:$springSecurityVersion" + compile project(':spring-session-data-redis'), + "org.springframework.boot:spring-boot-starter-web", + "org.springframework.boot:spring-boot-starter-thymeleaf", + "redis.embedded:embedded-redis:0.2", + "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect", + "org.springframework.security:spring-security-web:$springSecurityVersion", + "org.springframework.security:spring-security-config:$springSecurityVersion" - testCompile "org.springframework.boot:spring-boot-starter-test" + testCompile "org.springframework.boot:spring-boot-starter-test" - integrationTestCompile gebDependencies, - "org.spockframework:spock-spring:$spockVersion" + integrationTestCompile gebDependencies, + "org.spockframework:spock-spring:$spockVersion" } integrationTest { - doFirst { - def port = reservePort() + doFirst { + def port = reservePort() - def host = 'localhost:' + port - systemProperties['geb.build.baseUrl'] = 'http://'+host+'/' - systemProperties['geb.build.reportsDir'] = 'build/geb-reports' - systemProperties['server.port'] = port - systemProperties['management.port'] = 0 - } + def host = 'localhost:' + port + systemProperties['geb.build.baseUrl'] = 'http://'+host+'/' + systemProperties['geb.build.reportsDir'] = 'build/geb-reports' + systemProperties['server.port'] = port + systemProperties['management.port'] = 0 + } } def reservePort() { - def socket = new ServerSocket(0) - def result = socket.localPort - socket.close() - result + def socket = new ServerSocket(0) + def result = socket.localPort + socket.close() + result } \ No newline at end of file diff --git a/samples/boot/src/integration-test/groovy/sample/BootTests.groovy b/samples/boot/src/integration-test/groovy/sample/BootTests.groovy index 134aaf52..b1c8d7f4 100644 --- a/samples/boot/src/integration-test/groovy/sample/BootTests.groovy +++ b/samples/boot/src/integration-test/groovy/sample/BootTests.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 geb.spock.* @@ -23,37 +38,37 @@ import pages.* @IntegrationTest class BootTests extends GebReportingSpec { - def 'Unauthenticated user sent to log in page'() { - when: 'unauthenticated user request protected page' - via HomePage - then: 'sent to the log in page' - at LoginPage - } + def 'Unauthenticated user sent to log in page'() { + when: 'unauthenticated user request protected page' + via HomePage + then: 'sent to the log in page' + at LoginPage + } - def 'Log in views home page'() { - when: 'log in successfully' - login() - then: 'sent to original page' - at HomePage - and: 'the username is displayed' - username == 'user' - 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 in views home page'() { + when: 'log in successfully' + login() + then: 'sent to original page' + at HomePage + and: 'the username is displayed' + username == 'user' + 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 LoginPage - } + def 'Log out success'() { + when: + logout() + then: + at LoginPage + } - def 'Logged out user sent to log in page'() { - when: 'logged out user request protected page' - via HomePage - then: 'sent to the log in page' - at LoginPage - } + def 'Logged out user sent to log in page'() { + when: 'logged out user request protected page' + via HomePage + then: 'sent to the log in page' + at LoginPage + } } \ No newline at end of file diff --git a/samples/boot/src/integration-test/groovy/sample/pages/HomePage.groovy b/samples/boot/src/integration-test/groovy/sample/pages/HomePage.groovy index ec93126f..867b81a7 100644 --- a/samples/boot/src/integration-test/groovy/sample/pages/HomePage.groovy +++ b/samples/boot/src/integration-test/groovy/sample/pages/HomePage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.* @@ -8,10 +23,10 @@ import geb.* * @author Rob Winch */ class HomePage extends Page { - static url = '' - static at = { assert driver.title == 'Spring Session Sample - Secured Content'; true} - static content = { - username { $('#un').text() } - logout(to:LoginPage) { $('input[type=submit]').click() } - } + static url = '' + static at = { assert driver.title == 'Spring Session Sample - Secured Content'; true} + static content = { + username { $('#un').text() } + logout(to:LoginPage) { $('input[type=submit]').click() } + } } diff --git a/samples/boot/src/integration-test/groovy/sample/pages/LoginPage.groovy b/samples/boot/src/integration-test/groovy/sample/pages/LoginPage.groovy index 63f9d6f9..ceeb790a 100644 --- a/samples/boot/src/integration-test/groovy/sample/pages/LoginPage.groovy +++ b/samples/boot/src/integration-test/groovy/sample/pages/LoginPage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.* @@ -8,15 +23,15 @@ import geb.* * @author Rob Winch */ class LoginPage extends Page { - static url = '/login' - static at = { assert driver.title == 'Login Page'; true} - static content = { - form { $('form') } - submit { $('input[type=submit]') } - login(required:false) { user='user', pass='password' -> - form.username = user - form.password = pass - submit.click(HomePage) - } - } + static url = '/login' + static at = { assert driver.title == 'Login Page'; true} + static content = { + form { $('form') } + submit { $('input[type=submit]') } + login(required:false) { user='user', pass='password' -> + form.username = user + form.password = pass + submit.click(HomePage) + } + } } diff --git a/samples/boot/src/main/java/sample/Application.java b/samples/boot/src/main/java/sample/Application.java index 8bf6cf63..7646ee50 100644 --- a/samples/boot/src/main/java/sample/Application.java +++ b/samples/boot/src/main/java/sample/Application.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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 @@ -28,7 +28,7 @@ import org.springframework.context.annotation.Configuration; @EnableAutoConfiguration public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } diff --git a/samples/boot/src/main/java/sample/config/EmbeddedRedisConfiguration.java b/samples/boot/src/main/java/sample/config/EmbeddedRedisConfiguration.java index 38958db6..b380d397 100644 --- a/samples/boot/src/main/java/sample/config/EmbeddedRedisConfiguration.java +++ b/samples/boot/src/main/java/sample/config/EmbeddedRedisConfiguration.java @@ -1,19 +1,19 @@ -package sample.config; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 + * 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 + * 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. + * 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.config; import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; @@ -36,35 +36,33 @@ import redis.embedded.RedisServer; @Configuration public class EmbeddedRedisConfiguration { - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public static RedisServerBean redisServer() { + return new RedisServerBean(); + } - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(Protocol.DEFAULT_PORT); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(Protocol.DEFAULT_PORT); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } } \ No newline at end of file diff --git a/samples/boot/src/main/java/sample/config/HttpSessionConfig.java b/samples/boot/src/main/java/sample/config/HttpSessionConfig.java index 0a424266..5bb05052 100644 --- a/samples/boot/src/main/java/sample/config/HttpSessionConfig.java +++ b/samples/boot/src/main/java/sample/config/HttpSessionConfig.java @@ -1,6 +1,23 @@ +/* + * Copyright 2002-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 + * + * 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.config; import org.springframework.session.data.redis.config.annotation.web.http.*; +// tag::class[] @EnableRedisHttpSession // <1> public class HttpSessionConfig { } +// end::class[] \ No newline at end of file diff --git a/samples/boot/src/main/java/sample/config/SecurityConfig.java b/samples/boot/src/main/java/sample/config/SecurityConfig.java index 2bc8d1a1..ab040300 100644 --- a/samples/boot/src/main/java/sample/config/SecurityConfig.java +++ b/samples/boot/src/main/java/sample/config/SecurityConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -26,10 +26,10 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth - .inMemoryAuthentication() - .withUser("user").password("password").roles("USER"); - } + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER"); + } } diff --git a/samples/boot/src/main/java/sample/mvc/IndexController.java b/samples/boot/src/main/java/sample/mvc/IndexController.java index 16c0343f..8a76934d 100644 --- a/samples/boot/src/main/java/sample/mvc/IndexController.java +++ b/samples/boot/src/main/java/sample/mvc/IndexController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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 @@ -26,8 +26,8 @@ import org.springframework.web.bind.annotation.RequestMapping; */ @Controller public class IndexController { - @RequestMapping("/") - public String index() { - return "index"; - } + @RequestMapping("/") + public String index() { + return "index"; + } } diff --git a/samples/boot/src/main/resources/templates/index.html b/samples/boot/src/main/resources/templates/index.html index a7f875cb..1a3f6e49 100644 --- a/samples/boot/src/main/resources/templates/index.html +++ b/samples/boot/src/main/resources/templates/index.html @@ -1,11 +1,11 @@ - - Secured Content - - -
-

Secured Page

-

This page is secured using Spring Boot, Spring Session, and Spring Security.

-
- + + Secured Content + + +
+

Secured Page

+

This page is secured using Spring Boot, Spring Session, and Spring Security.

+
+ \ No newline at end of file diff --git a/samples/boot/src/main/resources/templates/layout.html b/samples/boot/src/main/resources/templates/layout.html index 40685fe6..e6edb849 100644 --- a/samples/boot/src/main/resources/templates/layout.html +++ b/samples/boot/src/main/resources/templates/layout.html @@ -1,122 +1,122 @@ - - Spring Session Sample - - - - + .container { + width: auto; + max-width: 680px; + } + .container .credit { + margin: 20px 0; + text-align: center; + } + a { + color: green; + } + .navbar-form { + margin-left: 1em; + } + + - - - + + + - -
- +
+
- - + + \ No newline at end of file diff --git a/samples/hazelcast/build.gradle b/samples/hazelcast/build.gradle index a4acb6bc..1f9f34b6 100644 --- a/samples/hazelcast/build.gradle +++ b/samples/hazelcast/build.gradle @@ -3,17 +3,17 @@ apply from: TOMCAT_GRADLE tasks.findByPath("artifactoryPublish")?.enabled = false sonarRunner { - skipProject = true + skipProject = true } dependencies { - compile project(':spring-session'), - "com.hazelcast:hazelcast-client:3.3.3", - jstlDependencies + compile project(':spring-session'), + "com.hazelcast:hazelcast-client:3.3.3", + jstlDependencies - providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" + providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" - testCompile 'junit:junit:4.11' + testCompile 'junit:junit:4.11' - integrationTestCompile gebDependencies + integrationTestCompile gebDependencies } \ No newline at end of file diff --git a/samples/hazelcast/src/integration-test/groovy/sample/AttributeTests.groovy b/samples/hazelcast/src/integration-test/groovy/sample/AttributeTests.groovy index 37febcb8..a5f85c86 100644 --- a/samples/hazelcast/src/integration-test/groovy/sample/AttributeTests.groovy +++ b/samples/hazelcast/src/integration-test/groovy/sample/AttributeTests.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 geb.spock.* @@ -12,19 +27,19 @@ import pages.* */ @Stepwise class AttributeTests extends GebReportingSpec { - def 'first visit no attributes'() { - when: - to HomePage - then: - attributes.empty - } + def 'first visit no attributes'() { + when: + to HomePage + then: + attributes.empty + } - def 'create attribute'() { - when: - createAttribute('a','b') - then: - attributes.size() == 1 - attributes[0].name == 'a' - attributes[0].value == 'b' - } + def 'create attribute'() { + when: + createAttribute('a','b') + then: + attributes.size() == 1 + attributes[0].name == 'a' + attributes[0].value == 'b' + } } \ No newline at end of file diff --git a/samples/hazelcast/src/integration-test/groovy/sample/pages/HomePage.groovy b/samples/hazelcast/src/integration-test/groovy/sample/pages/HomePage.groovy index ab5c4590..e087b5c4 100644 --- a/samples/hazelcast/src/integration-test/groovy/sample/pages/HomePage.groovy +++ b/samples/hazelcast/src/integration-test/groovy/sample/pages/HomePage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.* @@ -8,23 +23,23 @@ import geb.* * @author Rob Winch */ class HomePage extends Page { - static url = '' - static at = { assert driver.title == 'Session Attributes'; true} - static content = { - form { $('form') } - submit { $('input[type=submit]') } - createAttribute(required:false) { name, value -> - form.attributeName = name - form.attributeValue = value - submit.click(HomePage) - } - attributes { moduleList AttributeRow, $("table tr").tail() } - } + static url = '' + static at = { assert driver.title == 'Session Attributes'; true} + static content = { + form { $('form') } + submit { $('input[type=submit]') } + createAttribute(required:false) { name, value -> + form.attributeName = name + form.attributeValue = value + submit.click(HomePage) + } + attributes { moduleList AttributeRow, $("table tr").tail() } + } } class AttributeRow extends Module { - static content = { - cell { $("td", it) } - name { cell(0).text() } - value { cell(1).text() } - } + static content = { + cell { $("td", it) } + name { cell(0).text() } + value { cell(1).text() } + } } diff --git a/samples/hazelcast/src/main/java/sample/Initializer.java b/samples/hazelcast/src/main/java/sample/Initializer.java index 0f99f331..c1caf406 100644 --- a/samples/hazelcast/src/main/java/sample/Initializer.java +++ b/samples/hazelcast/src/main/java/sample/Initializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -40,51 +40,51 @@ import java.util.Map; @WebListener public class Initializer implements ServletContextListener { - private HazelcastInstance instance; + private HazelcastInstance instance; - public void contextInitialized(ServletContextEvent sce) { - String sessionMapName = "spring:session:sessions"; - ServletContext sc = sce.getServletContext(); + public void contextInitialized(ServletContextEvent sce) { + String sessionMapName = "spring:session:sessions"; + ServletContext sc = sce.getServletContext(); - Config cfg = new Config(); - NetworkConfig netConfig = new NetworkConfig(); - netConfig.setPort(getAvailablePort()); - cfg.setNetworkConfig(netConfig); - SerializerConfig serializer = new SerializerConfig() - .setTypeClass(Object.class) - .setImplementation(new ObjectStreamSerializer()); - cfg.getSerializationConfig().addSerializerConfig(serializer); - MapConfig mc = new MapConfig(); - mc.setName(sessionMapName); - mc.setTimeToLiveSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS); - cfg.addMapConfig(mc); + Config cfg = new Config(); + NetworkConfig netConfig = new NetworkConfig(); + netConfig.setPort(getAvailablePort()); + cfg.setNetworkConfig(netConfig); + SerializerConfig serializer = new SerializerConfig() + .setTypeClass(Object.class) + .setImplementation(new ObjectStreamSerializer()); + cfg.getSerializationConfig().addSerializerConfig(serializer); + MapConfig mc = new MapConfig(); + mc.setName(sessionMapName); + mc.setTimeToLiveSeconds(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS); + cfg.addMapConfig(mc); - instance = Hazelcast.newHazelcastInstance(cfg); - Map sessions = instance.getMap(sessionMapName); + instance = Hazelcast.newHazelcastInstance(cfg); + Map sessions = instance.getMap(sessionMapName); - SessionRepository sessionRepository = - new MapSessionRepository(sessions); - SessionRepositoryFilter filter = - new SessionRepositoryFilter(sessionRepository); - Dynamic fr = sc.addFilter("springSessionFilter", filter); - fr.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); - } + SessionRepository sessionRepository = + new MapSessionRepository(sessions); + SessionRepositoryFilter filter = + new SessionRepositoryFilter(sessionRepository); + Dynamic fr = sc.addFilter("springSessionFilter", filter); + fr.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/*"); + } - public void contextDestroyed(ServletContextEvent sce) { - instance.shutdown(); - } + public void contextDestroyed(ServletContextEvent sce) { + instance.shutdown(); + } - private static int getAvailablePort() { - ServerSocket socket = null; - try { - socket = new ServerSocket(0); - return socket.getLocalPort(); - } catch(IOException e) { - throw new RuntimeException(e); - } finally { - try { - socket.close(); - }catch(IOException e) {} - } - } + private static int getAvailablePort() { + ServerSocket socket = null; + try { + socket = new ServerSocket(0); + return socket.getLocalPort(); + } catch(IOException e) { + throw new RuntimeException(e); + } finally { + try { + socket.close(); + }catch(IOException e) {} + } + } } \ No newline at end of file diff --git a/samples/hazelcast/src/main/java/sample/ObjectStreamSerializer.java b/samples/hazelcast/src/main/java/sample/ObjectStreamSerializer.java index 7a203f2e..11db8e8c 100644 --- a/samples/hazelcast/src/main/java/sample/ObjectStreamSerializer.java +++ b/samples/hazelcast/src/main/java/sample/ObjectStreamSerializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -32,28 +32,28 @@ import com.hazelcast.nio.serialization.StreamSerializer; * */ public class ObjectStreamSerializer implements StreamSerializer { - public int getTypeId() { - return 2; - } + public int getTypeId() { + return 2; + } - public void write(ObjectDataOutput objectDataOutput, Object object) - throws IOException { - ObjectOutputStream out = new ObjectOutputStream((OutputStream) objectDataOutput); - out.writeObject(object); - out.flush(); - } + public void write(ObjectDataOutput objectDataOutput, Object object) + throws IOException { + ObjectOutputStream out = new ObjectOutputStream((OutputStream) objectDataOutput); + out.writeObject(object); + out.flush(); + } - public Object read(ObjectDataInput objectDataInput) - throws IOException { - ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput); - try { - return in.readObject(); - } catch (ClassNotFoundException e) { - throw new IOException(e); - } - } + public Object read(ObjectDataInput objectDataInput) + throws IOException { + ObjectInputStream in = new ObjectInputStream((InputStream) objectDataInput); + try { + return in.readObject(); + } catch (ClassNotFoundException e) { + throw new IOException(e); + } + } - public void destroy() { - } + public void destroy() { + } } diff --git a/samples/hazelcast/src/main/java/sample/SessionServlet.java b/samples/hazelcast/src/main/java/sample/SessionServlet.java index 683ecd46..95924600 100644 --- a/samples/hazelcast/src/main/java/sample/SessionServlet.java +++ b/samples/hazelcast/src/main/java/sample/SessionServlet.java @@ -1,19 +1,19 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 + * 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 + * 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. + * 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 javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; @@ -28,13 +28,13 @@ import java.io.IOException; @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() + "/"); - } + @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; + private static final long serialVersionUID = 2878267318695777395L; } diff --git a/samples/httpsession-xml/build.gradle b/samples/httpsession-xml/build.gradle index 8e1d8e5f..2f002180 100644 --- a/samples/httpsession-xml/build.gradle +++ b/samples/httpsession-xml/build.gradle @@ -3,18 +3,18 @@ apply from: TOMCAT_GRADLE tasks.findByPath("artifactoryPublish")?.enabled = false sonarRunner { - skipProject = true + skipProject = true } dependencies { - compile project(':spring-session-data-redis'), - "org.springframework:spring-web:$springVersion", - "redis.embedded:embedded-redis:0.2", - jstlDependencies + compile project(':spring-session-data-redis'), + "org.springframework:spring-web:$springVersion", + "redis.embedded:embedded-redis:0.2", + jstlDependencies - providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" + providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" - testCompile 'junit:junit:4.11' + testCompile 'junit:junit:4.11' - integrationTestCompile gebDependencies + integrationTestCompile gebDependencies } \ No newline at end of file diff --git a/samples/httpsession-xml/src/integration-test/groovy/sample/AttributeTests.groovy b/samples/httpsession-xml/src/integration-test/groovy/sample/AttributeTests.groovy index 37febcb8..a5f85c86 100644 --- a/samples/httpsession-xml/src/integration-test/groovy/sample/AttributeTests.groovy +++ b/samples/httpsession-xml/src/integration-test/groovy/sample/AttributeTests.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 geb.spock.* @@ -12,19 +27,19 @@ import pages.* */ @Stepwise class AttributeTests extends GebReportingSpec { - def 'first visit no attributes'() { - when: - to HomePage - then: - attributes.empty - } + def 'first visit no attributes'() { + when: + to HomePage + then: + attributes.empty + } - def 'create attribute'() { - when: - createAttribute('a','b') - then: - attributes.size() == 1 - attributes[0].name == 'a' - attributes[0].value == 'b' - } + def 'create attribute'() { + when: + createAttribute('a','b') + then: + attributes.size() == 1 + attributes[0].name == 'a' + attributes[0].value == 'b' + } } \ No newline at end of file diff --git a/samples/httpsession-xml/src/integration-test/groovy/sample/pages/HomePage.groovy b/samples/httpsession-xml/src/integration-test/groovy/sample/pages/HomePage.groovy index ab5c4590..e087b5c4 100644 --- a/samples/httpsession-xml/src/integration-test/groovy/sample/pages/HomePage.groovy +++ b/samples/httpsession-xml/src/integration-test/groovy/sample/pages/HomePage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.* @@ -8,23 +23,23 @@ import geb.* * @author Rob Winch */ class HomePage extends Page { - static url = '' - static at = { assert driver.title == 'Session Attributes'; true} - static content = { - form { $('form') } - submit { $('input[type=submit]') } - createAttribute(required:false) { name, value -> - form.attributeName = name - form.attributeValue = value - submit.click(HomePage) - } - attributes { moduleList AttributeRow, $("table tr").tail() } - } + static url = '' + static at = { assert driver.title == 'Session Attributes'; true} + static content = { + form { $('form') } + submit { $('input[type=submit]') } + createAttribute(required:false) { name, value -> + form.attributeName = name + form.attributeValue = value + submit.click(HomePage) + } + attributes { moduleList AttributeRow, $("table tr").tail() } + } } class AttributeRow extends Module { - static content = { - cell { $("td", it) } - name { cell(0).text() } - value { cell(1).text() } - } + static content = { + cell { $("td", it) } + name { cell(0).text() } + value { cell(1).text() } + } } diff --git a/samples/httpsession-xml/src/main/java/sample/RedisHttpSessionConfig.java b/samples/httpsession-xml/src/main/java/sample/RedisHttpSessionConfig.java index 0f959f3e..524adeb5 100644 --- a/samples/httpsession-xml/src/main/java/sample/RedisHttpSessionConfig.java +++ b/samples/httpsession-xml/src/main/java/sample/RedisHttpSessionConfig.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.session.data.redis.config.annotation.web.http.*; diff --git a/samples/httpsession-xml/src/main/java/sample/RedisServerBean.java b/samples/httpsession-xml/src/main/java/sample/RedisServerBean.java index a2826b1c..1d0f9a13 100644 --- a/samples/httpsession-xml/src/main/java/sample/RedisServerBean.java +++ b/samples/httpsession-xml/src/main/java/sample/RedisServerBean.java @@ -1,6 +1,5 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -14,14 +13,14 @@ package sample; * License for the specific language governing permissions and limitations under * the License. */ +package sample; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.beans.factory.support.BeanDefinitionRegistry; import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import redis.clients.jedis.Protocol; import redis.embedded.RedisServer; @@ -34,21 +33,21 @@ import redis.embedded.RedisServer; * @author Rob Winch */ public class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(Protocol.DEFAULT_PORT); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(Protocol.DEFAULT_PORT); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} } \ No newline at end of file diff --git a/samples/httpsession-xml/src/main/java/sample/SessionServlet.java b/samples/httpsession-xml/src/main/java/sample/SessionServlet.java index 2330d645..3c510143 100644 --- a/samples/httpsession-xml/src/main/java/sample/SessionServlet.java +++ b/samples/httpsession-xml/src/main/java/sample/SessionServlet.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 javax.servlet.*; @@ -5,16 +20,19 @@ import javax.servlet.annotation.*; import javax.servlet.http.*; import java.io.IOException; +// 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() + "/"); - } + @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; + private static final long serialVersionUID = 2878267318695777395L; } + +// end::class[] \ No newline at end of file diff --git a/samples/httpsession/build.gradle b/samples/httpsession/build.gradle index 8e1d8e5f..2f002180 100644 --- a/samples/httpsession/build.gradle +++ b/samples/httpsession/build.gradle @@ -3,18 +3,18 @@ apply from: TOMCAT_GRADLE tasks.findByPath("artifactoryPublish")?.enabled = false sonarRunner { - skipProject = true + skipProject = true } dependencies { - compile project(':spring-session-data-redis'), - "org.springframework:spring-web:$springVersion", - "redis.embedded:embedded-redis:0.2", - jstlDependencies + compile project(':spring-session-data-redis'), + "org.springframework:spring-web:$springVersion", + "redis.embedded:embedded-redis:0.2", + jstlDependencies - providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" + providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" - testCompile 'junit:junit:4.11' + testCompile 'junit:junit:4.11' - integrationTestCompile gebDependencies + integrationTestCompile gebDependencies } \ No newline at end of file diff --git a/samples/httpsession/src/integration-test/groovy/sample/AttributeTests.groovy b/samples/httpsession/src/integration-test/groovy/sample/AttributeTests.groovy index 37febcb8..a5f85c86 100644 --- a/samples/httpsession/src/integration-test/groovy/sample/AttributeTests.groovy +++ b/samples/httpsession/src/integration-test/groovy/sample/AttributeTests.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 geb.spock.* @@ -12,19 +27,19 @@ import pages.* */ @Stepwise class AttributeTests extends GebReportingSpec { - def 'first visit no attributes'() { - when: - to HomePage - then: - attributes.empty - } + def 'first visit no attributes'() { + when: + to HomePage + then: + attributes.empty + } - def 'create attribute'() { - when: - createAttribute('a','b') - then: - attributes.size() == 1 - attributes[0].name == 'a' - attributes[0].value == 'b' - } + def 'create attribute'() { + when: + createAttribute('a','b') + then: + attributes.size() == 1 + attributes[0].name == 'a' + attributes[0].value == 'b' + } } \ No newline at end of file diff --git a/samples/httpsession/src/integration-test/groovy/sample/pages/HomePage.groovy b/samples/httpsession/src/integration-test/groovy/sample/pages/HomePage.groovy index ab5c4590..e087b5c4 100644 --- a/samples/httpsession/src/integration-test/groovy/sample/pages/HomePage.groovy +++ b/samples/httpsession/src/integration-test/groovy/sample/pages/HomePage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.* @@ -8,23 +23,23 @@ import geb.* * @author Rob Winch */ class HomePage extends Page { - static url = '' - static at = { assert driver.title == 'Session Attributes'; true} - static content = { - form { $('form') } - submit { $('input[type=submit]') } - createAttribute(required:false) { name, value -> - form.attributeName = name - form.attributeValue = value - submit.click(HomePage) - } - attributes { moduleList AttributeRow, $("table tr").tail() } - } + static url = '' + static at = { assert driver.title == 'Session Attributes'; true} + static content = { + form { $('form') } + submit { $('input[type=submit]') } + createAttribute(required:false) { name, value -> + form.attributeName = name + form.attributeValue = value + submit.click(HomePage) + } + attributes { moduleList AttributeRow, $("table tr").tail() } + } } class AttributeRow extends Module { - static content = { - cell { $("td", it) } - name { cell(0).text() } - value { cell(1).text() } - } + static content = { + cell { $("td", it) } + name { cell(0).text() } + value { cell(1).text() } + } } diff --git a/samples/httpsession/src/main/java/sample/Config.java b/samples/httpsession/src/main/java/sample/Config.java index 35769400..7db58d9d 100644 --- a/samples/httpsession/src/main/java/sample/Config.java +++ b/samples/httpsession/src/main/java/sample/Config.java @@ -1,17 +1,33 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.jedis.*; import org.springframework.session.data.redis.config.annotation.web.http.*; +// tag::class[] @Import(EmbeddedRedisConfiguration.class) // <1> @EnableRedisHttpSession // <2> public class Config { - @Bean - public JedisConnectionFactory connectionFactory() { - return new JedisConnectionFactory(); // <3> - } + @Bean + public JedisConnectionFactory connectionFactory() { + return new JedisConnectionFactory(); // <3> + } } +// end::class[] \ No newline at end of file diff --git a/samples/httpsession/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/httpsession/src/main/java/sample/EmbeddedRedisConfiguration.java index f1341caa..c50d54c1 100644 --- a/samples/httpsession/src/main/java/sample/EmbeddedRedisConfiguration.java +++ b/samples/httpsession/src/main/java/sample/EmbeddedRedisConfiguration.java @@ -1,6 +1,5 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -14,6 +13,8 @@ package sample; * License for the specific language governing permissions and limitations under * the License. */ +package sample; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -36,34 +37,34 @@ import redis.embedded.RedisServer; @Configuration public class EmbeddedRedisConfiguration { - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public static RedisServerBean redisServer() { + return new RedisServerBean(); + } - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(Protocol.DEFAULT_PORT); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(Protocol.DEFAULT_PORT); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } } \ No newline at end of file diff --git a/samples/httpsession/src/main/java/sample/Initializer.java b/samples/httpsession/src/main/java/sample/Initializer.java index 1260b3e7..7512f33c 100644 --- a/samples/httpsession/src/main/java/sample/Initializer.java +++ b/samples/httpsession/src/main/java/sample/Initializer.java @@ -1,11 +1,28 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; +// tag::class[] public class Initializer - extends AbstractHttpSessionApplicationInitializer { // <1> + extends AbstractHttpSessionApplicationInitializer { // <1> - public Initializer() { - super(Config.class); // <2> - } + public Initializer() { + super(Config.class); // <2> + } } +// end::class[] \ No newline at end of file diff --git a/samples/httpsession/src/main/java/sample/SessionServlet.java b/samples/httpsession/src/main/java/sample/SessionServlet.java index 2330d645..f0a8d6dc 100644 --- a/samples/httpsession/src/main/java/sample/SessionServlet.java +++ b/samples/httpsession/src/main/java/sample/SessionServlet.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 javax.servlet.*; @@ -5,16 +20,18 @@ import javax.servlet.annotation.*; import javax.servlet.http.*; import java.io.IOException; +// 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() + "/"); - } + @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; + private static final long serialVersionUID = 2878267318695777395L; } +// tag::end[] \ No newline at end of file diff --git a/samples/httpsession/src/main/webapp/index.jsp b/samples/httpsession/src/main/webapp/index.jsp index 75c690d1..3a5564c0 100644 --- a/samples/httpsession/src/main/webapp/index.jsp +++ b/samples/httpsession/src/main/webapp/index.jsp @@ -2,47 +2,47 @@ - Session Attributes - - + Session Attributes + + -
-

Description

-

This application demonstrates how to use a Redis instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.

+
+

Description

+

This application demonstrates how to use a Redis instance to back your session. Notice that there is no JSESSIONID cookie. We are also able to customize the way of identifying what the requested session id is.

-

Try it

+

Try it

-
- - - - - -
+
+ + + + + +
-
+
- - - - - - - - - - - - - - - -
Attribute NameAttribute Value
-
+ + + + + + + + + + + + + + + +
Attribute NameAttribute Value
+
diff --git a/samples/rest/build.gradle b/samples/rest/build.gradle index a48fbfbb..b8942402 100644 --- a/samples/rest/build.gradle +++ b/samples/rest/build.gradle @@ -3,22 +3,22 @@ apply from: TOMCAT_GRADLE tasks.findByPath("artifactoryPublish")?.enabled = false sonarRunner { - skipProject = true + skipProject = true } dependencies { - compile project(':spring-session-data-redis'), - "org.springframework:spring-webmvc:$springVersion", - "redis.embedded:embedded-redis:0.2", - "org.springframework.security:spring-security-config:$springSecurityVersion", - "org.springframework.security:spring-security-web:$springSecurityVersion", - "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion", - jstlDependencies + compile project(':spring-session-data-redis'), + "org.springframework:spring-webmvc:$springVersion", + "redis.embedded:embedded-redis:0.2", + "org.springframework.security:spring-security-config:$springSecurityVersion", + "org.springframework.security:spring-security-web:$springSecurityVersion", + "com.fasterxml.jackson.core:jackson-databind:$jacksonVersion", + jstlDependencies - providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" + providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" - testCompile 'junit:junit:4.11' + testCompile 'junit:junit:4.11' - integrationTestCompile spockDependencies, - 'org.codehaus.groovy.modules.http-builder:http-builder:0.7' + integrationTestCompile spockDependencies, + 'org.codehaus.groovy.modules.http-builder:http-builder:0.7' } \ No newline at end of file diff --git a/samples/rest/src/integration-test/groovy/sample/RestTests.groovy b/samples/rest/src/integration-test/groovy/sample/RestTests.groovy index 5fdaabac..0510c0d6 100644 --- a/samples/rest/src/integration-test/groovy/sample/RestTests.groovy +++ b/samples/rest/src/integration-test/groovy/sample/RestTests.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 groovyx.net.http.HttpResponseException diff --git a/samples/rest/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/rest/src/main/java/sample/EmbeddedRedisConfiguration.java index f44603eb..956ce5fc 100644 --- a/samples/rest/src/main/java/sample/EmbeddedRedisConfiguration.java +++ b/samples/rest/src/main/java/sample/EmbeddedRedisConfiguration.java @@ -1,19 +1,19 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 + * 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 + * 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. + * 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.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -36,35 +36,33 @@ import redis.embedded.RedisServer; @Configuration public class EmbeddedRedisConfiguration { - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public static RedisServerBean redisServer() { + return new RedisServerBean(); + } - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(Protocol.DEFAULT_PORT); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(Protocol.DEFAULT_PORT); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } } \ No newline at end of file diff --git a/samples/rest/src/main/java/sample/HttpSessionConfig.java b/samples/rest/src/main/java/sample/HttpSessionConfig.java index 15181fc3..cd4de91c 100644 --- a/samples/rest/src/main/java/sample/HttpSessionConfig.java +++ b/samples/rest/src/main/java/sample/HttpSessionConfig.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.context.annotation.Bean; @@ -8,18 +23,20 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR import org.springframework.session.web.http.HeaderHttpSessionStrategy; import org.springframework.session.web.http.HttpSessionStrategy; +// tag::class[] @Configuration @Import(EmbeddedRedisConfiguration.class) // <1> @EnableRedisHttpSession // <2> public class HttpSessionConfig { - @Bean - public JedisConnectionFactory connectionFactory() { - return new JedisConnectionFactory(); // <3> - } + @Bean + public JedisConnectionFactory connectionFactory() { + return new JedisConnectionFactory(); // <3> + } - @Bean - public HttpSessionStrategy httpSessionStrategy() { - return new HeaderHttpSessionStrategy(); // <4> - } + @Bean + public HttpSessionStrategy httpSessionStrategy() { + return new HeaderHttpSessionStrategy(); // <4> + } } +// end::class[] \ No newline at end of file diff --git a/samples/rest/src/main/java/sample/Initializer.java b/samples/rest/src/main/java/sample/Initializer.java index d9b12bda..f8627a7f 100644 --- a/samples/rest/src/main/java/sample/Initializer.java +++ b/samples/rest/src/main/java/sample/Initializer.java @@ -1,7 +1,24 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; +// tag::class[] public class Initializer extends AbstractHttpSessionApplicationInitializer { } +// end::class[] \ No newline at end of file diff --git a/samples/rest/src/main/java/sample/SecurityConfig.java b/samples/rest/src/main/java/sample/SecurityConfig.java index afb5dd88..bca7a442 100644 --- a/samples/rest/src/main/java/sample/SecurityConfig.java +++ b/samples/rest/src/main/java/sample/SecurityConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -28,19 +28,19 @@ import org.springframework.security.config.annotation.web.configuration.WebSecur @EnableWebSecurity public class SecurityConfig extends WebSecurityConfigurerAdapter { - @Override - protected void configure(HttpSecurity http) throws Exception { - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .httpBasic(); - } + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .httpBasic(); + } - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth - .inMemoryAuthentication() - .withUser("user").password("password").roles("USER"); - } + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER"); + } } diff --git a/samples/rest/src/main/java/sample/SecurityInitializer.java b/samples/rest/src/main/java/sample/SecurityInitializer.java index 0a8c47f2..754f3b44 100644 --- a/samples/rest/src/main/java/sample/SecurityInitializer.java +++ b/samples/rest/src/main/java/sample/SecurityInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -21,6 +21,6 @@ import org.springframework.security.web.context.AbstractSecurityWebApplicationIn * @author Rob Winch */ public class SecurityInitializer extends - AbstractSecurityWebApplicationInitializer { + AbstractSecurityWebApplicationInitializer { } \ No newline at end of file diff --git a/samples/rest/src/main/java/sample/mvc/MvcConfig.java b/samples/rest/src/main/java/sample/mvc/MvcConfig.java index 619e908a..b1d60737 100644 --- a/samples/rest/src/main/java/sample/mvc/MvcConfig.java +++ b/samples/rest/src/main/java/sample/mvc/MvcConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 diff --git a/samples/rest/src/main/java/sample/mvc/MvcInitializer.java b/samples/rest/src/main/java/sample/mvc/MvcInitializer.java index a711da69..6c88c72c 100644 --- a/samples/rest/src/main/java/sample/mvc/MvcInitializer.java +++ b/samples/rest/src/main/java/sample/mvc/MvcInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -23,20 +23,20 @@ import sample.SecurityConfig; * @author Rob Winch */ public class MvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { - // tag::config[] - @Override - protected Class[] getRootConfigClasses() { - return new Class[] {SecurityConfig.class, HttpSessionConfig.class}; - } - // end::config[] + // tag::config[] + @Override + protected Class[] getRootConfigClasses() { + return new Class[] {SecurityConfig.class, HttpSessionConfig.class}; + } + // end::config[] - @Override - protected Class[] getServletConfigClasses() { - return new Class[] { MvcConfig.class }; - } + @Override + protected Class[] getServletConfigClasses() { + return new Class[] { MvcConfig.class }; + } - @Override - protected String[] getServletMappings() { - return new String[] { "/" }; - } + @Override + protected String[] getServletMappings() { + return new String[] { "/" }; + } } diff --git a/samples/rest/src/main/java/sample/mvc/RestDemoController.java b/samples/rest/src/main/java/sample/mvc/RestDemoController.java index 32428a5e..08ca0585 100644 --- a/samples/rest/src/main/java/sample/mvc/RestDemoController.java +++ b/samples/rest/src/main/java/sample/mvc/RestDemoController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -15,33 +15,33 @@ */ package sample.mvc; -import org.springframework.http.HttpStatus; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.bind.annotation.ResponseStatus; -import org.springframework.web.bind.annotation.RestController; - -import javax.servlet.http.HttpSession; import java.security.Principal; import java.util.HashMap; import java.util.Map; +import javax.servlet.http.HttpSession; + +import org.springframework.http.HttpStatus; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestController; + /** * @author Rob Winch */ @RestController public class RestDemoController { - @RequestMapping(value="/",produces = "application/json") - public Map helloUser(Principal principal) { - HashMap result = new HashMap(); - result.put("username", principal.getName()); - return result; - } + @RequestMapping(value="/",produces = "application/json") + public Map helloUser(Principal principal) { + HashMap result = new HashMap(); + result.put("username", principal.getName()); + return result; + } - @RequestMapping("/logout") - @ResponseStatus(HttpStatus.NO_CONTENT) - public void logout(HttpSession session) { - session.invalidate(); - } + @RequestMapping("/logout") + @ResponseStatus(HttpStatus.NO_CONTENT) + public void logout(HttpSession session) { + session.invalidate(); + } } diff --git a/samples/security/build.gradle b/samples/security/build.gradle index aa2b289e..e8646576 100644 --- a/samples/security/build.gradle +++ b/samples/security/build.gradle @@ -3,20 +3,20 @@ apply from: TOMCAT_GRADLE tasks.findByPath("artifactoryPublish")?.enabled = false sonarRunner { - skipProject = true + skipProject = true } dependencies { - compile project(':spring-session-data-redis'), - "org.springframework:spring-web:$springVersion", - "redis.embedded:embedded-redis:0.2", - "org.springframework.security:spring-security-config:$springSecurityVersion", - "org.springframework.security:spring-security-web:$springSecurityVersion", - jstlDependencies + compile project(':spring-session-data-redis'), + "org.springframework:spring-web:$springVersion", + "redis.embedded:embedded-redis:0.2", + "org.springframework.security:spring-security-config:$springSecurityVersion", + "org.springframework.security:spring-security-web:$springSecurityVersion", + jstlDependencies - providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" + providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" - testCompile 'junit:junit:4.11' + testCompile 'junit:junit:4.11' - integrationTestCompile gebDependencies + integrationTestCompile gebDependencies } \ No newline at end of file diff --git a/samples/security/src/integration-test/groovy/sample/SecurityTests.groovy b/samples/security/src/integration-test/groovy/sample/SecurityTests.groovy index 61fdbc0e..5dd53f12 100644 --- a/samples/security/src/integration-test/groovy/sample/SecurityTests.groovy +++ b/samples/security/src/integration-test/groovy/sample/SecurityTests.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 geb.spock.GebReportingSpec @@ -14,37 +29,37 @@ import spock.lang.Stepwise @Stepwise class SecurityTests extends GebReportingSpec { - def 'Unauthenticated user sent to log in page'() { - when: 'unauthenticated user request protected page' - via HomePage - then: 'sent to the log in page' - at LoginPage - } + def 'Unauthenticated user sent to log in page'() { + when: 'unauthenticated user request protected page' + via HomePage + then: 'sent to the log in page' + at LoginPage + } - def 'Log in views home page'() { - when: 'log in successfully' - login() - then: 'sent to original page' - at HomePage - and: 'the username is displayed' - username == 'user' - 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 in views home page'() { + when: 'log in successfully' + login() + then: 'sent to original page' + at HomePage + and: 'the username is displayed' + username == 'user' + 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 LoginPage - } + def 'Log out success'() { + when: + logout() + then: + at LoginPage + } - def 'Logged out user sent to log in page'() { - when: 'logged out user request protected page' - via HomePage - then: 'sent to the log in page' - at LoginPage - } + def 'Logged out user sent to log in page'() { + when: 'logged out user request protected page' + via HomePage + then: 'sent to the log in page' + at LoginPage + } } \ No newline at end of file diff --git a/samples/security/src/integration-test/groovy/sample/pages/HomePage.groovy b/samples/security/src/integration-test/groovy/sample/pages/HomePage.groovy index 53cd3c5b..45634e66 100644 --- a/samples/security/src/integration-test/groovy/sample/pages/HomePage.groovy +++ b/samples/security/src/integration-test/groovy/sample/pages/HomePage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.Page @@ -8,10 +23,10 @@ import geb.Page * @author Rob Winch */ class HomePage extends Page { - static url = '' - static at = { assert driver.title == 'Secured Content'; true} - static content = { - username { $('#un').text() } - logout(to:LoginPage) { $('input[type=submit]').click() } - } + static url = '' + static at = { assert driver.title == 'Secured Content'; true} + static content = { + username { $('#un').text() } + logout(to:LoginPage) { $('input[type=submit]').click() } + } } diff --git a/samples/security/src/integration-test/groovy/sample/pages/LoginPage.groovy b/samples/security/src/integration-test/groovy/sample/pages/LoginPage.groovy index 758b84d4..08c7fb27 100644 --- a/samples/security/src/integration-test/groovy/sample/pages/LoginPage.groovy +++ b/samples/security/src/integration-test/groovy/sample/pages/LoginPage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.Page @@ -8,15 +23,15 @@ import geb.Page * @author Rob Winch */ class LoginPage extends Page { - static url = '/login' - static at = { assert driver.title == 'Login Page'; true} - static content = { - form { $('form') } - submit { $('input[type=submit]') } - login(required:false) { user='user', pass='password' -> - form.username = user - form.password = pass - submit.click(HomePage) - } - } + static url = '/login' + static at = { assert driver.title == 'Login Page'; true} + static content = { + form { $('form') } + submit { $('input[type=submit]') } + login(required:false) { user='user', pass='password' -> + form.username = user + form.password = pass + submit.click(HomePage) + } + } } diff --git a/samples/security/src/main/java/sample/Config.java b/samples/security/src/main/java/sample/Config.java index 720ea301..3b749f11 100644 --- a/samples/security/src/main/java/sample/Config.java +++ b/samples/security/src/main/java/sample/Config.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.context.annotation.Bean; @@ -6,13 +21,15 @@ import org.springframework.context.annotation.Import; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; +// tag::class[] @Configuration @Import(EmbeddedRedisConfiguration.class) // <1> @EnableRedisHttpSession // <2> public class Config { - @Bean - public JedisConnectionFactory connectionFactory() { - return new JedisConnectionFactory(); // <3> - } + @Bean + public JedisConnectionFactory connectionFactory() { + return new JedisConnectionFactory(); // <3> + } } +// end::class[] \ No newline at end of file diff --git a/samples/security/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/security/src/main/java/sample/EmbeddedRedisConfiguration.java index f44603eb..a8083ea3 100644 --- a/samples/security/src/main/java/sample/EmbeddedRedisConfiguration.java +++ b/samples/security/src/main/java/sample/EmbeddedRedisConfiguration.java @@ -1,6 +1,5 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -14,6 +13,8 @@ package sample; * License for the specific language governing permissions and limitations under * the License. */ +package sample; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -36,35 +37,33 @@ import redis.embedded.RedisServer; @Configuration public class EmbeddedRedisConfiguration { - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public static RedisServerBean redisServer() { + return new RedisServerBean(); + } - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(Protocol.DEFAULT_PORT); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(Protocol.DEFAULT_PORT); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } } \ No newline at end of file diff --git a/samples/security/src/main/java/sample/Initializer.java b/samples/security/src/main/java/sample/Initializer.java index d9b12bda..f8627a7f 100644 --- a/samples/security/src/main/java/sample/Initializer.java +++ b/samples/security/src/main/java/sample/Initializer.java @@ -1,7 +1,24 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; +// tag::class[] public class Initializer extends AbstractHttpSessionApplicationInitializer { } +// end::class[] \ No newline at end of file diff --git a/samples/security/src/main/java/sample/SecurityConfig.java b/samples/security/src/main/java/sample/SecurityConfig.java index bb5f9acd..e6c5da8c 100644 --- a/samples/security/src/main/java/sample/SecurityConfig.java +++ b/samples/security/src/main/java/sample/SecurityConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -25,10 +25,10 @@ import org.springframework.security.config.annotation.web.configuration.EnableWe @EnableWebSecurity public class SecurityConfig { - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { - auth - .inMemoryAuthentication() - .withUser("user").password("password").roles("USER"); - } + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception { + auth + .inMemoryAuthentication() + .withUser("user").password("password").roles("USER"); + } } diff --git a/samples/security/src/main/java/sample/SecurityInitializer.java b/samples/security/src/main/java/sample/SecurityInitializer.java index 196697c7..7cb5982d 100644 --- a/samples/security/src/main/java/sample/SecurityInitializer.java +++ b/samples/security/src/main/java/sample/SecurityInitializer.java @@ -1,11 +1,28 @@ +/* + * Copyright 2002-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 + * + * 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.springframework.security.web.context.AbstractSecurityWebApplicationInitializer; +// tag::class[] public class SecurityInitializer extends - AbstractSecurityWebApplicationInitializer { + AbstractSecurityWebApplicationInitializer { - public SecurityInitializer() { - super(SecurityConfig.class, Config.class); - } -} \ No newline at end of file + public SecurityInitializer() { + super(SecurityConfig.class, Config.class); + } +} +// end::class[] \ No newline at end of file diff --git a/samples/security/src/main/java/sample/SessionServlet.java b/samples/security/src/main/java/sample/SessionServlet.java index c05bb437..2d56ce48 100644 --- a/samples/security/src/main/java/sample/SessionServlet.java +++ b/samples/security/src/main/java/sample/SessionServlet.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 javax.servlet.ServletException; @@ -10,13 +25,13 @@ import java.io.IOException; @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() + "/"); - } + @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; + private static final long serialVersionUID = 2878267318695777395L; } diff --git a/samples/security/src/main/webapp/index.jsp b/samples/security/src/main/webapp/index.jsp index 614ba800..11d471e0 100644 --- a/samples/security/src/main/webapp/index.jsp +++ b/samples/security/src/main/webapp/index.jsp @@ -2,31 +2,31 @@ - Secured Content - - + Secured Content + + -
-

Description

-

This demonstrates how Spring Session can be combined with Spring Security. The important thing to ensure is that Spring Session's Filter is included before Spring Security's Filter.

+
+

Description

+

This demonstrates how Spring Session can be combined with Spring Security. The important thing to ensure is that Spring Session's Filter is included before Spring Security's Filter.

-

Logged in as

+

Logged in as

-

You are currently logged in as .

+

You are currently logged in as .

- -
- - -
-
+ +
+ + +
+
diff --git a/samples/users/build.gradle b/samples/users/build.gradle index 8e1d8e5f..2f002180 100644 --- a/samples/users/build.gradle +++ b/samples/users/build.gradle @@ -3,18 +3,18 @@ apply from: TOMCAT_GRADLE tasks.findByPath("artifactoryPublish")?.enabled = false sonarRunner { - skipProject = true + skipProject = true } dependencies { - compile project(':spring-session-data-redis'), - "org.springframework:spring-web:$springVersion", - "redis.embedded:embedded-redis:0.2", - jstlDependencies + compile project(':spring-session-data-redis'), + "org.springframework:spring-web:$springVersion", + "redis.embedded:embedded-redis:0.2", + jstlDependencies - providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" + providedCompile "javax.servlet:javax.servlet-api:$servletApiVersion" - testCompile 'junit:junit:4.11' + testCompile 'junit:junit:4.11' - integrationTestCompile gebDependencies + integrationTestCompile gebDependencies } \ No newline at end of file diff --git a/samples/users/src/integration-test/groovy/sample/UserTests.groovy b/samples/users/src/integration-test/groovy/sample/UserTests.groovy index cdfdc579..659704dc 100644 --- a/samples/users/src/integration-test/groovy/sample/UserTests.groovy +++ b/samples/users/src/integration-test/groovy/sample/UserTests.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 geb.spock.* @@ -13,112 +28,112 @@ import pages.* */ @Stepwise class UserTests extends GebReportingSpec { - def 'first visit not authenticated'() { - when: - to HomePage - then: - form - !username - } + def 'first visit not authenticated'() { + when: + to HomePage + then: + form + !username + } - def 'invalid login'() { - setup: - def user = 'rob' - when: - login(user, user+'invalid') - then: - !username - error == 'Invalid username / password. Please ensure the username is the same as the password.' - } + def 'invalid login'() { + setup: + def user = 'rob' + when: + login(user, user+'invalid') + then: + !username + error == 'Invalid username / password. Please ensure the username is the same as the password.' + } - def 'empty username'() { - setup: - def user = '' - when: - login(user, user) - then: - !username - error == 'Invalid username / password. Please ensure the username is the same as the password.' - } + def 'empty username'() { + setup: + def user = '' + when: + login(user, user) + then: + !username + error == 'Invalid username / password. Please ensure the username is the same as the password.' + } - def 'login single user'() { - setup: - def user = 'rob' - when: - login(user, user) - then: - username == user - } + def 'login single user'() { + setup: + def user = 'rob' + when: + login(user, user) + then: + username == user + } - def 'add account'() { - when: - addAccount.click(HomePage) - then: - form - !username - } + def 'add account'() { + when: + addAccount.click(HomePage) + then: + form + !username + } - def 'log in second user'() { - setup: - def user = 'luke' - when: - login(user, user) - then: - username == user - } + def 'log in second user'() { + setup: + def user = 'luke' + when: + login(user, user) + then: + username == user + } - def 'following links keeps new session'() { - when: - navLink.click(LinkPage) - then: - username == 'luke' - } + def 'following links keeps new session'() { + when: + navLink.click(LinkPage) + then: + username == 'luke' + } - def 'switch account rob'() { - setup: - def user = 'rob' - when: - switchAccount(user) - then: - username == user - } + def 'switch account rob'() { + setup: + def user = 'rob' + when: + switchAccount(user) + then: + username == user + } - def 'following links keeps original session'() { - when: - navLink.click(LinkPage) - then: - username == 'rob' - } + def 'following links keeps original session'() { + when: + navLink.click(LinkPage) + then: + username == 'rob' + } - def 'switch account luke'() { - setup: - def user = 'luke' - when: - switchAccount(user) - then: - username == user - } + def 'switch account luke'() { + setup: + def user = 'luke' + when: + switchAccount(user) + then: + username == user + } - def 'logout luke'() { - when: - logout.click(HomePage) - then: - !username - } + def 'logout luke'() { + when: + logout.click(HomePage) + then: + !username + } - def 'switch back rob'() { - setup: - def user = 'rob' - when: - switchAccount(user) - then: - username == user - } + def 'switch back rob'() { + setup: + def user = 'rob' + when: + switchAccount(user) + then: + username == user + } - def 'logout rob'() { - when: - logout.click(HomePage) - then: - !username - } + def 'logout rob'() { + when: + logout.click(HomePage) + then: + !username + } } \ No newline at end of file diff --git a/samples/users/src/integration-test/groovy/sample/pages/HomePage.groovy b/samples/users/src/integration-test/groovy/sample/pages/HomePage.groovy index eaf94c08..92351d02 100644 --- a/samples/users/src/integration-test/groovy/sample/pages/HomePage.groovy +++ b/samples/users/src/integration-test/groovy/sample/pages/HomePage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.* @@ -8,24 +23,24 @@ import geb.* * @author Rob Winch */ class HomePage extends Page { - static url = '' - static at = { assert driver.title == 'Demonstrates Multi User Log In'; true} - static content = { - navLink { $('#navLink') } - error { $('#error').text() } - form { $('form') } - username(required:false) { $('#un').text() } - logout(required:false) { $('#logout') } - addAccount(required:false) { $('#addAccount') } - submit { $('input[type=submit]') } - login(required:false) { user, pass -> - form.username = user - form.password = pass - submit.click(HomePage) - } - switchAccount{ un -> - $("#switchAccount${un}").click(HomePage) - } - attributes { moduleList AttributeRow, $("table tr").tail() } - } + static url = '' + static at = { assert driver.title == 'Demonstrates Multi User Log In'; true} + static content = { + navLink { $('#navLink') } + error { $('#error').text() } + form { $('form') } + username(required:false) { $('#un').text() } + logout(required:false) { $('#logout') } + addAccount(required:false) { $('#addAccount') } + submit { $('input[type=submit]') } + login(required:false) { user, pass -> + form.username = user + form.password = pass + submit.click(HomePage) + } + switchAccount{ un -> + $("#switchAccount${un}").click(HomePage) + } + attributes { moduleList AttributeRow, $("table tr").tail() } + } } diff --git a/samples/users/src/integration-test/groovy/sample/pages/LinkPage.groovy b/samples/users/src/integration-test/groovy/sample/pages/LinkPage.groovy index f72baf48..0d87bace 100644 --- a/samples/users/src/integration-test/groovy/sample/pages/LinkPage.groovy +++ b/samples/users/src/integration-test/groovy/sample/pages/LinkPage.groovy @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.* @@ -8,13 +23,13 @@ import geb.* * @author Rob Winch */ class LinkPage extends Page { - static url = '' - static at = { assert driver.title == 'Linked Page'; true} - static content = { - form { $('#navLinks') } - username(required:false) { $('#un').text() } - switchAccount{ un -> - $("#switchAccount${un}").click(HomePage) - } - } + static url = '' + static at = { assert driver.title == 'Linked Page'; true} + static content = { + form { $('#navLinks') } + username(required:false) { $('#un').text() } + switchAccount{ un -> + $("#switchAccount${un}").click(HomePage) + } + } } diff --git a/samples/users/src/main/java/sample/Account.java b/samples/users/src/main/java/sample/Account.java index d24fe999..b0348f5d 100644 --- a/samples/users/src/main/java/sample/Account.java +++ b/samples/users/src/main/java/sample/Account.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -16,29 +16,29 @@ package sample; public class Account { - private String username; + private String username; - private String logoutUrl; + private String logoutUrl; - private String switchAccountUrl; + private String switchAccountUrl; - public Account(String username, String logoutUrl, String switchAccountUrl) { - super(); - this.username = username; - this.logoutUrl = logoutUrl; - this.switchAccountUrl = switchAccountUrl; - } + public Account(String username, String logoutUrl, String switchAccountUrl) { + super(); + this.username = username; + this.logoutUrl = logoutUrl; + this.switchAccountUrl = switchAccountUrl; + } - public String getUsername() { - return username; - } + public String getUsername() { + return username; + } - public String getLogoutUrl() { - return logoutUrl; - } + public String getLogoutUrl() { + return logoutUrl; + } - public String getSwitchAccountUrl() { - return switchAccountUrl; - } + public String getSwitchAccountUrl() { + return switchAccountUrl; + } } diff --git a/samples/users/src/main/java/sample/Config.java b/samples/users/src/main/java/sample/Config.java index 8bc170b4..8a0a95ef 100644 --- a/samples/users/src/main/java/sample/Config.java +++ b/samples/users/src/main/java/sample/Config.java @@ -1,6 +1,5 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -14,6 +13,7 @@ package sample; * License for the specific language governing permissions and limitations under * the License. */ +package sample; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -24,13 +24,15 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR /** * @author Rob Winch */ +// tag::class[] @Import(EmbeddedRedisConfiguration.class) @Configuration @EnableRedisHttpSession public class Config { - @Bean - public JedisConnectionFactory connectionFactory() { - return new JedisConnectionFactory(); - } + @Bean + public JedisConnectionFactory connectionFactory() { + return new JedisConnectionFactory(); + } } +// end::class[] \ No newline at end of file diff --git a/samples/users/src/main/java/sample/EmbeddedRedisConfiguration.java b/samples/users/src/main/java/sample/EmbeddedRedisConfiguration.java index b1db4048..b0a344f8 100644 --- a/samples/users/src/main/java/sample/EmbeddedRedisConfiguration.java +++ b/samples/users/src/main/java/sample/EmbeddedRedisConfiguration.java @@ -1,6 +1,5 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -14,6 +13,8 @@ package sample; * License for the specific language governing permissions and limitations under * the License. */ +package sample; + import org.springframework.beans.BeansException; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; @@ -36,36 +37,34 @@ import redis.embedded.RedisServer; @Configuration public class EmbeddedRedisConfiguration { - @Bean - public RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public RedisServerBean redisServer() { + return new RedisServerBean(); + } - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(Protocol.DEFAULT_PORT); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(Protocol.DEFAULT_PORT); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } } diff --git a/samples/users/src/main/java/sample/Initializer.java b/samples/users/src/main/java/sample/Initializer.java index 9d93ebb5..8bc0289d 100644 --- a/samples/users/src/main/java/sample/Initializer.java +++ b/samples/users/src/main/java/sample/Initializer.java @@ -1,6 +1,5 @@ -package sample; /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -14,7 +13,7 @@ package sample; * License for the specific language governing permissions and limitations under * the License. */ - +package sample; import javax.servlet.ServletContext; @@ -25,12 +24,12 @@ import org.springframework.session.web.context.AbstractHttpSessionApplicationIni */ public class Initializer extends AbstractHttpSessionApplicationInitializer { - public Initializer() { - super(Config.class); - } + public Initializer() { + super(Config.class); + } - @Override - protected void afterSessionRepositoryFilter(ServletContext servletContext) { - appendFilters(servletContext, new UserAccountsFilter()); - } + @Override + protected void afterSessionRepositoryFilter(ServletContext servletContext) { + appendFilters(servletContext, new UserAccountsFilter()); + } } \ No newline at end of file diff --git a/samples/users/src/main/java/sample/LoginServlet.java b/samples/users/src/main/java/sample/LoginServlet.java index c6e9cd7d..856a19e7 100644 --- a/samples/users/src/main/java/sample/LoginServlet.java +++ b/samples/users/src/main/java/sample/LoginServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -26,21 +26,21 @@ import javax.servlet.http.HttpServletResponse; @WebServlet("/login") public class LoginServlet extends HttpServlet { - @Override - protected void doPost(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - String username = req.getParameter("username"); - String password = req.getParameter("password"); + @Override + protected void doPost(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + String username = req.getParameter("username"); + String password = req.getParameter("password"); - if(username != null && !"".equals(username) && username.equals(password)) { - req.getSession().setAttribute("username", username); - String url = resp.encodeRedirectURL(req.getContextPath() + "/"); - resp.sendRedirect(url); - } else { - String url = resp.encodeRedirectURL(req.getContextPath() + "/?error"); - resp.sendRedirect(url); - } - } + if(username != null && !"".equals(username) && username.equals(password)) { + req.getSession().setAttribute("username", username); + String url = resp.encodeRedirectURL(req.getContextPath() + "/"); + resp.sendRedirect(url); + } else { + String url = resp.encodeRedirectURL(req.getContextPath() + "/?error"); + resp.sendRedirect(url); + } + } - private static final long serialVersionUID = -8157634860354132501L; + private static final long serialVersionUID = -8157634860354132501L; } \ No newline at end of file diff --git a/samples/users/src/main/java/sample/LogoutServlet.java b/samples/users/src/main/java/sample/LogoutServlet.java index d972c6fb..3f91ae46 100644 --- a/samples/users/src/main/java/sample/LogoutServlet.java +++ b/samples/users/src/main/java/sample/LogoutServlet.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -27,16 +27,16 @@ import javax.servlet.http.HttpSession; @WebServlet("/logout") public class LogoutServlet extends HttpServlet { - @Override - protected void doGet(HttpServletRequest req, HttpServletResponse resp) - throws ServletException, IOException { - HttpSession session = req.getSession(false); - if(session != null) { - session.invalidate(); - } - String url = resp.encodeRedirectURL(req.getContextPath() + "/"); - resp.sendRedirect(url); - } + @Override + protected void doGet(HttpServletRequest req, HttpServletResponse resp) + throws ServletException, IOException { + HttpSession session = req.getSession(false); + if(session != null) { + session.invalidate(); + } + String url = resp.encodeRedirectURL(req.getContextPath() + "/"); + resp.sendRedirect(url); + } - private static final long serialVersionUID = 4061762524521437433L; + private static final long serialVersionUID = 4061762524521437433L; } \ No newline at end of file diff --git a/samples/users/src/main/java/sample/UserAccountsFilter.java b/samples/users/src/main/java/sample/UserAccountsFilter.java index 0a8d54f2..88721b1b 100644 --- a/samples/users/src/main/java/sample/UserAccountsFilter.java +++ b/samples/users/src/main/java/sample/UserAccountsFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -34,68 +34,68 @@ import org.springframework.session.web.http.HttpSessionManager; public class UserAccountsFilter implements Filter { - public void init(FilterConfig filterConfig) throws ServletException { - } + public void init(FilterConfig filterConfig) throws ServletException { + } - @SuppressWarnings("unchecked") - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - HttpServletRequest httpRequest = (HttpServletRequest) request; + @SuppressWarnings("unchecked") + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; - // tag::HttpSessionManager[] - HttpSessionManager sessionManager = - (HttpSessionManager) httpRequest.getAttribute(HttpSessionManager.class.getName()); - // end::HttpSessionManager[] - SessionRepository repo = - (SessionRepository) httpRequest.getAttribute(SessionRepository.class.getName()); + // tag::HttpSessionManager[] + HttpSessionManager sessionManager = + (HttpSessionManager) httpRequest.getAttribute(HttpSessionManager.class.getName()); + // end::HttpSessionManager[] + SessionRepository repo = + (SessionRepository) httpRequest.getAttribute(SessionRepository.class.getName()); - String currentSessionAlias = sessionManager.getCurrentSessionAlias(httpRequest); - Map sessionIds = sessionManager.getSessionIds(httpRequest); - String unauthenticatedAlias = null; + String currentSessionAlias = sessionManager.getCurrentSessionAlias(httpRequest); + Map sessionIds = sessionManager.getSessionIds(httpRequest); + String unauthenticatedAlias = null; - String contextPath = httpRequest.getContextPath(); - List accounts = new ArrayList(); - Account currentAccount = null; - for(Map.Entry entry : sessionIds.entrySet()) { - String alias = entry.getKey(); - String sessionId = entry.getValue(); + String contextPath = httpRequest.getContextPath(); + List accounts = new ArrayList(); + Account currentAccount = null; + for(Map.Entry entry : sessionIds.entrySet()) { + String alias = entry.getKey(); + String sessionId = entry.getValue(); - Session session = repo.getSession(sessionId); - if(session == null) { - continue; - } + Session session = repo.getSession(sessionId); + if(session == null) { + continue; + } - String username = session.getAttribute("username"); - if(username == null) { - unauthenticatedAlias = alias; - continue; - } + String username = session.getAttribute("username"); + if(username == null) { + unauthenticatedAlias = alias; + continue; + } - String logoutUrl = sessionManager.encodeURL("./logout", alias); - String switchAccountUrl = sessionManager.encodeURL("./", alias); - Account account = new Account(username, logoutUrl, switchAccountUrl); - if(currentSessionAlias.equals(alias)) { - currentAccount = account; - } else { - accounts.add(account); - } - } + String logoutUrl = sessionManager.encodeURL("./logout", alias); + String switchAccountUrl = sessionManager.encodeURL("./", alias); + Account account = new Account(username, logoutUrl, switchAccountUrl); + if(currentSessionAlias.equals(alias)) { + currentAccount = account; + } else { + accounts.add(account); + } + } - // tag::addAccountUrl[] - String addAlias = unauthenticatedAlias == null ? // <1> - sessionManager.getNewSessionAlias(httpRequest) : // <2> - unauthenticatedAlias; // <3> - String addAccountUrl = sessionManager.encodeURL(contextPath, addAlias); // <4> - // end::addAccountUrl[] + // tag::addAccountUrl[] + String addAlias = unauthenticatedAlias == null ? // <1> + sessionManager.getNewSessionAlias(httpRequest) : // <2> + unauthenticatedAlias; // <3> + String addAccountUrl = sessionManager.encodeURL(contextPath, addAlias); // <4> + // end::addAccountUrl[] - httpRequest.setAttribute("currentAccount", currentAccount); - httpRequest.setAttribute("addAccountUrl", addAccountUrl); - httpRequest.setAttribute("accounts", accounts); + httpRequest.setAttribute("currentAccount", currentAccount); + httpRequest.setAttribute("addAccountUrl", addAccountUrl); + httpRequest.setAttribute("accounts", accounts); - chain.doFilter(request, response); - } + chain.doFilter(request, response); + } - public void destroy() { - } + public void destroy() { + } } diff --git a/samples/websocket/build.gradle b/samples/websocket/build.gradle index ece21ea5..03492372 100644 --- a/samples/websocket/build.gradle +++ b/samples/websocket/build.gradle @@ -1,10 +1,10 @@ buildscript { - repositories { - mavenCentral() - } - dependencies { - classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion") - } + repositories { + mavenCentral() + } + dependencies { + classpath("org.springframework.boot:spring-boot-gradle-plugin:$springBootVersion") + } } apply plugin: 'spring-boot' @@ -17,23 +17,23 @@ tasks.findByPath("artifactoryPublish")?.enabled = false group = 'samples' dependencies { - compile project(':spring-session-data-redis'), - "org.springframework.boot:spring-boot-starter-web", - "org.springframework.boot:spring-boot-starter-data-jpa", - "org.springframework.boot:spring-boot-starter-thymeleaf", - "org.springframework.boot:spring-boot-starter-websocket", - "org.springframework:spring-websocket:${springVersion}", - "org.springframework.data:spring-data-jpa:1.7.0.RELEASE", - "redis.embedded:embedded-redis:0.2", - "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect", - "com.h2database:h2", - "org.springframework.security:spring-security-web:$springSecurityVersion", - "org.springframework.security:spring-security-config:$springSecurityVersion", - "org.springframework.security:spring-security-messaging:$springSecurityVersion", - "org.springframework.security:spring-security-data:$springSecurityVersion" + compile project(':spring-session-data-redis'), + "org.springframework.boot:spring-boot-starter-web", + "org.springframework.boot:spring-boot-starter-data-jpa", + "org.springframework.boot:spring-boot-starter-thymeleaf", + "org.springframework.boot:spring-boot-starter-websocket", + "org.springframework:spring-websocket:${springVersion}", + "org.springframework.data:spring-data-jpa:1.7.0.RELEASE", + "redis.embedded:embedded-redis:0.2", + "nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect", + "com.h2database:h2", + "org.springframework.security:spring-security-web:$springSecurityVersion", + "org.springframework.security:spring-security-config:$springSecurityVersion", + "org.springframework.security:spring-security-messaging:$springSecurityVersion", + "org.springframework.security:spring-security-data:$springSecurityVersion" - testCompile "org.springframework.boot:spring-boot-starter-test", - "org.springframework.security:spring-security-test:$springSecurityVersion" + testCompile "org.springframework.boot:spring-boot-starter-test", + "org.springframework.security:spring-security-test:$springSecurityVersion" } \ No newline at end of file diff --git a/samples/websocket/src/main/java/sample/Application.java b/samples/websocket/src/main/java/sample/Application.java index 8bf6cf63..7646ee50 100644 --- a/samples/websocket/src/main/java/sample/Application.java +++ b/samples/websocket/src/main/java/sample/Application.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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 @@ -28,7 +28,7 @@ import org.springframework.context.annotation.Configuration; @EnableAutoConfiguration public class Application { - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } } diff --git a/samples/websocket/src/main/java/sample/config/DataSourceConfig.java b/samples/websocket/src/main/java/sample/config/DataSourceConfig.java index c4eaff9f..dc09be9d 100644 --- a/samples/websocket/src/main/java/sample/config/DataSourceConfig.java +++ b/samples/websocket/src/main/java/sample/config/DataSourceConfig.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.config; import javax.sql.DataSource; @@ -11,14 +26,14 @@ import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; @Configuration public class DataSourceConfig { - @Bean - public DataSource dataSource() { - EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); - return builder.setType(EmbeddedDatabaseType.H2).build(); - } + @Bean + public DataSource dataSource() { + EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); + return builder.setType(EmbeddedDatabaseType.H2).build(); + } - @Bean - public JedisConnectionFactory connectionFactory() throws Exception { - return new JedisConnectionFactory(); - } + @Bean + public JedisConnectionFactory connectionFactory() throws Exception { + return new JedisConnectionFactory(); + } } diff --git a/samples/websocket/src/main/java/sample/config/EmbeddedRedisConfig.java b/samples/websocket/src/main/java/sample/config/EmbeddedRedisConfig.java index 01e05749..1b32587e 100644 --- a/samples/websocket/src/main/java/sample/config/EmbeddedRedisConfig.java +++ b/samples/websocket/src/main/java/sample/config/EmbeddedRedisConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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 @@ -33,36 +33,34 @@ import redis.embedded.RedisServer; @Configuration public class EmbeddedRedisConfig { - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public static RedisServerBean redisServer() { + return new RedisServerBean(); + } - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(Protocol.DEFAULT_PORT); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(Protocol.DEFAULT_PORT); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - @Override - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - @Override - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } } \ No newline at end of file diff --git a/samples/websocket/src/main/java/sample/config/H2Initializer.java b/samples/websocket/src/main/java/sample/config/H2Initializer.java index 9a62655c..bdc7a0ae 100644 --- a/samples/websocket/src/main/java/sample/config/H2Initializer.java +++ b/samples/websocket/src/main/java/sample/config/H2Initializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -32,7 +32,7 @@ public class H2Initializer { @Bean public ServletRegistrationBean h2Servlet() { ServletRegistrationBean servletBean = new ServletRegistrationBean(); - servletBean.addUrlMappings("/h2/*"); + servletBean.addUrlMappings("/h2/*"); servletBean.setServlet(new WebServlet()); return servletBean; } diff --git a/samples/websocket/src/main/java/sample/config/WebSecurityConfig.java b/samples/websocket/src/main/java/sample/config/WebSecurityConfig.java index 21be6a8d..4f787e43 100644 --- a/samples/websocket/src/main/java/sample/config/WebSecurityConfig.java +++ b/samples/websocket/src/main/java/sample/config/WebSecurityConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -34,31 +34,34 @@ import org.springframework.session.data.redis.config.annotation.web.http.EnableR // tag::enable-redis-httpsession[] @EnableRedisHttpSession//(maxInactiveIntervalInSeconds = 60) public class WebSecurityConfig - extends WebSecurityConfigurerAdapter { + extends WebSecurityConfigurerAdapter { // end::enable-redis-httpsession[] - @Override - protected void configure(HttpSecurity http) throws Exception { + // @formatter:off + @Override + protected void configure(HttpSecurity http) throws Exception { + http + .authorizeRequests() + .anyRequest().authenticated() + .and() + .formLogin() + .and() + .logout() + .permitAll(); + } + // @formatter:on - http - .authorizeRequests() - .anyRequest().authenticated() - .and() - .formLogin() - .and() - .logout() - .permitAll(); - } + // @formatter:off + @Autowired + public void configureGlobal(AuthenticationManagerBuilder auth, UserDetailsService userDetailsService) throws Exception { + auth + .userDetailsService(userDetailsService) + .passwordEncoder(new BCryptPasswordEncoder()); + } + // @formatter:on - @Autowired - public void configureGlobal(AuthenticationManagerBuilder auth, UserDetailsService userDetailsService) throws Exception { - auth - .userDetailsService(userDetailsService) - .passwordEncoder(new BCryptPasswordEncoder()); - } - - @Bean - public SecurityEvaluationContextExtension securityEvaluationContextExtension() { - return new SecurityEvaluationContextExtension(); - } + @Bean + public SecurityEvaluationContextExtension securityEvaluationContextExtension() { + return new SecurityEvaluationContextExtension(); + } } \ No newline at end of file diff --git a/samples/websocket/src/main/java/sample/config/WebSocketConfig.java b/samples/websocket/src/main/java/sample/config/WebSocketConfig.java index 1c7c46cf..63ffab44 100644 --- a/samples/websocket/src/main/java/sample/config/WebSocketConfig.java +++ b/samples/websocket/src/main/java/sample/config/WebSocketConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -15,7 +15,6 @@ */ package sample.config; - import org.springframework.context.annotation.Configuration; import org.springframework.messaging.simp.config.MessageBrokerRegistry; import org.springframework.scheduling.annotation.EnableScheduling; @@ -29,16 +28,16 @@ import org.springframework.web.socket.config.annotation.StompEndpointRegistry; @EnableScheduling @EnableWebSocketMessageBroker public class WebSocketConfig - extends AbstractSessionWebSocketMessageBrokerConfigurer { // <1> + extends AbstractSessionWebSocketMessageBrokerConfigurer { // <1> - protected void configureStompEndpoints(StompEndpointRegistry registry) { // <2> - registry.addEndpoint("/messages") - .withSockJS(); - } + protected void configureStompEndpoints(StompEndpointRegistry registry) { // <2> + registry.addEndpoint("/messages") + .withSockJS(); + } - public void configureMessageBroker(MessageBrokerRegistry registry) { - registry.enableSimpleBroker("/queue/", "/topic/"); - registry.setApplicationDestinationPrefixes("/app"); - } + public void configureMessageBroker(MessageBrokerRegistry registry) { + registry.enableSimpleBroker("/queue/", "/topic/"); + registry.setApplicationDestinationPrefixes("/app"); + } } // end::class[] \ No newline at end of file diff --git a/samples/websocket/src/main/java/sample/config/WebSocketHandlersConfig.java b/samples/websocket/src/main/java/sample/config/WebSocketHandlersConfig.java index a84bf78b..65378c72 100644 --- a/samples/websocket/src/main/java/sample/config/WebSocketHandlersConfig.java +++ b/samples/websocket/src/main/java/sample/config/WebSocketHandlersConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -31,13 +31,13 @@ import sample.websocket.WebSocketDisconnectHandler; @Configuration public class WebSocketHandlersConfig { - @Bean - public WebSocketConnectHandler webSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { - return new WebSocketConnectHandler(messagingTemplate, repository); - } + @Bean + public WebSocketConnectHandler webSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { + return new WebSocketConnectHandler(messagingTemplate, repository); + } - @Bean - public WebSocketDisconnectHandler webSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { - return new WebSocketDisconnectHandler(messagingTemplate, repository); - } + @Bean + public WebSocketDisconnectHandler webSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { + return new WebSocketDisconnectHandler(messagingTemplate, repository); + } } diff --git a/samples/websocket/src/main/java/sample/config/WebSocketSecurityConfig.java b/samples/websocket/src/main/java/sample/config/WebSocketSecurityConfig.java index 8b4eb2ec..392bbb07 100644 --- a/samples/websocket/src/main/java/sample/config/WebSocketSecurityConfig.java +++ b/samples/websocket/src/main/java/sample/config/WebSocketSecurityConfig.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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 @@ -26,11 +26,13 @@ import org.springframework.security.config.annotation.web.socket.AbstractSecurit @Configuration public class WebSocketSecurityConfig extends AbstractSecurityWebSocketMessageBrokerConfigurer { - @Override - protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { - messages - .antMatchers(SimpMessageType.MESSAGE,"/queue/**","/topic/**").denyAll() - .antMatchers(SimpMessageType.SUBSCRIBE, "/queue/**/*-user*","/topic/**/*-user*").denyAll() - .anyMessage().authenticated(); - } + // @formatter:off + @Override + protected void configureInbound(MessageSecurityMetadataSourceRegistry messages) { + messages + .antMatchers(SimpMessageType.MESSAGE,"/queue/**","/topic/**").denyAll() + .antMatchers(SimpMessageType.SUBSCRIBE, "/queue/**/*-user*","/topic/**/*-user*").denyAll() + .anyMessage().authenticated(); + } + // @formatter:on } \ No newline at end of file diff --git a/samples/websocket/src/main/java/sample/data/ActiveWebSocketUser.java b/samples/websocket/src/main/java/sample/data/ActiveWebSocketUser.java index 29baf726..0352ee0f 100644 --- a/samples/websocket/src/main/java/sample/data/ActiveWebSocketUser.java +++ b/samples/websocket/src/main/java/sample/data/ActiveWebSocketUser.java @@ -1,6 +1,20 @@ +/* + * Copyright 2002-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 + * + * 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.data; - import java.util.Calendar; import javax.persistence.Entity; @@ -10,13 +24,13 @@ import javax.persistence.Id; public class ActiveWebSocketUser { @Id private String id; - + private String username; - + private Calendar connectionTime; public ActiveWebSocketUser() {} - + public ActiveWebSocketUser(String id, String username, Calendar connectionTime) { super(); this.id = id; @@ -39,6 +53,6 @@ public class ActiveWebSocketUser { public void setConnectionTime(Calendar connectionTime) { this.connectionTime = connectionTime; } - - + + } diff --git a/samples/websocket/src/main/java/sample/data/ActiveWebSocketUserRepository.java b/samples/websocket/src/main/java/sample/data/ActiveWebSocketUserRepository.java index 06da9590..fad2c3c6 100644 --- a/samples/websocket/src/main/java/sample/data/ActiveWebSocketUserRepository.java +++ b/samples/websocket/src/main/java/sample/data/ActiveWebSocketUserRepository.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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.data; import java.util.List; diff --git a/samples/websocket/src/main/java/sample/data/InstantMessage.java b/samples/websocket/src/main/java/sample/data/InstantMessage.java index acdfdc23..b8e1b8a1 100644 --- a/samples/websocket/src/main/java/sample/data/InstantMessage.java +++ b/samples/websocket/src/main/java/sample/data/InstantMessage.java @@ -1,14 +1,29 @@ +/* + * Copyright 2002-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 + * + * 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.data; import java.util.Calendar; public class InstantMessage { private String to; - + private String from; - + private String message; - + private Calendar created = Calendar.getInstance(); public String getTo() { @@ -42,7 +57,7 @@ public class InstantMessage { public void setCreated(Calendar created) { this.created = created; } - - + + } diff --git a/samples/websocket/src/main/java/sample/data/User.java b/samples/websocket/src/main/java/sample/data/User.java index 4ae07a13..541ba209 100644 --- a/samples/websocket/src/main/java/sample/data/User.java +++ b/samples/websocket/src/main/java/sample/data/User.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -40,73 +40,73 @@ import org.springframework.security.crypto.password.PasswordEncoder; @Entity public class User implements Serializable { - @Id - @GeneratedValue(strategy = GenerationType.AUTO) - private Long id; + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; - @NotEmpty(message = "First name is required.") - private String firstName; + @NotEmpty(message = "First name is required.") + private String firstName; - @NotEmpty(message = "Last name is required.") - private String lastName; + @NotEmpty(message = "Last name is required.") + private String lastName; - @Email(message = "Please provide a valid email address.") - @NotEmpty(message = "Email is required.") - @Column(unique=true, nullable = false) - private String email; + @Email(message = "Please provide a valid email address.") + @NotEmpty(message = "Email is required.") + @Column(unique=true, nullable = false) + private String email; - @NotEmpty(message = "Password is required.") - private String password; + @NotEmpty(message = "Password is required.") + private String password; - public User() {} + public User() {} - public User(User user) { - this.id = user.id; - this.firstName = user.firstName; - this.lastName = user.lastName; - this.email = user.email; - this.password = user.password; - } + public User(User user) { + this.id = user.id; + this.firstName = user.firstName; + this.lastName = user.lastName; + this.email = user.email; + this.password = user.password; + } - public String getPassword() { - return password; - } + public String getPassword() { + return password; + } - public void setPassword(String password) { - this.password = password; - } + public void setPassword(String password) { + this.password = password; + } - public Long getId() { - return id; - } + public Long getId() { + return id; + } - public void setId(Long id) { - this.id = id; - } + public void setId(Long id) { + this.id = id; + } - public String getFirstName() { - return firstName; - } + public String getFirstName() { + return firstName; + } - public void setFirstName(String firstName) { - this.firstName = firstName; - } + public void setFirstName(String firstName) { + this.firstName = firstName; + } - public String getLastName() { - return lastName; - } + public String getLastName() { + return lastName; + } - public void setLastName(String lastName) { - this.lastName = lastName; - } + public void setLastName(String lastName) { + this.lastName = lastName; + } - public String getEmail() { - return email; - } + public String getEmail() { + return email; + } - public void setEmail(String email) { - this.email = email; - } + public void setEmail(String email) { + this.email = email; + } - private static final long serialVersionUID = 2738859149330833739L; + private static final long serialVersionUID = 2738859149330833739L; } \ No newline at end of file diff --git a/samples/websocket/src/main/java/sample/data/UserRepository.java b/samples/websocket/src/main/java/sample/data/UserRepository.java index 5339e23a..76084255 100644 --- a/samples/websocket/src/main/java/sample/data/UserRepository.java +++ b/samples/websocket/src/main/java/sample/data/UserRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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 @@ -25,5 +25,5 @@ import org.springframework.data.repository.CrudRepository; */ public interface UserRepository extends CrudRepository { - User findByEmail(String email); + User findByEmail(String email); } diff --git a/samples/websocket/src/main/java/sample/mvc/MessageController.java b/samples/websocket/src/main/java/sample/mvc/MessageController.java index 1c0f3eaf..dfda7fbb 100644 --- a/samples/websocket/src/main/java/sample/mvc/MessageController.java +++ b/samples/websocket/src/main/java/sample/mvc/MessageController.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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 @@ -22,7 +22,6 @@ import org.springframework.messaging.Message; import org.springframework.messaging.handler.annotation.MessageMapping; import org.springframework.messaging.simp.SimpMessageSendingOperations; import org.springframework.messaging.simp.annotation.SubscribeMapping; -import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; @@ -40,29 +39,29 @@ import sample.security.CurrentUser; @Controller @RequestMapping("/") public class MessageController { - private SimpMessageSendingOperations messagingTemplate; - private ActiveWebSocketUserRepository activeUserRepository; + private SimpMessageSendingOperations messagingTemplate; + private ActiveWebSocketUserRepository activeUserRepository; - @Autowired - public MessageController(ActiveWebSocketUserRepository activeUserRepository,SimpMessageSendingOperations messagingTemplate) { - this.activeUserRepository = activeUserRepository; - this.messagingTemplate = messagingTemplate; - } + @Autowired + public MessageController(ActiveWebSocketUserRepository activeUserRepository,SimpMessageSendingOperations messagingTemplate) { + this.activeUserRepository = activeUserRepository; + this.messagingTemplate = messagingTemplate; + } - @RequestMapping("/") - public String im() { - return "index"; - } + @RequestMapping("/") + public String im() { + return "index"; + } - @MessageMapping("/im") - public void im(InstantMessage im, @CurrentUser User currentUser) { - im.setFrom(currentUser.getEmail()); - messagingTemplate.convertAndSendToUser(im.getTo(),"/queue/messages",im); - messagingTemplate.convertAndSendToUser(im.getFrom(),"/queue/messages",im); - } + @MessageMapping("/im") + public void im(InstantMessage im, @CurrentUser User currentUser) { + im.setFrom(currentUser.getEmail()); + messagingTemplate.convertAndSendToUser(im.getTo(),"/queue/messages",im); + messagingTemplate.convertAndSendToUser(im.getFrom(),"/queue/messages",im); + } - @SubscribeMapping("/users") - public List subscribeMessages() throws Exception { - return activeUserRepository.findAllActiveUsers(); - } + @SubscribeMapping("/users") + public List subscribeMessages() throws Exception { + return activeUserRepository.findAllActiveUsers(); + } } diff --git a/samples/websocket/src/main/java/sample/security/CurrentUser.java b/samples/websocket/src/main/java/sample/security/CurrentUser.java index 4eab1069..39c96577 100644 --- a/samples/websocket/src/main/java/sample/security/CurrentUser.java +++ b/samples/websocket/src/main/java/sample/security/CurrentUser.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. diff --git a/samples/websocket/src/main/java/sample/security/UserRepositoryUserDetailsService.java b/samples/websocket/src/main/java/sample/security/UserRepositoryUserDetailsService.java index dad93095..5344ab20 100644 --- a/samples/websocket/src/main/java/sample/security/UserRepositoryUserDetailsService.java +++ b/samples/websocket/src/main/java/sample/security/UserRepositoryUserDetailsService.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -33,55 +33,55 @@ import org.springframework.stereotype.Service; */ @Service public class UserRepositoryUserDetailsService implements UserDetailsService { - private final UserRepository userRepository; + private final UserRepository userRepository; - @Autowired - public UserRepositoryUserDetailsService(UserRepository userRepository) { - this.userRepository = userRepository; - } + @Autowired + public UserRepositoryUserDetailsService(UserRepository userRepository) { + this.userRepository = userRepository; + } - /* (non-Javadoc) - * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String) - */ - public UserDetails loadUserByUsername(String username) - throws UsernameNotFoundException { - User user = userRepository.findByEmail(username); - if(user == null) { - throw new UsernameNotFoundException("Could not find user " + username); - } - return new CustomUserDetails(user); - } + /* (non-Javadoc) + * @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String) + */ + public UserDetails loadUserByUsername(String username) + throws UsernameNotFoundException { + User user = userRepository.findByEmail(username); + if(user == null) { + throw new UsernameNotFoundException("Could not find user " + username); + } + return new CustomUserDetails(user); + } - private final static class CustomUserDetails extends User implements UserDetails { + private final static class CustomUserDetails extends User implements UserDetails { - private CustomUserDetails(User user) { - super(user); - } + private CustomUserDetails(User user) { + super(user); + } - public Collection getAuthorities() { - return AuthorityUtils.createAuthorityList("ROLE_USER"); - } + public Collection getAuthorities() { + return AuthorityUtils.createAuthorityList("ROLE_USER"); + } - public String getUsername() { - return getEmail(); - } + public String getUsername() { + return getEmail(); + } - public boolean isAccountNonExpired() { - return true; - } + public boolean isAccountNonExpired() { + return true; + } - public boolean isAccountNonLocked() { - return true; - } + public boolean isAccountNonLocked() { + return true; + } - public boolean isCredentialsNonExpired() { - return true; - } + public boolean isCredentialsNonExpired() { + return true; + } - public boolean isEnabled() { - return true; - } + public boolean isEnabled() { + return true; + } - private static final long serialVersionUID = 5639683223516504866L; - } + private static final long serialVersionUID = 5639683223516504866L; + } } diff --git a/samples/websocket/src/main/java/sample/websocket/WebSocketConnectHandler.java b/samples/websocket/src/main/java/sample/websocket/WebSocketConnectHandler.java index 3163e441..18dd9e8c 100644 --- a/samples/websocket/src/main/java/sample/websocket/WebSocketConnectHandler.java +++ b/samples/websocket/src/main/java/sample/websocket/WebSocketConnectHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -29,23 +29,23 @@ import sample.data.ActiveWebSocketUser; import sample.data.ActiveWebSocketUserRepository; public class WebSocketConnectHandler implements ApplicationListener { - private ActiveWebSocketUserRepository repository; - private SimpMessageSendingOperations messagingTemplate; + private ActiveWebSocketUserRepository repository; + private SimpMessageSendingOperations messagingTemplate; - public WebSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { - super(); - this.messagingTemplate = messagingTemplate; - this.repository = repository; - } + public WebSocketConnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { + super(); + this.messagingTemplate = messagingTemplate; + this.repository = repository; + } - public void onApplicationEvent(SessionConnectEvent event) { - MessageHeaders headers = event.getMessage().getHeaders(); - Principal user = SimpMessageHeaderAccessor.getUser(headers); - if(user == null) { - return; - } - String id = SimpMessageHeaderAccessor.getSessionId(headers); - repository.save(new ActiveWebSocketUser(id, user.getName(), Calendar.getInstance())); - messagingTemplate.convertAndSend("/topic/friends/signin", Arrays.asList(user.getName())); - } + public void onApplicationEvent(SessionConnectEvent event) { + MessageHeaders headers = event.getMessage().getHeaders(); + Principal user = SimpMessageHeaderAccessor.getUser(headers); + if(user == null) { + return; + } + String id = SimpMessageHeaderAccessor.getSessionId(headers); + repository.save(new ActiveWebSocketUser(id, user.getName(), Calendar.getInstance())); + messagingTemplate.convertAndSend("/topic/friends/signin", Arrays.asList(user.getName())); + } } \ No newline at end of file diff --git a/samples/websocket/src/main/java/sample/websocket/WebSocketDisconnectHandler.java b/samples/websocket/src/main/java/sample/websocket/WebSocketDisconnectHandler.java index ca624d10..bd80b3c9 100644 --- a/samples/websocket/src/main/java/sample/websocket/WebSocketDisconnectHandler.java +++ b/samples/websocket/src/main/java/sample/websocket/WebSocketDisconnectHandler.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -25,27 +25,27 @@ import sample.data.ActiveWebSocketUser; import sample.data.ActiveWebSocketUserRepository; public class WebSocketDisconnectHandler implements ApplicationListener { - private ActiveWebSocketUserRepository repository; - private SimpMessageSendingOperations messagingTemplate; + private ActiveWebSocketUserRepository repository; + private SimpMessageSendingOperations messagingTemplate; - public WebSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { - super(); - this.messagingTemplate = messagingTemplate; - this.repository = repository; - } + public WebSocketDisconnectHandler(SimpMessageSendingOperations messagingTemplate, ActiveWebSocketUserRepository repository) { + super(); + this.messagingTemplate = messagingTemplate; + this.repository = repository; + } - public void onApplicationEvent(SessionDisconnectEvent event) { - String id = event.getSessionId(); - if(id == null) { - return; - } - ActiveWebSocketUser user = repository.findOne(id); - if(user == null) { - return; - } + public void onApplicationEvent(SessionDisconnectEvent event) { + String id = event.getSessionId(); + if(id == null) { + return; + } + ActiveWebSocketUser user = repository.findOne(id); + if(user == null) { + return; + } - repository.delete(id); - messagingTemplate.convertAndSend("/topic/friends/signout", Arrays.asList(user.getUsername())); + repository.delete(id); + messagingTemplate.convertAndSend("/topic/friends/signout", Arrays.asList(user.getUsername())); - } + } } \ No newline at end of file diff --git a/samples/websocket/src/main/resources/static/resources/js/message.js b/samples/websocket/src/main/resources/static/resources/js/message.js index dcfc0ab5..a13fba39 100644 --- a/samples/websocket/src/main/resources/static/resources/js/message.js +++ b/samples/websocket/src/main/resources/static/resources/js/message.js @@ -1,139 +1,139 @@ function ApplicationModel(stompClient) { - var self = this; + var self = this; - self.friends = ko.observableArray(); - self.username = ko.observable(); - self.conversation = ko.observable(new ImConversationModel(stompClient,this.username)); - self.notifications = ko.observableArray(); + self.friends = ko.observableArray(); + self.username = ko.observable(); + self.conversation = ko.observable(new ImConversationModel(stompClient,this.username)); + self.notifications = ko.observableArray(); - self.connect = function() { - stompClient.connect({}, function(frame) { + self.connect = function() { + stompClient.connect({}, function(frame) { - console.log('Connected ' + frame); - self.username(frame.headers['user-name']); + console.log('Connected ' + frame); + self.username(frame.headers['user-name']); // self.friendSignin({"username": "luke"}); - stompClient.subscribe("/user/queue/errors", function(message) { - self.pushNotification("Error " + message.body); - }); - stompClient.subscribe("/app/users", function(message) { - var friends = JSON.parse(message.body); + stompClient.subscribe("/user/queue/errors", function(message) { + self.pushNotification("Error " + message.body); + }); + stompClient.subscribe("/app/users", function(message) { + var friends = JSON.parse(message.body); - for(var i=0;i 5) { - self.notifications.shift(); - } - } + self.pushNotification = function(text) { + self.notifications.push({notification: text}); + if (self.notifications().length > 5) { + self.notifications.shift(); + } + } - self.logout = function() { - stompClient.disconnect(); - window.location.href = "../logout.html"; - } + self.logout = function() { + stompClient.disconnect(); + window.location.href = "../logout.html"; + } - self.friendSignin = function(friend) { - self.friends.push(friend); - } + self.friendSignin = function(friend) { + self.friends.push(friend); + } - self.friendSignout = function(friend) { - var r = self.friends.remove( - function(item) { - item.username == friend.username - } - ); - self.friends(r); - } + self.friendSignout = function(friend) { + var r = self.friends.remove( + function(item) { + item.username == friend.username + } + ); + self.friends(r); + } } function ImFriend(data) { - var self = this; + var self = this; - self.username = data.username; + self.username = data.username; } function ImConversationModel(stompClient,from) { - var self = this; - self.stompClient = stompClient; - self.from = from; - self.to = ko.observable(new ImFriend('null')); - self.draft = ko.observable('') + var self = this; + self.stompClient = stompClient; + self.from = from; + self.to = ko.observable(new ImFriend('null')); + self.draft = ko.observable('') - self.messages = ko.observableArray(); + self.messages = ko.observableArray(); - self.receiveMessage = function(message) { - var elem = $('#chat'); - var isFromSelf = self.from() == message.from; - var isFromTo = self.to().username == message.from; - if(!(isFromTo || isFromSelf)) { - self.chat(new ImFriend({"username":message.from})) - } + self.receiveMessage = function(message) { + var elem = $('#chat'); + var isFromSelf = self.from() == message.from; + var isFromTo = self.to().username == message.from; + if(!(isFromTo || isFromSelf)) { + self.chat(new ImFriend({"username":message.from})) + } - var atBottom = (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()); + var atBottom = (elem[0].scrollHeight - elem.scrollTop() == elem.outerHeight()); - self.messages.push(new ImModel(message)); + self.messages.push(new ImModel(message)); - if (atBottom) - elem.scrollTop(elem[0].scrollHeight); - }; + if (atBottom) + elem.scrollTop(elem[0].scrollHeight); + }; - self.chat = function(to) { - self.to(to); - self.draft(''); - self.messages.removeAll() - $('#trade-dialog').modal(); - } + self.chat = function(to) { + self.to(to); + self.draft(''); + self.messages.removeAll() + $('#trade-dialog').modal(); + } - self.send = function() { - var data = { - "created" : new Date(), - "from" : self.from(), - "to" : self.to().username, - "message" : self.draft() - }; - var destination = "/app/im"; // /queue/messages-user1 - stompClient.send(destination, {}, JSON.stringify(data)); - self.draft(''); - } + self.send = function() { + var data = { + "created" : new Date(), + "from" : self.from(), + "to" : self.to().username, + "message" : self.draft() + }; + var destination = "/app/im"; // /queue/messages-user1 + stompClient.send(destination, {}, JSON.stringify(data)); + self.draft(''); + } }; function ImModel(data) { - var self = this; + var self = this; - self.created = new Date(data.created); - self.to = data.to; - self.message = data.message; - self.from = data.from; - self.messageFormatted = ko.computed(function() { - return self.created.getHours() + ":" + self.created.getMinutes() + ":" + self.created.getSeconds() + " - " + self.from + " - " + self.message; - }) + self.created = new Date(data.created); + self.to = data.to; + self.message = data.message; + self.from = data.from; + self.messageFormatted = ko.computed(function() { + return self.created.getHours() + ":" + self.created.getMinutes() + ":" + self.created.getSeconds() + " - " + self.from + " - " + self.message; + }) }; diff --git a/samples/websocket/src/main/resources/templates/index.html b/samples/websocket/src/main/resources/templates/index.html index 97a4f67b..a5d18e4f 100644 --- a/samples/websocket/src/main/resources/templates/index.html +++ b/samples/websocket/src/main/resources/templates/index.html @@ -1,74 +1,74 @@ - - View All - - -
-
-
-

Chat Application

-
-
- - - - - - - - - - - - - -
User
- -
+ + View All + + +
+
+
+

Chat Application

+
+
+ + + + + + + + + + + + + +
User
+ +
- -
-
Notifications
-
    -
  • -
-
-
-
+ +
+
Notifications
+
    +
  • +
+
+
+
- - - - - - + + + + + + - - - + -
- + })(); + +
+ \ No newline at end of file diff --git a/samples/websocket/src/main/resources/templates/layout.html b/samples/websocket/src/main/resources/templates/layout.html index 7d910605..f1b15e4b 100644 --- a/samples/websocket/src/main/resources/templates/layout.html +++ b/samples/websocket/src/main/resources/templates/layout.html @@ -1,124 +1,124 @@ - - SecureMail - - - - + .container { + width: auto; + max-width: 680px; + } + .container .credit { + margin: 20px 0; + text-align: center; + } + a { + color: green; + } + .navbar-form { + margin-left: 1em; + } + + - - - + + + - -
- +
+
- - + + \ No newline at end of file diff --git a/spring-session-data-redis/build.gradle b/spring-session-data-redis/build.gradle index c3d7b222..a45448d8 100644 --- a/spring-session-data-redis/build.gradle +++ b/spring-session-data-redis/build.gradle @@ -6,10 +6,10 @@ apply plugin: 'spring-io' description = "Aggregator for Spring Session and Spring Data Redis" dependencies { - compile project(':spring-session'), - "org.springframework.data:spring-data-redis:$springDataRedisVersion", - "redis.clients:jedis:$jedisVersion", - "org.apache.commons:commons-pool2:$commonsPoolVersion" + compile project(':spring-session'), + "org.springframework.data:spring-data-redis:$springDataRedisVersion", + "redis.clients:jedis:$jedisVersion", + "org.apache.commons:commons-pool2:$commonsPoolVersion" - springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties" + springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties" } \ No newline at end of file diff --git a/spring-session/build.gradle b/spring-session/build.gradle index fce25450..55793312 100644 --- a/spring-session/build.gradle +++ b/spring-session/build.gradle @@ -10,87 +10,87 @@ project.conf2ScopeMappings.addMapping(MavenPlugin.TEST_COMPILE_PRIORITY + 2, pro check.dependsOn integrationTest configurations { - jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo + jacoco //Configuration Group used by Sonar to provide Code Coverage using JaCoCo } dependencies { - optional "org.springframework.data:spring-data-redis:$springDataRedisVersion", - "org.springframework:spring-context:$springVersion", - "org.springframework:spring-web:$springVersion", - "org.springframework:spring-messaging:$springVersion", - "org.springframework:spring-websocket:$springVersion" - provided "javax.servlet:javax.servlet-api:$servletApiVersion" - integrationTestCompile "redis.clients:jedis:2.4.1", - "org.apache.commons:commons-pool2:2.2", - "redis.embedded:embedded-redis:0.4" - testCompile 'junit:junit:4.11', - 'org.mockito:mockito-core:1.9.5', - "org.springframework:spring-test:$springVersion", - 'org.easytesting:fest-assert:1.4', - "org.springframework.security:spring-security-core:$springSecurityVersion" + optional "org.springframework.data:spring-data-redis:$springDataRedisVersion", + "org.springframework:spring-context:$springVersion", + "org.springframework:spring-web:$springVersion", + "org.springframework:spring-messaging:$springVersion", + "org.springframework:spring-websocket:$springVersion" + provided "javax.servlet:javax.servlet-api:$servletApiVersion" + integrationTestCompile "redis.clients:jedis:2.4.1", + "org.apache.commons:commons-pool2:2.2", + "redis.embedded:embedded-redis:0.4" + testCompile 'junit:junit:4.11', + 'org.mockito:mockito-core:1.9.5', + "org.springframework:spring-test:$springVersion", + 'org.easytesting:fest-assert:1.4', + "org.springframework.security:spring-security-core:$springSecurityVersion" - jacoco "org.jacoco:org.jacoco.agent:0.7.2.201409121644:runtime" + jacoco "org.jacoco:org.jacoco.agent:0.7.2.201409121644:runtime" - springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties" + springIoVersions "io.spring.platform:platform-versions:${springIoVersion}@properties" } ext.javadocLinks = [ - "http://docs.oracle.com/javase/8/docs/api/", - "http://docs.oracle.com/javaee/7/api/", - "http://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ - "http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/", - "http://glassfish.java.net/nonav/docs/v3/api/", - "http://docs.jboss.org/jbossas/javadoc/4.0.5/connector/", - "http://docs.jboss.org/jbossas/javadoc/7.1.2.Final/", - "http://commons.apache.org/proper/commons-lang/javadocs/api-2.5/", - "http://commons.apache.org/proper/commons-codec/apidocs/", - "http://commons.apache.org/proper/commons-dbcp/apidocs/", - "http://portals.apache.org/pluto/portlet-2.0-apidocs/", - "http://tiles.apache.org/tiles-request/apidocs/", - "http://tiles.apache.org/framework/apidocs/", - "http://aopalliance.sourceforge.net/doc/", - "http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/", - "http://ehcache.org/apidocs/", - "http://quartz-scheduler.org/api/2.2.0/", - "http://fasterxml.github.com/jackson-core/javadoc/2.3.0/", - "http://fasterxml.github.com/jackson-databind/javadoc/2.3.0/", - "http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/" + "http://docs.oracle.com/javase/8/docs/api/", + "http://docs.oracle.com/javaee/7/api/", + "http://docs.oracle.com/cd/E13222_01/wls/docs90/javadocs/", // CommonJ + "http://pic.dhe.ibm.com/infocenter/wasinfo/v7r0/topic/com.ibm.websphere.javadoc.doc/web/apidocs/", + "http://glassfish.java.net/nonav/docs/v3/api/", + "http://docs.jboss.org/jbossas/javadoc/4.0.5/connector/", + "http://docs.jboss.org/jbossas/javadoc/7.1.2.Final/", + "http://commons.apache.org/proper/commons-lang/javadocs/api-2.5/", + "http://commons.apache.org/proper/commons-codec/apidocs/", + "http://commons.apache.org/proper/commons-dbcp/apidocs/", + "http://portals.apache.org/pluto/portlet-2.0-apidocs/", + "http://tiles.apache.org/tiles-request/apidocs/", + "http://tiles.apache.org/framework/apidocs/", + "http://aopalliance.sourceforge.net/doc/", + "http://www.eclipse.org/aspectj/doc/released/aspectj5rt-api/", + "http://ehcache.org/apidocs/", + "http://quartz-scheduler.org/api/2.2.0/", + "http://fasterxml.github.com/jackson-core/javadoc/2.3.0/", + "http://fasterxml.github.com/jackson-databind/javadoc/2.3.0/", + "http://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/" ] as String[] javadoc { - description = "Generates project-level javadoc for use in -javadoc jar" + description = "Generates project-level javadoc for use in -javadoc jar" - options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED - options.author = true - options.header = project.name - options.links(project.ext.javadocLinks) - options.addStringOption('-quiet') + options.memberLevel = org.gradle.external.javadoc.JavadocMemberLevel.PROTECTED + options.author = true + options.header = project.name + options.links(project.ext.javadocLinks) + options.addStringOption('-quiet') - // suppress warnings due to cross-module @see and @link references; - // note that global 'api' task does display all warnings. - logging.captureStandardError LogLevel.INFO - logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message + // suppress warnings due to cross-module @see and @link references; + // note that global 'api' task does display all warnings. + logging.captureStandardError LogLevel.INFO + logging.captureStandardOutput LogLevel.INFO // suppress "## warnings" message } task sourcesJar(type: Jar, dependsOn: classes) { - classifier = 'sources' - from sourceSets.main.allSource - // don't include or exclude anything explicitly by default. See SPR-12085. + classifier = 'sources' + from sourceSets.main.allSource + // don't include or exclude anything explicitly by default. See SPR-12085. } task javadocJar(type: Jar) { - classifier = "javadoc" - from javadoc + classifier = "javadoc" + from javadoc } artifacts { - archives sourcesJar - archives javadocJar + archives sourcesJar + archives javadocJar } test { - jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*" + jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*" } integrationTest { - jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*" + jvmArgs "-javaagent:${configurations.jacoco.asPath}=destfile=${buildDir}/jacoco.exec,includes=${project.group}.*" } diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java b/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java index 1cee0cab..61e3571e 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryITests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.data.redis; import static org.fest.assertions.Assertions.assertThat; @@ -19,7 +34,6 @@ import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; -import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.AuthorityUtils; @@ -32,148 +46,145 @@ import org.springframework.session.events.SessionDestroyedEvent; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import redis.clients.jedis.Protocol; import redis.embedded.RedisServer; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class RedisOperationsSessionRepositoryITests { - private RedisServer redisServer; + @Autowired + private SessionRepository repository; - @Autowired - private SessionRepository repository; + @Autowired + private SessionDestroyedEventRegistry registry; - @Autowired - private SessionDestroyedEventRegistry registry; + private final Object lock = new Object(); - private final Object lock = new Object(); + @Before + public void setup() { + registry.setLock(lock); + } - @Before - public void setup() { - registry.setLock(lock); - } + @Test + public void saves() throws InterruptedException { + S toSave = repository.createSession(); + toSave.setAttribute("a", "b"); + Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user","password", AuthorityUtils.createAuthorityList("ROLE_USER")); + SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext(); + toSaveContext.setAuthentication(toSaveToken); + toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext); - @Test - public void saves() throws InterruptedException { - S toSave = repository.createSession(); - toSave.setAttribute("a", "b"); - Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user","password", AuthorityUtils.createAuthorityList("ROLE_USER")); - SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext(); - toSaveContext.setAuthentication(toSaveToken); - toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext); + repository.save(toSave); - repository.save(toSave); + Session session = repository.getSession(toSave.getId()); - Session session = repository.getSession(toSave.getId()); + assertThat(session.getId()).isEqualTo(toSave.getId()); + assertThat(session.getAttributeNames()).isEqualTo(session.getAttributeNames()); + assertThat(session.getAttribute("a")).isEqualTo(toSave.getAttribute("a")); - assertThat(session.getId()).isEqualTo(toSave.getId()); - assertThat(session.getAttributeNames()).isEqualTo(session.getAttributeNames()); - assertThat(session.getAttribute("a")).isEqualTo(toSave.getAttribute("a")); + repository.delete(toSave.getId()); - repository.delete(toSave.getId()); + assertThat(repository.getSession(toSave.getId())).isNull(); + synchronized (lock) { + lock.wait(3000); + } + assertThat(registry.receivedEvent()).isTrue(); + } - assertThat(repository.getSession(toSave.getId())).isNull(); - synchronized (lock) { - lock.wait(3000); - } - assertThat(registry.receivedEvent()).isTrue(); - } + @Test + public void putAllOnSingleAttrDoesNotRemoveOld() { + S toSave = repository.createSession(); + toSave.setAttribute("a", "b"); - @Test - public void putAllOnSingleAttrDoesNotRemoveOld() { - S toSave = repository.createSession(); - toSave.setAttribute("a", "b"); + repository.save(toSave); + toSave = repository.getSession(toSave.getId()); - repository.save(toSave); - toSave = repository.getSession(toSave.getId()); + toSave.setAttribute("1", "2"); - toSave.setAttribute("1", "2"); + repository.save(toSave); + toSave = repository.getSession(toSave.getId()); - repository.save(toSave); - toSave = repository.getSession(toSave.getId()); + Session session = repository.getSession(toSave.getId()); + assertThat(session.getAttributeNames().size()).isEqualTo(2); + assertThat(session.getAttribute("a")).isEqualTo("b"); + assertThat(session.getAttribute("1")).isEqualTo("2"); + } - Session session = repository.getSession(toSave.getId()); - assertThat(session.getAttributeNames().size()).isEqualTo(2); - assertThat(session.getAttribute("a")).isEqualTo("b"); - assertThat(session.getAttribute("1")).isEqualTo("2"); - } + static class SessionDestroyedEventRegistry implements ApplicationListener { + private boolean receivedEvent; + private Object lock; - static class SessionDestroyedEventRegistry implements ApplicationListener { - private boolean receivedEvent; - private Object lock; + public void onApplicationEvent(SessionDestroyedEvent event) { + receivedEvent = true; + synchronized (lock) { + lock.notifyAll(); + } + } - public void onApplicationEvent(SessionDestroyedEvent event) { - receivedEvent = true; - synchronized (lock) { - lock.notifyAll(); - } - } + public boolean receivedEvent() { + return receivedEvent; + } - public boolean receivedEvent() { - return receivedEvent; - } + public void setLock(Object lock) { + this.lock = lock; + } + } - public void setLock(Object lock) { - this.lock = lock; - } - } + @Configuration + @EnableRedisHttpSession + static class Config { + @Bean + public JedisConnectionFactory connectionFactory() throws Exception { + JedisConnectionFactory factory = new JedisConnectionFactory(); + factory.setPort(getPort()); + factory.setUsePool(false); + return factory; + } - @Configuration - @EnableRedisHttpSession - static class Config { - @Bean - public JedisConnectionFactory connectionFactory() throws Exception { - JedisConnectionFactory factory = new JedisConnectionFactory(); - factory.setPort(getPort()); - factory.setUsePool(false); - return factory; - } + @Bean + public static RedisServerBean redisServer() { + return new RedisServerBean(); + } - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public SessionDestroyedEventRegistry sessionDestroyedEventRegistry() { + return new SessionDestroyedEventRegistry(); + } - @Bean - public SessionDestroyedEventRegistry sessionDestroyedEventRegistry() { - return new SessionDestroyedEventRegistry(); - } - - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(getPort()); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(getPort()); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } + } - private static Integer availablePort; + private static Integer availablePort; - private static int getPort() throws IOException { - if(availablePort == null) { - ServerSocket socket = new ServerSocket(0); - availablePort = socket.getLocalPort(); - socket.close(); - } - return availablePort; - } + private static int getPort() throws IOException { + if(availablePort == null) { + ServerSocket socket = new ServerSocket(0); + availablePort = socket.getLocalPort(); + socket.close(); + } + return availablePort; + } } \ No newline at end of file diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java index 65b39b46..d0887d07 100644 --- a/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java +++ b/spring-session/src/integration-test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSessionExpireSessionDestroyedTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -35,145 +35,139 @@ import org.springframework.context.ApplicationListener; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; -import org.springframework.scheduling.annotation.EnableScheduling; import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; import org.springframework.security.core.Authentication; import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.core.context.SecurityContext; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.session.ExpiringSession; -import org.springframework.session.Session; import org.springframework.session.SessionRepository; -import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; import org.springframework.session.events.SessionDestroyedEvent; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import redis.clients.jedis.Protocol; import redis.embedded.RedisServer; @RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration public class EnableRedisHttpSessionExpireSessionDestroyedTests { - private RedisServer redisServer; + @Autowired + private SessionRepository repository; - @Autowired - private SessionRepository repository; + @Autowired + private SessionDestroyedEventRegistry registry; - @Autowired - private SessionDestroyedEventRegistry registry; + private final Object lock = new Object(); - private final Object lock = new Object(); + @Before + public void setup() { + registry.setLock(lock); + } - @Before - public void setup() { - registry.setLock(lock); - } + @Test + public void expireFiresSessionDestroyedEvent() throws InterruptedException { + S toSave = repository.createSession(); + toSave.setAttribute("a", "b"); + Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user","password", AuthorityUtils.createAuthorityList("ROLE_USER")); + SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext(); + toSaveContext.setAuthentication(toSaveToken); + toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext); - @Test - public void expireFiresSessionDestroyedEvent() throws InterruptedException { - S toSave = repository.createSession(); - toSave.setAttribute("a", "b"); - Authentication toSaveToken = new UsernamePasswordAuthenticationToken("user","password", AuthorityUtils.createAuthorityList("ROLE_USER")); - SecurityContext toSaveContext = SecurityContextHolder.createEmptyContext(); - toSaveContext.setAuthentication(toSaveToken); - toSave.setAttribute("SPRING_SECURITY_CONTEXT", toSaveContext); + repository.save(toSave); - repository.save(toSave); + synchronized (lock) { + lock.wait((toSave.getMaxInactiveIntervalInSeconds() * 1000) + 1); + } + if(!registry.receivedEvent()) { + // Redis makes no guarantees on when an expired event will be fired + // we can ensure it gets fired by trying to get the session + repository.getSession(toSave.getId()); + synchronized (lock) { + if(!registry.receivedEvent()) { + // wait at most second to process the event + lock.wait(1000); + } + } + } + assertThat(registry.receivedEvent()).isTrue(); + } - synchronized (lock) { - lock.wait((toSave.getMaxInactiveIntervalInSeconds() * 1000) + 1); - } - if(!registry.receivedEvent()) { - // Redis makes no guarantees on when an expired event will be fired - // we can ensure it gets fired by trying to get the session - repository.getSession(toSave.getId()); - synchronized (lock) { - if(!registry.receivedEvent()) { - // wait at most second to process the event - lock.wait(1000); - } - } - } - assertThat(registry.receivedEvent()).isTrue(); - } + static class SessionDestroyedEventRegistry implements ApplicationListener { + private boolean receivedEvent; + private Object lock; - static class SessionDestroyedEventRegistry implements ApplicationListener { - private boolean receivedEvent; - private Object lock; + public void onApplicationEvent(SessionDestroyedEvent event) { + synchronized (lock) { + receivedEvent = true; + lock.notifyAll(); + } + } - public void onApplicationEvent(SessionDestroyedEvent event) { - synchronized (lock) { - receivedEvent = true; - lock.notifyAll(); - } - } + public boolean receivedEvent() { + return receivedEvent; + } - public boolean receivedEvent() { - return receivedEvent; - } + public void setLock(Object lock) { + this.lock = lock; + } + } - public void setLock(Object lock) { - this.lock = lock; - } - } + @Configuration + @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1) + static class Config { + @Bean + public JedisConnectionFactory connectionFactory() throws Exception { + JedisConnectionFactory factory = new JedisConnectionFactory(); + factory.setPort(getPort()); + factory.setUsePool(false); + return factory; + } - @Configuration - @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 1) - static class Config { - @Bean - public JedisConnectionFactory connectionFactory() throws Exception { - JedisConnectionFactory factory = new JedisConnectionFactory(); - factory.setPort(getPort()); - factory.setUsePool(false); - return factory; - } + @Bean + public static RedisServerBean redisServer() { + return new RedisServerBean(); + } - @Bean - public static RedisServerBean redisServer() { - return new RedisServerBean(); - } + @Bean + public SessionDestroyedEventRegistry sessionDestroyedEventRegistry() { + return new SessionDestroyedEventRegistry(); + } - @Bean - public SessionDestroyedEventRegistry sessionDestroyedEventRegistry() { - return new SessionDestroyedEventRegistry(); - } - - /** - * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean - * is initialized before any other Beans. Specifically, we want to ensure - * that the Redis Server is started before RedisHttpSessionConfiguration - * attempts to enable Keyspace notifications. - */ - static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { - private RedisServer redisServer; + /** + * Implements BeanDefinitionRegistryPostProcessor to ensure this Bean + * is initialized before any other Beans. Specifically, we want to ensure + * that the Redis Server is started before RedisHttpSessionConfiguration + * attempts to enable Keyspace notifications. + */ + static class RedisServerBean implements InitializingBean, DisposableBean, BeanDefinitionRegistryPostProcessor { + private RedisServer redisServer; - public void afterPropertiesSet() throws Exception { - redisServer = new RedisServer(getPort()); - redisServer.start(); - } + public void afterPropertiesSet() throws Exception { + redisServer = new RedisServer(getPort()); + redisServer.start(); + } - public void destroy() throws Exception { - if(redisServer != null) { - redisServer.stop(); - } - } + public void destroy() throws Exception { + if(redisServer != null) { + redisServer.stop(); + } + } - public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} + public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {} - public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} - } - } + public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {} + } + } - private static Integer availablePort; + private static Integer availablePort; - private static int getPort() throws IOException { - if(availablePort == null) { - ServerSocket socket = new ServerSocket(0); - availablePort = socket.getLocalPort(); - socket.close(); - } - return availablePort; - } + private static int getPort() throws IOException { + if(availablePort == null) { + ServerSocket socket = new ServerSocket(0); + availablePort = socket.getLocalPort(); + socket.close(); + } + return availablePort; + } } diff --git a/spring-session/src/main/java/org/springframework/session/ExpiringSession.java b/spring-session/src/main/java/org/springframework/session/ExpiringSession.java index c51455ec..d371330a 100644 --- a/spring-session/src/main/java/org/springframework/session/ExpiringSession.java +++ b/spring-session/src/main/java/org/springframework/session/ExpiringSession.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session; /** @@ -8,39 +23,39 @@ package org.springframework.session; */ public interface ExpiringSession extends Session { - /** - * Gets the time when this session was created in milliseconds since midnight of 1/1/1970 GMT. - * - * @return the time when this session was created in milliseconds since midnight of 1/1/1970 GMT. - */ - long getCreationTime(); + /** + * Gets the time when this session was created in milliseconds since midnight of 1/1/1970 GMT. + * + * @return the time when this session was created in milliseconds since midnight of 1/1/1970 GMT. + */ + long getCreationTime(); - /** - * Gets the last time this {@link Session} was accessed expressed in milliseconds since midnight of 1/1/1970 GMT - * - * @return the last time the client sent a request associated with the session expressed in milliseconds since midnight of 1/1/1970 GMT - */ - long getLastAccessedTime(); + /** + * Gets the last time this {@link Session} was accessed expressed in milliseconds since midnight of 1/1/1970 GMT + * + * @return the last time the client sent a request associated with the session expressed in milliseconds since midnight of 1/1/1970 GMT + */ + long getLastAccessedTime(); - /** - * Sets the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout. - * - * @param interval the number of seconds that the {@link Session} should be kept alive between client requests. - */ - void setMaxInactiveIntervalInSeconds(int interval); + /** + * Sets the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout. + * + * @param interval the number of seconds that the {@link Session} should be kept alive between client requests. + */ + void setMaxInactiveIntervalInSeconds(int interval); - /** - * Gets the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout. - * - * @return the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout. - */ - int getMaxInactiveIntervalInSeconds(); + /** + * Gets the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout. + * + * @return the maximum inactive interval in seconds between requests before this session will be invalidated. A negative time indicates that the session will never timeout. + */ + int getMaxInactiveIntervalInSeconds(); - /** - * Returns true if the session is expired. - * - * @return true if the session is expired, else false. - */ - boolean isExpired(); + /** + * Returns true if the session is expired. + * + * @return true if the session is expired, else false. + */ + boolean isExpired(); } diff --git a/spring-session/src/main/java/org/springframework/session/MapSession.java b/spring-session/src/main/java/org/springframework/session/MapSession.java index bea1bf9f..b418d56b 100644 --- a/spring-session/src/main/java/org/springframework/session/MapSession.java +++ b/spring-session/src/main/java/org/springframework/session/MapSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -41,126 +41,126 @@ import java.util.concurrent.TimeUnit; * @author Rob Winch */ public final class MapSession implements ExpiringSession, Serializable { - /** - * Default {@link #setMaxInactiveIntervalInSeconds(int)} (30 minutes) - */ - public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800; + /** + * Default {@link #setMaxInactiveIntervalInSeconds(int)} (30 minutes) + */ + public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800; - private String id = UUID.randomUUID().toString(); - private Map sessionAttrs = new HashMap(); - private long creationTime = System.currentTimeMillis(); - private long lastAccessedTime = creationTime; + private String id = UUID.randomUUID().toString(); + private Map sessionAttrs = new HashMap(); + private long creationTime = System.currentTimeMillis(); + private long lastAccessedTime = creationTime; - /** - * Defaults to 30 minutes - */ - private int maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; + /** + * Defaults to 30 minutes + */ + private int maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS; - /** - * Creates a new instance - */ - public MapSession() { - } + /** + * Creates a new instance + */ + public MapSession() { + } - /** - * Creates a new instance from the provided {@link Session} - * - * @param session the {@link Session} to initialize this {@link Session} with. Cannot be null. - */ - public MapSession(ExpiringSession session) { - if(session == null) { - throw new IllegalArgumentException("session cannot be null"); - } - this.id = session.getId(); - this.sessionAttrs = new HashMap(session.getAttributeNames().size()); - for (String attrName : session.getAttributeNames()) { - Object attrValue = session.getAttribute(attrName); - this.sessionAttrs.put(attrName, attrValue); - } - this.lastAccessedTime = session.getLastAccessedTime(); - this.creationTime = session.getCreationTime(); - this.maxInactiveInterval = session.getMaxInactiveIntervalInSeconds(); - } + /** + * Creates a new instance from the provided {@link Session} + * + * @param session the {@link Session} to initialize this {@link Session} with. Cannot be null. + */ + public MapSession(ExpiringSession session) { + if(session == null) { + throw new IllegalArgumentException("session cannot be null"); + } + this.id = session.getId(); + this.sessionAttrs = new HashMap(session.getAttributeNames().size()); + for (String attrName : session.getAttributeNames()) { + Object attrValue = session.getAttribute(attrName); + this.sessionAttrs.put(attrName, attrValue); + } + this.lastAccessedTime = session.getLastAccessedTime(); + this.creationTime = session.getCreationTime(); + this.maxInactiveInterval = session.getMaxInactiveIntervalInSeconds(); + } - public void setLastAccessedTime(long lastAccessedTime) { - this.lastAccessedTime = lastAccessedTime; - } + public void setLastAccessedTime(long lastAccessedTime) { + this.lastAccessedTime = lastAccessedTime; + } - public long getCreationTime() { - return creationTime; - } + public long getCreationTime() { + return creationTime; + } - public String getId() { - return id; - } + public String getId() { + return id; + } - public long getLastAccessedTime() { - return lastAccessedTime; - } + public long getLastAccessedTime() { + return lastAccessedTime; + } - public void setMaxInactiveIntervalInSeconds(int interval) { - this.maxInactiveInterval = interval; - } + public void setMaxInactiveIntervalInSeconds(int interval) { + this.maxInactiveInterval = interval; + } - public int getMaxInactiveIntervalInSeconds() { - return maxInactiveInterval; - } + public int getMaxInactiveIntervalInSeconds() { + return maxInactiveInterval; + } - public boolean isExpired() { - return isExpired(System.currentTimeMillis()); - } + public boolean isExpired() { + return isExpired(System.currentTimeMillis()); + } - boolean isExpired(long now) { - if(maxInactiveInterval < 0) { - return false; - } - return now - TimeUnit.SECONDS.toMillis(maxInactiveInterval) >= lastAccessedTime; - } + boolean isExpired(long now) { + if(maxInactiveInterval < 0) { + return false; + } + return now - TimeUnit.SECONDS.toMillis(maxInactiveInterval) >= lastAccessedTime; + } - public Object getAttribute(String attributeName) { - return sessionAttrs.get(attributeName); - } + public Object getAttribute(String attributeName) { + return sessionAttrs.get(attributeName); + } - public Set getAttributeNames() { - return sessionAttrs.keySet(); - } + public Set getAttributeNames() { + return sessionAttrs.keySet(); + } - public void setAttribute(String attributeName, Object attributeValue) { - if (attributeValue == null) { - removeAttribute(attributeName); - } else { - sessionAttrs.put(attributeName, attributeValue); - } - } + public void setAttribute(String attributeName, Object attributeValue) { + if (attributeValue == null) { + removeAttribute(attributeName); + } else { + sessionAttrs.put(attributeName, attributeValue); + } + } - public void removeAttribute(String attributeName) { - sessionAttrs.remove(attributeName); - } + public void removeAttribute(String attributeName) { + sessionAttrs.remove(attributeName); + } - /** - * Sets the time that this {@link Session} was created in milliseconds since midnight of 1/1/1970 GMT. The default is when the {@link Session} was instantiated. - * @param creationTime the time that this {@link Session} was created in milliseconds since midnight of 1/1/1970 GMT. - */ - public void setCreationTime(long creationTime) { - this.creationTime = creationTime; - } + /** + * Sets the time that this {@link Session} was created in milliseconds since midnight of 1/1/1970 GMT. The default is when the {@link Session} was instantiated. + * @param creationTime the time that this {@link Session} was created in milliseconds since midnight of 1/1/1970 GMT. + */ + public void setCreationTime(long creationTime) { + this.creationTime = creationTime; + } - /** - * 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) { - this.id = id; - } + /** + * 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) { + this.id = id; + } - public boolean equals(Object obj) { - return obj instanceof Session && id.equals(((Session) obj).getId()); - } + public boolean equals(Object obj) { + return obj instanceof Session && id.equals(((Session) obj).getId()); + } - public int hashCode() { - return id.hashCode(); - } + public int hashCode() { + return id.hashCode(); + } - private static final long serialVersionUID = 7160779239673823561L; + private static final long serialVersionUID = 7160779239673823561L; } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/MapSessionRepository.java b/spring-session/src/main/java/org/springframework/session/MapSessionRepository.java index 7a991f7b..c4595b9e 100644 --- a/spring-session/src/main/java/org/springframework/session/MapSessionRepository.java +++ b/spring-session/src/main/java/org/springframework/session/MapSessionRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -33,67 +33,67 @@ import java.util.concurrent.ConcurrentHashMap; * @since 1.0 */ public class MapSessionRepository implements SessionRepository { - /** - * If non-null, this value is used to override {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}. - */ - private Integer defaultMaxInactiveInterval; + /** + * If non-null, this value is used to override {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}. + */ + private Integer defaultMaxInactiveInterval; - private final Map sessions; + private final Map sessions; - /** - * Creates an instance backed by a {@link java.util.concurrent.ConcurrentHashMap} - */ - public MapSessionRepository() { - this(new ConcurrentHashMap()); - } + /** + * Creates an instance backed by a {@link java.util.concurrent.ConcurrentHashMap} + */ + public MapSessionRepository() { + this(new ConcurrentHashMap()); + } - /** - * 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 sessions) { - if(sessions == null) { - throw new IllegalArgumentException("sessions cannot be null"); - } - this.sessions = sessions; - } + /** + * 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 sessions) { + if(sessions == null) { + throw new IllegalArgumentException("sessions cannot be null"); + } + this.sessions = sessions; + } - /** - * If non-null, this value is used to override {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}. - * @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between client requests. - */ - public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) { - this.defaultMaxInactiveInterval = Integer.valueOf(defaultMaxInactiveInterval); - } + /** + * If non-null, this value is used to override {@link ExpiringSession#setMaxInactiveIntervalInSeconds(int)}. + * @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between client requests. + */ + public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) { + this.defaultMaxInactiveInterval = Integer.valueOf(defaultMaxInactiveInterval); + } - public void save(ExpiringSession session) { - sessions.put(session.getId(), new MapSession(session)); - } + public void save(ExpiringSession session) { + sessions.put(session.getId(), new MapSession(session)); + } - public ExpiringSession getSession(String id) { - ExpiringSession saved = sessions.get(id); - if(saved == null) { - return null; - } - if(saved.isExpired()) { - delete(saved.getId()); - return null; - } - MapSession result = new MapSession(saved); - result.setLastAccessedTime(System.currentTimeMillis()); - return result; - } + public ExpiringSession getSession(String id) { + ExpiringSession saved = sessions.get(id); + if(saved == null) { + return null; + } + if(saved.isExpired()) { + delete(saved.getId()); + return null; + } + MapSession result = new MapSession(saved); + result.setLastAccessedTime(System.currentTimeMillis()); + return result; + } - public void delete(String id) { - sessions.remove(id); - } + public void delete(String id) { + sessions.remove(id); + } - public ExpiringSession createSession() { - ExpiringSession result = new MapSession(); - if(defaultMaxInactiveInterval != null) { - result.setMaxInactiveIntervalInSeconds(defaultMaxInactiveInterval); - } - return result; - } + public ExpiringSession createSession() { + ExpiringSession result = new MapSession(); + if(defaultMaxInactiveInterval != null) { + result.setMaxInactiveIntervalInSeconds(defaultMaxInactiveInterval); + } + return result; + } } diff --git a/spring-session/src/main/java/org/springframework/session/Session.java b/spring-session/src/main/java/org/springframework/session/Session.java index c6bc4883..7f94c2eb 100644 --- a/spring-session/src/main/java/org/springframework/session/Session.java +++ b/spring-session/src/main/java/org/springframework/session/Session.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -26,41 +26,41 @@ import java.util.Set; */ public interface Session { - /** - * Gets a unique string that identifies the {@link Session} - * - * @return a unique string that identifies the {@link Session} - */ - String getId(); + /** + * Gets a unique string that identifies the {@link Session} + * + * @return a unique string that identifies the {@link Session} + */ + String getId(); - /** - * Gets the Object associated with the specified name or null if no Object is associated to that name. - * - * @param attributeName the name of the attribute to get - * @return the Object associated with the specified name or null if no Object is associated to that name - * @param The return type of the attribute - */ - T getAttribute(String attributeName); + /** + * Gets the Object associated with the specified name or null if no Object is associated to that name. + * + * @param attributeName the name of the attribute to get + * @return the Object associated with the specified name or null if no Object is associated to that name + * @param The return type of the attribute + */ + T getAttribute(String attributeName); - /** - * 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) - */ - Set getAttributeNames(); + /** + * 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) + */ + Set getAttributeNames(); - /** - * 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. - */ - void setAttribute(String attributeName, Object attributeValue); + /** + * 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. + */ + void setAttribute(String attributeName, Object attributeValue); - /** - * Removes the attribute with the provided attribute name - * @param attributeName the name of the attribute to remove - */ - void removeAttribute(String attributeName); + /** + * Removes the attribute with the provided attribute name + * @param attributeName the name of the attribute to remove + */ + void removeAttribute(String attributeName); } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/SessionRepository.java b/spring-session/src/main/java/org/springframework/session/SessionRepository.java index c108f1ca..66da4f16 100644 --- a/spring-session/src/main/java/org/springframework/session/SessionRepository.java +++ b/spring-session/src/main/java/org/springframework/session/SessionRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -23,46 +23,46 @@ package org.springframework.session; */ public interface SessionRepository { - /** - * Creates a new {@link Session} that is capable of being persisted by this {@link SessionRepository}. - * - *

This allows optimizations and customizations in how the {@link Session} is persisted. For example, the - * implementation returned might keep track of the changes ensuring that only the delta needs to be persisted on - * a save.

- * - * @return a new {@link Session} that is capable of being persisted by this {@link SessionRepository} - */ - S createSession(); + /** + * Creates a new {@link Session} that is capable of being persisted by this {@link SessionRepository}. + * + *

This allows optimizations and customizations in how the {@link Session} is persisted. For example, the + * implementation returned might keep track of the changes ensuring that only the delta needs to be persisted on + * a save.

+ * + * @return a new {@link Session} that is capable of being persisted by this {@link SessionRepository} + */ + S createSession(); - /** - * Ensures the {@link Session} created by {@link org.springframework.session.SessionRepository#createSession()} is saved. - * - *

- * Some implementations may choose to save as the {@link Session} is updated by returning a {@link Session} that - * immediately persists any changes. In this case, this method may not actually do anything. - *

- * - * @param session the {@link Session} to save - */ - void save(S session); + /** + * Ensures the {@link Session} created by {@link org.springframework.session.SessionRepository#createSession()} is saved. + * + *

+ * Some implementations may choose to save as the {@link Session} is updated by returning a {@link Session} that + * immediately persists any changes. In this case, this method may not actually do anything. + *

+ * + * @param session the {@link Session} to save + */ + void save(S session); - /** - * Gets the {@link Session} by the {@link Session#getId()} or null if no {@link Session} is found. - * - *

- * If the {@link Session} extends {@link ExpiringSession}, then {@link ExpiringSession#getLastAccessedTime()} will be - * updated on the returned object. In order to persist this change, {@link #save(Session)} must be invoked on the returned - * instance. - *

- * - * @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. - */ - S getSession(String id); + /** + * Gets the {@link Session} by the {@link Session#getId()} or null if no {@link Session} is found. + * + *

+ * If the {@link Session} extends {@link ExpiringSession}, then {@link ExpiringSession#getLastAccessedTime()} will be + * updated on the returned object. In order to persist this change, {@link #save(Session)} must be invoked on the returned + * instance. + *

+ * + * @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. + */ + S getSession(String id); - /** - * Deletes the {@link Session} with the given {@link Session#getId()} or does nothing if the {@link Session} is not found. - * @param id the {@link org.springframework.session.Session#getId()} to delete - */ - void delete(String id); + /** + * Deletes the {@link Session} with the given {@link Session#getId()} or does nothing if the {@link Session} is not found. + * @param id the {@link org.springframework.session.Session#getId()} to delete + */ + void delete(String id); } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java b/spring-session/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java index e9335543..7d33747d 100644 --- a/spring-session/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java +++ b/spring-session/src/main/java/org/springframework/session/data/redis/RedisOperationsSessionRepository.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -139,277 +139,277 @@ import org.springframework.util.Assert; * @author Rob Winch */ public class RedisOperationsSessionRepository implements SessionRepository { - /** - * The prefix for each key of the Redis Hash representing a single session. The suffix is the unique session id. - */ - static final String BOUNDED_HASH_KEY_PREFIX = "spring:session:sessions:"; + /** + * The prefix for each key of the Redis Hash representing a single session. The suffix is the unique session id. + */ + static final String BOUNDED_HASH_KEY_PREFIX = "spring:session:sessions:"; - /** - * The key in the Hash representing {@link org.springframework.session.ExpiringSession#getCreationTime()} - */ - static final String CREATION_TIME_ATTR = "creationTime"; + /** + * The key in the Hash representing {@link org.springframework.session.ExpiringSession#getCreationTime()} + */ + static final String CREATION_TIME_ATTR = "creationTime"; - /** - * The key in the Hash representing {@link org.springframework.session.ExpiringSession#getMaxInactiveIntervalInSeconds()} - */ - static final String MAX_INACTIVE_ATTR = "maxInactiveInterval"; + /** + * The key in the Hash representing {@link org.springframework.session.ExpiringSession#getMaxInactiveIntervalInSeconds()} + */ + static final String MAX_INACTIVE_ATTR = "maxInactiveInterval"; - /** - * The key in the Hash representing {@link org.springframework.session.ExpiringSession#getLastAccessedTime()} - */ - static final String LAST_ACCESSED_ATTR = "lastAccessedTime"; + /** + * The key in the Hash representing {@link org.springframework.session.ExpiringSession#getLastAccessedTime()} + */ + static final String LAST_ACCESSED_ATTR = "lastAccessedTime"; - /** - * The prefix of the key for used for session attributes. The suffix is the name of the session attribute. For - * example, if the session contained an attribute named attributeName, then there would be an entry in the hash named - * sessionAttr:attributeName that mapped to its value. - */ - static final String SESSION_ATTR_PREFIX = "sessionAttr:"; + /** + * The prefix of the key for used for session attributes. The suffix is the name of the session attribute. For + * example, if the session contained an attribute named attributeName, then there would be an entry in the hash named + * sessionAttr:attributeName that mapped to its value. + */ + static final String SESSION_ATTR_PREFIX = "sessionAttr:"; - private final RedisOperations sessionRedisOperations; + private final RedisOperations sessionRedisOperations; - private final RedisSessionExpirationPolicy expirationPolicy; + private final RedisSessionExpirationPolicy expirationPolicy; - /** - * If non-null, this value is used to override the default value for {@link RedisSession#setMaxInactiveIntervalInSeconds(int)}. - */ - private Integer defaultMaxInactiveInterval; + /** + * If non-null, this value is used to override the default value for {@link RedisSession#setMaxInactiveIntervalInSeconds(int)}. + */ + private Integer defaultMaxInactiveInterval; - /** - * Allows creating an instance and uses a default {@link RedisOperations} for both managing the session and the expirations. - * - * @param redisConnectionFactory the {@link RedisConnectionFactory} to use. - */ - @SuppressWarnings("unchecked") - public RedisOperationsSessionRepository(RedisConnectionFactory redisConnectionFactory) { - this(createDefaultTemplate(redisConnectionFactory)); - } + /** + * Allows creating an instance and uses a default {@link RedisOperations} for both managing the session and the expirations. + * + * @param redisConnectionFactory the {@link RedisConnectionFactory} to use. + */ + @SuppressWarnings("unchecked") + public RedisOperationsSessionRepository(RedisConnectionFactory redisConnectionFactory) { + this(createDefaultTemplate(redisConnectionFactory)); + } - /** - * Creates a new instance. For an example, refer to the class level javadoc. - * - * @param sessionRedisOperations The {@link RedisOperations} to use for managing the sessions. Cannot be null. - */ - public RedisOperationsSessionRepository(RedisOperations sessionRedisOperations) { - Assert.notNull(sessionRedisOperations, "sessionRedisOperations cannot be null"); - this.sessionRedisOperations = sessionRedisOperations; - this.expirationPolicy = new RedisSessionExpirationPolicy(sessionRedisOperations); - } + /** + * Creates a new instance. For an example, refer to the class level javadoc. + * + * @param sessionRedisOperations The {@link RedisOperations} to use for managing the sessions. Cannot be null. + */ + public RedisOperationsSessionRepository(RedisOperations sessionRedisOperations) { + Assert.notNull(sessionRedisOperations, "sessionRedisOperations cannot be null"); + this.sessionRedisOperations = sessionRedisOperations; + this.expirationPolicy = new RedisSessionExpirationPolicy(sessionRedisOperations); + } - /** - * Sets the maximum inactive interval in seconds between requests before newly created sessions will be - * invalidated. A negative time indicates that the session will never timeout. The default is 1800 (30 minutes). - * - * @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between - * client requests. - */ - public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) { - this.defaultMaxInactiveInterval = defaultMaxInactiveInterval; - } + /** + * Sets the maximum inactive interval in seconds between requests before newly created sessions will be + * invalidated. A negative time indicates that the session will never timeout. The default is 1800 (30 minutes). + * + * @param defaultMaxInactiveInterval the number of seconds that the {@link Session} should be kept alive between + * client requests. + */ + public void setDefaultMaxInactiveInterval(int defaultMaxInactiveInterval) { + this.defaultMaxInactiveInterval = defaultMaxInactiveInterval; + } - public void save(RedisSession session) { - session.saveDelta(); - } + public void save(RedisSession session) { + session.saveDelta(); + } - @Scheduled(cron="0 * * * * *") - public void cleanupExpiredSessions() { - this.expirationPolicy.cleanExpiredSessions(); - } + @Scheduled(cron="0 * * * * *") + public void cleanupExpiredSessions() { + this.expirationPolicy.cleanExpiredSessions(); + } - public RedisSession getSession(String id) { - return getSession(id, false); - } + public RedisSession getSession(String id) { + return getSession(id, false); + } - /** - * - * @param id the session id - * @param allowExpired - * if true, will also include expired sessions that have not been - * deleted. If false, will ensure expired sessions are not - * returned. - * @return - */ - private RedisSession getSession(String id, boolean allowExpired) { - Map entries = getSessionBoundHashOperations(id).entries(); - if(entries.isEmpty()) { - return null; - } - MapSession loaded = new MapSession(); - loaded.setId(id); - for(Map.Entry entry : entries.entrySet()) { - String key = (String) entry.getKey(); - if(CREATION_TIME_ATTR.equals(key)) { - loaded.setCreationTime((Long) entry.getValue()); - } else if(MAX_INACTIVE_ATTR.equals(key)) { - loaded.setMaxInactiveIntervalInSeconds((Integer) entry.getValue()); - } else if(LAST_ACCESSED_ATTR.equals(key)) { - loaded.setLastAccessedTime((Long) entry.getValue()); - } else if(key.startsWith(SESSION_ATTR_PREFIX)) { - loaded.setAttribute(key.substring(SESSION_ATTR_PREFIX.length()), entry.getValue()); - } - } - if(!allowExpired && loaded.isExpired()) { - return null; - } - RedisSession result = new RedisSession(loaded); - result.originalLastAccessTime = loaded.getLastAccessedTime() + TimeUnit.SECONDS.toMillis(loaded.getMaxInactiveIntervalInSeconds()); - result.setLastAccessedTime(System.currentTimeMillis()); - return result; - } + /** + * + * @param id the session id + * @param allowExpired + * if true, will also include expired sessions that have not been + * deleted. If false, will ensure expired sessions are not + * returned. + * @return + */ + private RedisSession getSession(String id, boolean allowExpired) { + Map entries = getSessionBoundHashOperations(id).entries(); + if(entries.isEmpty()) { + return null; + } + MapSession loaded = new MapSession(); + loaded.setId(id); + for(Map.Entry entry : entries.entrySet()) { + String key = (String) entry.getKey(); + if(CREATION_TIME_ATTR.equals(key)) { + loaded.setCreationTime((Long) entry.getValue()); + } else if(MAX_INACTIVE_ATTR.equals(key)) { + loaded.setMaxInactiveIntervalInSeconds((Integer) entry.getValue()); + } else if(LAST_ACCESSED_ATTR.equals(key)) { + loaded.setLastAccessedTime((Long) entry.getValue()); + } else if(key.startsWith(SESSION_ATTR_PREFIX)) { + loaded.setAttribute(key.substring(SESSION_ATTR_PREFIX.length()), entry.getValue()); + } + } + if(!allowExpired && loaded.isExpired()) { + return null; + } + RedisSession result = new RedisSession(loaded); + result.originalLastAccessTime = loaded.getLastAccessedTime() + TimeUnit.SECONDS.toMillis(loaded.getMaxInactiveIntervalInSeconds()); + result.setLastAccessedTime(System.currentTimeMillis()); + return result; + } - public void delete(String sessionId) { - ExpiringSession session = getSession(sessionId, true); - if(session == null) { - return; - } + public void delete(String sessionId) { + ExpiringSession session = getSession(sessionId, true); + if(session == null) { + return; + } - String key = getKey(sessionId); - expirationPolicy.onDelete(session); + String key = getKey(sessionId); + expirationPolicy.onDelete(session); - // always delete they key since session may be null if just expired - this.sessionRedisOperations.delete(key); - } + // always delete they key since session may be null if just expired + this.sessionRedisOperations.delete(key); + } - public RedisSession createSession() { - RedisSession redisSession = new RedisSession(); - if(defaultMaxInactiveInterval != null) { - redisSession.setMaxInactiveIntervalInSeconds(defaultMaxInactiveInterval); - } - return redisSession; - } + public RedisSession createSession() { + RedisSession redisSession = new RedisSession(); + if(defaultMaxInactiveInterval != null) { + redisSession.setMaxInactiveIntervalInSeconds(defaultMaxInactiveInterval); + } + return redisSession; + } - /** - * Gets the Hash key for this session by prefixing it appropriately. - * - * @param sessionId the session id - * @return the Hash key for this session by prefixing it appropriately. - */ - static String getKey(String sessionId) { - return BOUNDED_HASH_KEY_PREFIX + sessionId; - } + /** + * Gets the Hash key for this session by prefixing it appropriately. + * + * @param sessionId the session id + * @return the Hash key for this session by prefixing it appropriately. + */ + static String getKey(String sessionId) { + return BOUNDED_HASH_KEY_PREFIX + sessionId; + } - /** - * Gets the key for the specified session attribute - * - * @param attributeName - * @return - */ - static String getSessionAttrNameKey(String attributeName) { - return SESSION_ATTR_PREFIX + attributeName; - } + /** + * Gets the key for the specified session attribute + * + * @param attributeName + * @return + */ + static String getSessionAttrNameKey(String attributeName) { + return SESSION_ATTR_PREFIX + attributeName; + } - /** - * Gets the {@link BoundHashOperations} to operate on a {@link Session} - * @param sessionId the id of the {@link Session} to work with - * @return the {@link BoundHashOperations} to operate on a {@link Session} - */ - private BoundHashOperations getSessionBoundHashOperations(String sessionId) { - String key = getKey(sessionId); - return this.sessionRedisOperations.boundHashOps(key); - } + /** + * Gets the {@link BoundHashOperations} to operate on a {@link Session} + * @param sessionId the id of the {@link Session} to work with + * @return the {@link BoundHashOperations} to operate on a {@link Session} + */ + private BoundHashOperations getSessionBoundHashOperations(String sessionId) { + String key = getKey(sessionId); + return this.sessionRedisOperations.boundHashOps(key); + } - @SuppressWarnings("rawtypes") - private static RedisTemplate createDefaultTemplate(RedisConnectionFactory connectionFactory) { - Assert.notNull(connectionFactory,"connectionFactory cannot be null"); - RedisTemplate template = new RedisTemplate(); - template.setKeySerializer(new StringRedisSerializer()); - template.setHashKeySerializer(new StringRedisSerializer()); - template.setConnectionFactory(connectionFactory); - template.afterPropertiesSet(); - return template; - } + @SuppressWarnings("rawtypes") + private static RedisTemplate createDefaultTemplate(RedisConnectionFactory connectionFactory) { + Assert.notNull(connectionFactory,"connectionFactory cannot be null"); + RedisTemplate template = new RedisTemplate(); + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setConnectionFactory(connectionFactory); + template.afterPropertiesSet(); + return template; + } - /** - * A custom implementation of {@link Session} that uses a {@link MapSession} as the basis for its mapping. It keeps - * track of any attributes that have changed. When - * {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession#saveDelta()} is invoked - * all the attributes that have been changed will be persisted. - * - * @since 1.0 - * @author Rob Winch - */ - final class RedisSession implements ExpiringSession { - private final MapSession cached; - private Long originalLastAccessTime; - private Map delta = new HashMap(); + /** + * A custom implementation of {@link Session} that uses a {@link MapSession} as the basis for its mapping. It keeps + * track of any attributes that have changed. When + * {@link org.springframework.session.data.redis.RedisOperationsSessionRepository.RedisSession#saveDelta()} is invoked + * all the attributes that have been changed will be persisted. + * + * @since 1.0 + * @author Rob Winch + */ + final class RedisSession implements ExpiringSession { + private final MapSession cached; + private Long originalLastAccessTime; + private Map delta = new HashMap(); - /** - * Creates a new instance ensuring to mark all of the new attributes to be persisted in the next save operation. - */ - RedisSession() { - this(new MapSession()); - delta.put(CREATION_TIME_ATTR, getCreationTime()); - delta.put(MAX_INACTIVE_ATTR, getMaxInactiveIntervalInSeconds()); - delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime()); - } + /** + * Creates a new instance ensuring to mark all of the new attributes to be persisted in the next save operation. + */ + RedisSession() { + this(new MapSession()); + delta.put(CREATION_TIME_ATTR, getCreationTime()); + delta.put(MAX_INACTIVE_ATTR, getMaxInactiveIntervalInSeconds()); + delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime()); + } - /** - * Creates a new instance from the provided {@link MapSession} - * - * @param cached the {@MapSession} that represents the persisted session that was retrieved. Cannot be null. - */ - RedisSession(MapSession cached) { - Assert.notNull("MapSession cannot be null"); - this.cached = cached; - } + /** + * Creates a new instance from the provided {@link MapSession} + * + * @param cached the {@MapSession} that represents the persisted session that was retrieved. Cannot be null. + */ + RedisSession(MapSession cached) { + Assert.notNull("MapSession cannot be null"); + this.cached = cached; + } - public void setLastAccessedTime(long lastAccessedTime) { - cached.setLastAccessedTime(lastAccessedTime); - delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime()); - } + public void setLastAccessedTime(long lastAccessedTime) { + cached.setLastAccessedTime(lastAccessedTime); + delta.put(LAST_ACCESSED_ATTR, getLastAccessedTime()); + } - public boolean isExpired() { - return cached.isExpired(); - } + public boolean isExpired() { + return cached.isExpired(); + } - public long getCreationTime() { - return cached.getCreationTime(); - } + public long getCreationTime() { + return cached.getCreationTime(); + } - public String getId() { - return cached.getId(); - } + public String getId() { + return cached.getId(); + } - public long getLastAccessedTime() { - return cached.getLastAccessedTime(); - } + public long getLastAccessedTime() { + return cached.getLastAccessedTime(); + } - public void setMaxInactiveIntervalInSeconds(int interval) { - cached.setMaxInactiveIntervalInSeconds(interval); - delta.put(MAX_INACTIVE_ATTR, getMaxInactiveIntervalInSeconds()); - } + public void setMaxInactiveIntervalInSeconds(int interval) { + cached.setMaxInactiveIntervalInSeconds(interval); + delta.put(MAX_INACTIVE_ATTR, getMaxInactiveIntervalInSeconds()); + } - public int getMaxInactiveIntervalInSeconds() { - return cached.getMaxInactiveIntervalInSeconds(); - } + public int getMaxInactiveIntervalInSeconds() { + return cached.getMaxInactiveIntervalInSeconds(); + } - public Object getAttribute(String attributeName) { - return cached.getAttribute(attributeName); - } + public Object getAttribute(String attributeName) { + return cached.getAttribute(attributeName); + } - public Set getAttributeNames() { - return cached.getAttributeNames(); - } + public Set getAttributeNames() { + return cached.getAttributeNames(); + } - public void setAttribute(String attributeName, Object attributeValue) { - cached.setAttribute(attributeName, attributeValue); - delta.put(getSessionAttrNameKey(attributeName), attributeValue); - } + public void setAttribute(String attributeName, Object attributeValue) { + cached.setAttribute(attributeName, attributeValue); + delta.put(getSessionAttrNameKey(attributeName), attributeValue); + } - public void removeAttribute(String attributeName) { - cached.removeAttribute(attributeName); - delta.put(getSessionAttrNameKey(attributeName), null); - } + public void removeAttribute(String attributeName) { + cached.removeAttribute(attributeName); + delta.put(getSessionAttrNameKey(attributeName), null); + } - /** - * Saves any attributes that have been changed and updates the expiration of this session. - */ - private void saveDelta() { - String sessionId = getId(); - getSessionBoundHashOperations(sessionId).putAll(delta); - delta = new HashMap(delta.size()); + /** + * Saves any attributes that have been changed and updates the expiration of this session. + */ + private void saveDelta() { + String sessionId = getId(); + getSessionBoundHashOperations(sessionId).putAll(delta); + delta = new HashMap(delta.size()); - expirationPolicy.onExpirationUpdated(originalLastAccessTime, this); - } - } + expirationPolicy.onExpirationUpdated(originalLastAccessTime, this); + } + } } diff --git a/spring-session/src/main/java/org/springframework/session/data/redis/RedisSessionExpirationPolicy.java b/spring-session/src/main/java/org/springframework/session/data/redis/RedisSessionExpirationPolicy.java index c8727030..0bed91f5 100644 --- a/spring-session/src/main/java/org/springframework/session/data/redis/RedisSessionExpirationPolicy.java +++ b/spring-session/src/main/java/org/springframework/session/data/redis/RedisSessionExpirationPolicy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -17,7 +17,6 @@ package org.springframework.session.data.redis; import java.util.Calendar; import java.util.Date; -import java.util.HashSet; import java.util.Set; import java.util.concurrent.TimeUnit; @@ -46,101 +45,102 @@ import org.springframework.session.data.redis.RedisOperationsSessionRepository.R */ final class RedisSessionExpirationPolicy { - private static final Log logger = LogFactory.getLog(RedisOperationsSessionRepository.class); + private static final Log logger = LogFactory.getLog(RedisOperationsSessionRepository.class); - /** - * The prefix for each key of the Redis Hash representing a single session. The suffix is the unique session id. - */ - static final String EXPIRATION_BOUNDED_HASH_KEY_PREFIX = "spring:session:expirations:"; + /** + * The prefix for each key of the Redis Hash representing a single session. The suffix is the unique session id. + */ + static final String EXPIRATION_BOUNDED_HASH_KEY_PREFIX = "spring:session:expirations:"; - private final RedisOperations sessionRedisOperations; + private final RedisOperations sessionRedisOperations; - private final RedisOperations expirationRedisOperations; + private final RedisOperations expirationRedisOperations; - public RedisSessionExpirationPolicy( - RedisOperations sessionRedisOperations) { - super(); - this.sessionRedisOperations = sessionRedisOperations; - this.expirationRedisOperations = sessionRedisOperations; - } + @SuppressWarnings({ "rawtypes", "unchecked" }) + public RedisSessionExpirationPolicy( + RedisOperations sessionRedisOperations) { + super(); + this.sessionRedisOperations = sessionRedisOperations; + this.expirationRedisOperations = sessionRedisOperations; + } - public void onDelete(ExpiringSession session) { - long lastAccessedTime = session.getLastAccessedTime(); - int maxInactiveInterval = session.getMaxInactiveIntervalInSeconds(); + public void onDelete(ExpiringSession session) { + long lastAccessedTime = session.getLastAccessedTime(); + int maxInactiveInterval = session.getMaxInactiveIntervalInSeconds(); - long toExpire = roundUpToNextMinute(lastAccessedTime, maxInactiveInterval); - String expireKey = getExpirationKey(toExpire); - expirationRedisOperations.boundSetOps(expireKey).remove(session.getId()); - } + long toExpire = roundUpToNextMinute(lastAccessedTime, maxInactiveInterval); + String expireKey = getExpirationKey(toExpire); + expirationRedisOperations.boundSetOps(expireKey).remove(session.getId()); + } - public void onExpirationUpdated(Long originalExpirationTime, ExpiringSession session) { - if(originalExpirationTime != null) { - String expireKey = getExpirationKey(originalExpirationTime); - expirationRedisOperations.boundSetOps(expireKey).remove(session.getId()); - } + public void onExpirationUpdated(Long originalExpirationTime, ExpiringSession session) { + if(originalExpirationTime != null) { + String expireKey = getExpirationKey(originalExpirationTime); + expirationRedisOperations.boundSetOps(expireKey).remove(session.getId()); + } - long toExpire = roundUpToNextMinute(session.getLastAccessedTime(), session.getMaxInactiveIntervalInSeconds()); + long toExpire = roundUpToNextMinute(session.getLastAccessedTime(), session.getMaxInactiveIntervalInSeconds()); - String expireKey = getExpirationKey(toExpire); - expirationRedisOperations.boundSetOps(expireKey).add(session.getId()); + String expireKey = getExpirationKey(toExpire); + expirationRedisOperations.boundSetOps(expireKey).add(session.getId()); - long redisExpirationInSeconds = session.getMaxInactiveIntervalInSeconds(); - String sessionKey = getSessionKey(session.getId()); - expirationRedisOperations.boundSetOps(expireKey).expire(redisExpirationInSeconds, TimeUnit.SECONDS); - sessionRedisOperations.boundHashOps(sessionKey).expire(redisExpirationInSeconds, TimeUnit.SECONDS); - } + long redisExpirationInSeconds = session.getMaxInactiveIntervalInSeconds(); + String sessionKey = getSessionKey(session.getId()); + expirationRedisOperations.boundSetOps(expireKey).expire(redisExpirationInSeconds, TimeUnit.SECONDS); + sessionRedisOperations.boundHashOps(sessionKey).expire(redisExpirationInSeconds, TimeUnit.SECONDS); + } - private String getExpirationKey(long expires) { - return EXPIRATION_BOUNDED_HASH_KEY_PREFIX + expires; - } + private String getExpirationKey(long expires) { + return EXPIRATION_BOUNDED_HASH_KEY_PREFIX + expires; + } - private String getSessionKey(String sessionId) { - return RedisOperationsSessionRepository.BOUNDED_HASH_KEY_PREFIX + sessionId; - } + private String getSessionKey(String sessionId) { + return RedisOperationsSessionRepository.BOUNDED_HASH_KEY_PREFIX + sessionId; + } - public void cleanExpiredSessions() { - long now = System.currentTimeMillis(); - long prevMin = roundDownMinute(now); + public void cleanExpiredSessions() { + long now = System.currentTimeMillis(); + long prevMin = roundDownMinute(now); - if(logger.isDebugEnabled()) { - logger.debug("Cleaning up sessions expiring at "+ new Date(prevMin)); - } + if(logger.isDebugEnabled()) { + logger.debug("Cleaning up sessions expiring at "+ new Date(prevMin)); + } - String expirationKey = getExpirationKey(prevMin); - Set sessionsToExpire = expirationRedisOperations.boundSetOps(expirationKey).members(); - touch(expirationKey); - for(String session : sessionsToExpire) { - String sessionKey = getSessionKey(session); - touch(sessionKey); - } - } + String expirationKey = getExpirationKey(prevMin); + Set sessionsToExpire = expirationRedisOperations.boundSetOps(expirationKey).members(); + touch(expirationKey); + for(String session : sessionsToExpire) { + String sessionKey = getSessionKey(session); + touch(sessionKey); + } + } - /** - * By trying to access the session we only trigger a deletion if it the TTL is expired. This is done to handle - * https://github.com/spring-projects/spring-session/issues/93 - * - * @param key - */ - private void touch(String key) { - sessionRedisOperations.hasKey(key); - } + /** + * By trying to access the session we only trigger a deletion if it the TTL is expired. This is done to handle + * https://github.com/spring-projects/spring-session/issues/93 + * + * @param key + */ + private void touch(String key) { + sessionRedisOperations.hasKey(key); + } - private long roundUpToNextMinute(long timeInMs, int inactiveIntervalInSec) { + private long roundUpToNextMinute(long timeInMs, int inactiveIntervalInSec) { - Calendar date = Calendar.getInstance(); - date.setTimeInMillis(timeInMs + TimeUnit.SECONDS.toMillis(inactiveIntervalInSec)); - date.add(Calendar.MINUTE, 1); - date.clear(Calendar.SECOND); - date.clear(Calendar.MILLISECOND); - return date.getTimeInMillis(); - } + Calendar date = Calendar.getInstance(); + date.setTimeInMillis(timeInMs + TimeUnit.SECONDS.toMillis(inactiveIntervalInSec)); + date.add(Calendar.MINUTE, 1); + date.clear(Calendar.SECOND); + date.clear(Calendar.MILLISECOND); + return date.getTimeInMillis(); + } - private long roundDownMinute(long timeInMs) { - Calendar date = Calendar.getInstance(); - date.setTimeInMillis(timeInMs); - date.add(Calendar.MINUTE, -1); - date.clear(Calendar.SECOND); - date.clear(Calendar.MILLISECOND); - return date.getTimeInMillis(); - } + private long roundDownMinute(long timeInMs) { + Calendar date = Calendar.getInstance(); + date.setTimeInMillis(timeInMs); + date.add(Calendar.MINUTE, -1); + date.clear(Calendar.SECOND); + date.clear(Calendar.MILLISECOND); + return date.getTimeInMillis(); + } } diff --git a/spring-session/src/main/java/org/springframework/session/data/redis/SessionMessageListener.java b/spring-session/src/main/java/org/springframework/session/data/redis/SessionMessageListener.java index 74ec7206..a019272c 100644 --- a/spring-session/src/main/java/org/springframework/session/data/redis/SessionMessageListener.java +++ b/spring-session/src/main/java/org/springframework/session/data/redis/SessionMessageListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -32,53 +32,53 @@ import org.springframework.util.Assert; * @since 1.0 */ public class SessionMessageListener implements MessageListener { - private static final Log logger = LogFactory.getLog(SessionMessageListener.class); + private static final Log logger = LogFactory.getLog(SessionMessageListener.class); - private final ApplicationEventPublisher eventPublisher; + private final ApplicationEventPublisher eventPublisher; - /** - * Creates a new instance - * - * @param eventPublisher the {@link ApplicationEventPublisher} to use. Cannot be null. - */ - public SessionMessageListener(ApplicationEventPublisher eventPublisher) { - Assert.notNull(eventPublisher, "eventPublisher cannot be null"); - this.eventPublisher = eventPublisher; - } + /** + * Creates a new instance + * + * @param eventPublisher the {@link ApplicationEventPublisher} to use. Cannot be null. + */ + public SessionMessageListener(ApplicationEventPublisher eventPublisher) { + Assert.notNull(eventPublisher, "eventPublisher cannot be null"); + this.eventPublisher = eventPublisher; + } - public void onMessage(Message message, byte[] pattern) { - byte[] messageChannel = message.getChannel(); - byte[] messageBody = message.getBody(); - if(messageChannel == null || messageBody == null) { - return; - } - String channel = new String(messageChannel); - if(!(channel.endsWith(":del") || channel.endsWith(":expired"))) { - return; - } - String body = new String(messageBody); - if(!body.startsWith("spring:session:sessions:")) { - return; - } + public void onMessage(Message message, byte[] pattern) { + byte[] messageChannel = message.getChannel(); + byte[] messageBody = message.getBody(); + if(messageChannel == null || messageBody == null) { + return; + } + String channel = new String(messageChannel); + if(!(channel.endsWith(":del") || channel.endsWith(":expired"))) { + return; + } + String body = new String(messageBody); + if(!body.startsWith("spring:session:sessions:")) { + return; + } - int beginIndex = body.lastIndexOf(":") + 1; - int endIndex = body.length(); - String sessionId = body.substring(beginIndex, endIndex); + int beginIndex = body.lastIndexOf(":") + 1; + int endIndex = body.length(); + String sessionId = body.substring(beginIndex, endIndex); - if(logger.isDebugEnabled()) { - logger.debug("Publishing SessionDestroyedEvent for session " + sessionId); - } + if(logger.isDebugEnabled()) { + logger.debug("Publishing SessionDestroyedEvent for session " + sessionId); + } - publishEvent(new SessionDestroyedEvent(this, sessionId)); - } + publishEvent(new SessionDestroyedEvent(this, sessionId)); + } - private void publishEvent(ApplicationEvent event) { - try { - this.eventPublisher.publishEvent(event); - } - catch (Throwable ex) { - logger.error("Error publishing " + event + ".", ex); - } - } + private void publishEvent(ApplicationEvent event) { + try { + this.eventPublisher.publishEvent(event); + } + catch (Throwable ex) { + logger.error("Error publishing " + event + ".", ex); + } + } } diff --git a/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java b/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java index cb289307..9f1c65e1 100644 --- a/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java +++ b/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisHttpSession.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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. @@ -53,5 +53,5 @@ import org.springframework.data.redis.connection.RedisConnectionFactory; @Import(RedisHttpSessionConfiguration.class) @Configuration public @interface EnableRedisHttpSession { - int maxInactiveIntervalInSeconds() default 1800; + int maxInactiveIntervalInSeconds() default 1800; } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java b/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java index cbeb4dfc..d4eea24f 100644 --- a/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java +++ b/spring-session/src/main/java/org/springframework/session/data/redis/config/annotation/web/http/RedisHttpSessionConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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. @@ -22,7 +22,6 @@ import java.util.Map; import org.springframework.beans.factory.BeanClassLoaderAware; import org.springframework.beans.factory.InitializingBean; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.context.ApplicationEventPublisher; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @@ -59,132 +58,132 @@ import org.springframework.util.ClassUtils; @EnableScheduling public class RedisHttpSessionConfiguration implements ImportAware, BeanClassLoaderAware { - private ClassLoader beanClassLoader; + private ClassLoader beanClassLoader; - private Integer maxInactiveIntervalInSeconds; + private Integer maxInactiveIntervalInSeconds; - private HttpSessionStrategy httpSessionStrategy; + private HttpSessionStrategy httpSessionStrategy; - @Autowired - private ApplicationEventPublisher eventPublisher; + @Autowired + private ApplicationEventPublisher eventPublisher; - @Bean - public RedisMessageListenerContainer redisMessageListenerContainer( - RedisConnectionFactory connectionFactory) { - RedisMessageListenerContainer container = new RedisMessageListenerContainer(); - container.setConnectionFactory(connectionFactory); - container.addMessageListener(redisSessionMessageListener(), - Arrays.asList(new PatternTopic("__keyevent@*:del"),new PatternTopic("__keyevent@*:expired"))); - return container; - } + @Bean + public RedisMessageListenerContainer redisMessageListenerContainer( + RedisConnectionFactory connectionFactory) { + RedisMessageListenerContainer container = new RedisMessageListenerContainer(); + container.setConnectionFactory(connectionFactory); + container.addMessageListener(redisSessionMessageListener(), + Arrays.asList(new PatternTopic("__keyevent@*:del"),new PatternTopic("__keyevent@*:expired"))); + return container; + } - @Bean - public SessionMessageListener redisSessionMessageListener() { - return new SessionMessageListener(eventPublisher); - } + @Bean + public SessionMessageListener redisSessionMessageListener() { + return new SessionMessageListener(eventPublisher); + } - @Bean - public RedisTemplate sessionRedisTemplate(RedisConnectionFactory connectionFactory) { - RedisTemplate template = new RedisTemplate(); - template.setKeySerializer(new StringRedisSerializer()); - template.setHashKeySerializer(new StringRedisSerializer()); - template.setConnectionFactory(connectionFactory); - return template; - } + @Bean + public RedisTemplate sessionRedisTemplate(RedisConnectionFactory connectionFactory) { + RedisTemplate template = new RedisTemplate(); + template.setKeySerializer(new StringRedisSerializer()); + template.setHashKeySerializer(new StringRedisSerializer()); + template.setConnectionFactory(connectionFactory); + return template; + } - @Bean - public RedisOperationsSessionRepository sessionRepository(RedisTemplate sessionRedisTemplate) { - RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(sessionRedisTemplate); - sessionRepository.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds); - return sessionRepository; - } + @Bean + public RedisOperationsSessionRepository sessionRepository(RedisTemplate sessionRedisTemplate) { + RedisOperationsSessionRepository sessionRepository = new RedisOperationsSessionRepository(sessionRedisTemplate); + sessionRepository.setDefaultMaxInactiveInterval(maxInactiveIntervalInSeconds); + return sessionRepository; + } - @Bean - public SessionRepositoryFilter springSessionRepositoryFilter(SessionRepository sessionRepository) { - SessionRepositoryFilter sessionRepositoryFilter = new SessionRepositoryFilter(sessionRepository); - if(httpSessionStrategy != null) { - sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy); - } - return sessionRepositoryFilter; - } + @Bean + public SessionRepositoryFilter springSessionRepositoryFilter(SessionRepository sessionRepository) { + SessionRepositoryFilter sessionRepositoryFilter = new SessionRepositoryFilter(sessionRepository); + if(httpSessionStrategy != null) { + sessionRepositoryFilter.setHttpSessionStrategy(httpSessionStrategy); + } + return sessionRepositoryFilter; + } - public void setImportMetadata(AnnotationMetadata importMetadata) { + public void setImportMetadata(AnnotationMetadata importMetadata) { - Map enableAttrMap = importMetadata.getAnnotationAttributes(EnableRedisHttpSession.class.getName()); - AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap); - if(enableAttrs == null) { - // search parent classes - Class currentClass = ClassUtils.resolveClassName(importMetadata.getClassName(), beanClassLoader); - for(Class classToInspect = currentClass ;classToInspect != null; classToInspect = classToInspect.getSuperclass()) { - EnableRedisHttpSession enableWebSecurityAnnotation = AnnotationUtils.findAnnotation(classToInspect, EnableRedisHttpSession.class); - if(enableWebSecurityAnnotation == null) { - continue; - } - enableAttrMap = AnnotationUtils - .getAnnotationAttributes(enableWebSecurityAnnotation); - enableAttrs = AnnotationAttributes.fromMap(enableAttrMap); - } - } - maxInactiveIntervalInSeconds = enableAttrs.getNumber("maxInactiveIntervalInSeconds"); - } + Map enableAttrMap = importMetadata.getAnnotationAttributes(EnableRedisHttpSession.class.getName()); + AnnotationAttributes enableAttrs = AnnotationAttributes.fromMap(enableAttrMap); + if(enableAttrs == null) { + // search parent classes + Class currentClass = ClassUtils.resolveClassName(importMetadata.getClassName(), beanClassLoader); + for(Class classToInspect = currentClass ;classToInspect != null; classToInspect = classToInspect.getSuperclass()) { + EnableRedisHttpSession enableWebSecurityAnnotation = AnnotationUtils.findAnnotation(classToInspect, EnableRedisHttpSession.class); + if(enableWebSecurityAnnotation == null) { + continue; + } + enableAttrMap = AnnotationUtils + .getAnnotationAttributes(enableWebSecurityAnnotation); + enableAttrs = AnnotationAttributes.fromMap(enableAttrMap); + } + } + maxInactiveIntervalInSeconds = enableAttrs.getNumber("maxInactiveIntervalInSeconds"); + } - @Autowired(required = false) - public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) { - this.httpSessionStrategy = httpSessionStrategy; - } + @Autowired(required = false) + public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) { + this.httpSessionStrategy = httpSessionStrategy; + } - @Bean - public EnableRedisKeyspaceNotificationsInitializer enableRedisKeyspaceNotificationsInitializer(RedisConnectionFactory connectionFactory) { - return new EnableRedisKeyspaceNotificationsInitializer(connectionFactory); - } + @Bean + public EnableRedisKeyspaceNotificationsInitializer enableRedisKeyspaceNotificationsInitializer(RedisConnectionFactory connectionFactory) { + return new EnableRedisKeyspaceNotificationsInitializer(connectionFactory); + } - /** - * Ensures that Redis is configured to send keyspace notifications. This is important to ensure that expiration and - * deletion of sessions trigger SessionDestroyedEvents. Without the SessionDestroyedEvent resources may not get - * cleaned up properly. For example, the mapping of the Session to WebSocket connections may not get cleaned up. - */ - static class EnableRedisKeyspaceNotificationsInitializer implements InitializingBean { - static final String CONFIG_NOTIFY_KEYSPACE_EVENTS = "notify-keyspace-events"; + /** + * Ensures that Redis is configured to send keyspace notifications. This is important to ensure that expiration and + * deletion of sessions trigger SessionDestroyedEvents. Without the SessionDestroyedEvent resources may not get + * cleaned up properly. For example, the mapping of the Session to WebSocket connections may not get cleaned up. + */ + static class EnableRedisKeyspaceNotificationsInitializer implements InitializingBean { + static final String CONFIG_NOTIFY_KEYSPACE_EVENTS = "notify-keyspace-events"; - private final RedisConnectionFactory connectionFactory; + private final RedisConnectionFactory connectionFactory; - EnableRedisKeyspaceNotificationsInitializer(RedisConnectionFactory connectionFactory) { - this.connectionFactory = connectionFactory; - } + EnableRedisKeyspaceNotificationsInitializer(RedisConnectionFactory connectionFactory) { + this.connectionFactory = connectionFactory; + } - public void afterPropertiesSet() throws Exception { - RedisConnection connection = connectionFactory.getConnection(); - String notifyOptions = getNotifyOptions(connection); - String customizedNotifyOptions = notifyOptions; - if(!customizedNotifyOptions.contains("E")) { - customizedNotifyOptions += "E"; - } - boolean A = customizedNotifyOptions.contains("A"); - if(!(A || customizedNotifyOptions.contains("g"))) { - customizedNotifyOptions += "g"; - } - if(!(A || customizedNotifyOptions.contains("x"))) { - customizedNotifyOptions += "x"; - } - if(!notifyOptions.equals(customizedNotifyOptions)) { - connection.setConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS, customizedNotifyOptions); - } - } + public void afterPropertiesSet() throws Exception { + RedisConnection connection = connectionFactory.getConnection(); + String notifyOptions = getNotifyOptions(connection); + String customizedNotifyOptions = notifyOptions; + if(!customizedNotifyOptions.contains("E")) { + customizedNotifyOptions += "E"; + } + boolean A = customizedNotifyOptions.contains("A"); + if(!(A || customizedNotifyOptions.contains("g"))) { + customizedNotifyOptions += "g"; + } + if(!(A || customizedNotifyOptions.contains("x"))) { + customizedNotifyOptions += "x"; + } + if(!notifyOptions.equals(customizedNotifyOptions)) { + connection.setConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS, customizedNotifyOptions); + } + } - private String getNotifyOptions(RedisConnection connection) { - List config = connection.getConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS); - if(config.size() < 2) { - return ""; - } - return config.get(1); - } - } + private String getNotifyOptions(RedisConnection connection) { + List config = connection.getConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS); + if(config.size() < 2) { + return ""; + } + return config.get(1); + } + } - /* (non-Javadoc) - * @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.lang.ClassLoader) - */ - public void setBeanClassLoader(ClassLoader classLoader) { - this.beanClassLoader = classLoader; - } + /* (non-Javadoc) + * @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(java.lang.ClassLoader) + */ + public void setBeanClassLoader(ClassLoader classLoader) { + this.beanClassLoader = classLoader; + } } diff --git a/spring-session/src/main/java/org/springframework/session/events/SessionDestroyedEvent.java b/spring-session/src/main/java/org/springframework/session/events/SessionDestroyedEvent.java index e56411b0..e634d0f3 100644 --- a/spring-session/src/main/java/org/springframework/session/events/SessionDestroyedEvent.java +++ b/spring-session/src/main/java/org/springframework/session/events/SessionDestroyedEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -30,14 +30,14 @@ import org.springframework.session.SessionRepository; */ @SuppressWarnings("serial") public class SessionDestroyedEvent extends ApplicationEvent { - private final String sessionId; + private final String sessionId; - public SessionDestroyedEvent(Object source, String sessionId) { - super(source); - this.sessionId = sessionId; - } + public SessionDestroyedEvent(Object source, String sessionId) { + super(source); + this.sessionId = sessionId; + } - public String getSessionId() { - return sessionId; - } + public String getSessionId() { + return sessionId; + } } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/web/context/AbstractHttpSessionApplicationInitializer.java b/spring-session/src/main/java/org/springframework/session/web/context/AbstractHttpSessionApplicationInitializer.java index 106e8729..940eab53 100644 --- a/spring-session/src/main/java/org/springframework/session/web/context/AbstractHttpSessionApplicationInitializer.java +++ b/spring-session/src/main/java/org/springframework/session/web/context/AbstractHttpSessionApplicationInitializer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -73,210 +73,210 @@ import org.springframework.web.filter.DelegatingFilterProxy; @Order(100) public abstract class AbstractHttpSessionApplicationInitializer implements WebApplicationInitializer { - private static final String SERVLET_CONTEXT_PREFIX = "org.springframework.web.servlet.FrameworkServlet.CONTEXT."; + private static final String SERVLET_CONTEXT_PREFIX = "org.springframework.web.servlet.FrameworkServlet.CONTEXT."; - public static final String DEFAULT_FILTER_NAME = "springSessionRepositoryFilter"; + public static final String DEFAULT_FILTER_NAME = "springSessionRepositoryFilter"; - private final Class[] configurationClasses; + private final Class[] configurationClasses; - /** - * Creates a new instance that assumes the Spring Session configuration is - * loaded by some other means than this class. For example, a user might - * create a {@link ContextLoaderListener} using a subclass of - * {@link AbstractContextLoaderInitializer}. - * - * @see ContextLoaderListener - */ - protected AbstractHttpSessionApplicationInitializer() { - this.configurationClasses = null; - } + /** + * Creates a new instance that assumes the Spring Session configuration is + * loaded by some other means than this class. For example, a user might + * create a {@link ContextLoaderListener} using a subclass of + * {@link AbstractContextLoaderInitializer}. + * + * @see ContextLoaderListener + */ + protected AbstractHttpSessionApplicationInitializer() { + this.configurationClasses = null; + } - /** - * 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) { - this.configurationClasses = configurationClasses; - } + /** + * 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) { + this.configurationClasses = configurationClasses; + } - public void onStartup(ServletContext servletContext) - throws ServletException { - beforeSessionRepositoryFilter(servletContext); - if(configurationClasses != null) { - AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext(); - rootAppContext.register(configurationClasses); - servletContext.addListener(new ContextLoaderListener(rootAppContext)); - } - insertSessionRepositoryFilter(servletContext); - afterSessionRepositoryFilter(servletContext); - } + public void onStartup(ServletContext servletContext) + throws ServletException { + beforeSessionRepositoryFilter(servletContext); + if(configurationClasses != null) { + AnnotationConfigWebApplicationContext rootAppContext = new AnnotationConfigWebApplicationContext(); + rootAppContext.register(configurationClasses); + servletContext.addListener(new ContextLoaderListener(rootAppContext)); + } + insertSessionRepositoryFilter(servletContext); + afterSessionRepositoryFilter(servletContext); + } - /** - * Registers the springSessionRepositoryFilter - * @param servletContext the {@link ServletContext} - */ - private void insertSessionRepositoryFilter(ServletContext servletContext) { - String filterName = DEFAULT_FILTER_NAME; - DelegatingFilterProxy springSessionRepositoryFilter = new DelegatingFilterProxy(filterName); - String contextAttribute = getWebApplicationContextAttribute(); - if(contextAttribute != null) { - springSessionRepositoryFilter.setContextAttribute(contextAttribute); - } - registerFilter(servletContext, true, filterName, springSessionRepositoryFilter); - } + /** + * Registers the springSessionRepositoryFilter + * @param servletContext the {@link ServletContext} + */ + private void insertSessionRepositoryFilter(ServletContext servletContext) { + String filterName = DEFAULT_FILTER_NAME; + DelegatingFilterProxy springSessionRepositoryFilter = new DelegatingFilterProxy(filterName); + String contextAttribute = getWebApplicationContextAttribute(); + if(contextAttribute != null) { + springSessionRepositoryFilter.setContextAttribute(contextAttribute); + } + registerFilter(servletContext, true, filterName, springSessionRepositoryFilter); + } - /** - * 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 - */ - protected final void insertFilters(ServletContext servletContext,Filter... filters) { - registerFilters(servletContext, true, filters); - } + /** + * 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 + */ + protected final void insertFilters(ServletContext servletContext,Filter... filters) { + registerFilters(servletContext, true, filters); + } - /** - * 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 - */ - protected final void appendFilters(ServletContext servletContext,Filter... filters) { - registerFilters(servletContext, false, filters); - } + /** + * 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 + */ + protected final void appendFilters(ServletContext servletContext,Filter... filters) { + registerFilters(servletContext, false, filters); + } - /** - * 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) { - Assert.notEmpty(filters, "filters cannot be null or empty"); + /** + * 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) { + 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)); - } - String filterName = Conventions.getVariableName(filter); - registerFilter(servletContext, insertBeforeOtherFilters, filterName, filter); - } - } + for(Filter filter : filters) { + if(filter == null) { + throw new IllegalArgumentException("filters cannot contain null values. Got " + Arrays.asList(filters)); + } + String filterName = Conventions.getVariableName(filter); + registerFilter(servletContext, insertBeforeOtherFilters, filterName, filter); + } + } - /** - * Registers the provided filter using the {@link #isAsyncSessionSupported()} and {@link #getSessionDispatcherTypes()}. - * - * @param servletContext - * @param insertBeforeOtherFilters should this Filter be inserted before or after other {@link Filter} - * @param filterName - * @param filter - */ - private final 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."); - } - registration.setAsyncSupported(isAsyncSessionSupported()); - EnumSet dispatcherTypes = getSessionDispatcherTypes(); - registration.addMappingForUrlPatterns(dispatcherTypes, !insertBeforeOtherFilters, "/*"); - } + /** + * Registers the provided filter using the {@link #isAsyncSessionSupported()} and {@link #getSessionDispatcherTypes()}. + * + * @param servletContext + * @param insertBeforeOtherFilters should this Filter be inserted before or after other {@link Filter} + * @param filterName + * @param filter + */ + private final 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."); + } + registration.setAsyncSupported(isAsyncSessionSupported()); + EnumSet dispatcherTypes = getSessionDispatcherTypes(); + registration.addMappingForUrlPatterns(dispatcherTypes, !insertBeforeOtherFilters, "/*"); + } - /** - * Returns the {@link DelegatingFilterProxy#getContextAttribute()} or null - * if the parent {@link ApplicationContext} should be used. The default - * behavior is to use the parent {@link ApplicationContext}. - * - *

- * If {@link #getDispatcherWebApplicationContextSuffix()} is non-null the - * {@link WebApplicationContext} for the Dispatcher will be used. This means - * the child {@link ApplicationContext} is used to look up the - * springSessionRepositoryFilter bean. - *

- * - * @return the {@link DelegatingFilterProxy#getContextAttribute()} or null - * if the parent {@link ApplicationContext} should be used - */ - private String getWebApplicationContextAttribute() { - String dispatcherServletName = getDispatcherWebApplicationContextSuffix(); - if(dispatcherServletName == null) { - return null; - } - return SERVLET_CONTEXT_PREFIX + dispatcherServletName; - } + /** + * Returns the {@link DelegatingFilterProxy#getContextAttribute()} or null + * if the parent {@link ApplicationContext} should be used. The default + * behavior is to use the parent {@link ApplicationContext}. + * + *

+ * If {@link #getDispatcherWebApplicationContextSuffix()} is non-null the + * {@link WebApplicationContext} for the Dispatcher will be used. This means + * the child {@link ApplicationContext} is used to look up the + * springSessionRepositoryFilter bean. + *

+ * + * @return the {@link DelegatingFilterProxy#getContextAttribute()} or null + * if the parent {@link ApplicationContext} should be used + */ + private String getWebApplicationContextAttribute() { + String dispatcherServletName = getDispatcherWebApplicationContextSuffix(); + if(dispatcherServletName == null) { + return null; + } + return SERVLET_CONTEXT_PREFIX + dispatcherServletName; + } - /** - * Return the {@code } to use the DispatcherServlet's - * {@link WebApplicationContext} to find the {@link DelegatingFilterProxy} - * or null to use the parent {@link ApplicationContext}. - * - *

- * For example, if you are using AbstractDispatcherServletInitializer or - * AbstractAnnotationConfigDispatcherServletInitializer and using the - * provided Servlet name, you can return "dispatcher" from this method to - * use the DispatcherServlet's {@link WebApplicationContext}. - *

- * - * @return the {@code } of the DispatcherServlet to use its - * {@link WebApplicationContext} or null (default) to use the parent - * {@link ApplicationContext}. - */ - protected String getDispatcherWebApplicationContextSuffix() { - return null; - } + /** + * Return the {@code } to use the DispatcherServlet's + * {@link WebApplicationContext} to find the {@link DelegatingFilterProxy} + * or null to use the parent {@link ApplicationContext}. + * + *

+ * For example, if you are using AbstractDispatcherServletInitializer or + * AbstractAnnotationConfigDispatcherServletInitializer and using the + * provided Servlet name, you can return "dispatcher" from this method to + * use the DispatcherServlet's {@link WebApplicationContext}. + *

+ * + * @return the {@code } of the DispatcherServlet to use its + * {@link WebApplicationContext} or null (default) to use the parent + * {@link ApplicationContext}. + */ + protected String getDispatcherWebApplicationContextSuffix() { + return null; + } - /** - * Invoked before the springSessionRepositoryFilter is added. - * @param servletContext the {@link ServletContext} - */ - protected void beforeSessionRepositoryFilter(ServletContext servletContext) { + /** + * Invoked before the springSessionRepositoryFilter is added. + * @param servletContext the {@link ServletContext} + */ + protected void beforeSessionRepositoryFilter(ServletContext servletContext) { - } + } - /** - * Invoked after the springSessionRepositoryFilter is added. - * @param servletContext the {@link ServletContext} - */ - protected void afterSessionRepositoryFilter(ServletContext servletContext) { + /** + * Invoked after the springSessionRepositoryFilter is added. + * @param servletContext the {@link ServletContext} + */ + protected void afterSessionRepositoryFilter(ServletContext servletContext) { - } + } - /** - * Get the {@link DispatcherType} for the springSessionRepositoryFilter. - * @return the {@link DispatcherType} for the filter - */ - protected EnumSet getSessionDispatcherTypes() { - return EnumSet.of(DispatcherType.REQUEST, DispatcherType.ERROR, DispatcherType.ASYNC); - } + /** + * Get the {@link DispatcherType} for the springSessionRepositoryFilter. + * @return the {@link DispatcherType} for the filter + */ + protected EnumSet getSessionDispatcherTypes() { + 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; - } + /** + * 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; + } } diff --git a/spring-session/src/main/java/org/springframework/session/web/http/CookieHttpSessionStrategy.java b/spring-session/src/main/java/org/springframework/session/web/http/CookieHttpSessionStrategy.java index a1d2c4aa..515cbaa6 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/CookieHttpSessionStrategy.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/CookieHttpSessionStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -151,240 +151,240 @@ import org.springframework.session.Session; * @author Rob Winch */ public final class CookieHttpSessionStrategy implements MultiHttpSessionStrategy, HttpSessionManager { - static final String DEFAULT_ALIAS = "0"; + static final String DEFAULT_ALIAS = "0"; - static final String DEFAULT_SESSION_ALIAS_PARAM_NAME = "_s"; + static final String DEFAULT_SESSION_ALIAS_PARAM_NAME = "_s"; - private Pattern ALIAS_PATTERN = Pattern.compile("^[\\w-]{1,50}$"); + private Pattern ALIAS_PATTERN = Pattern.compile("^[\\w-]{1,50}$"); - private String cookieName = "SESSION"; + private String cookieName = "SESSION"; - private String sessionParam = DEFAULT_SESSION_ALIAS_PARAM_NAME; + private String sessionParam = DEFAULT_SESSION_ALIAS_PARAM_NAME; - public String getRequestedSessionId(HttpServletRequest request) { - Map sessionIds = getSessionIds(request); - String sessionAlias = getCurrentSessionAlias(request); - return sessionIds.get(sessionAlias); - } + public String getRequestedSessionId(HttpServletRequest request) { + Map sessionIds = getSessionIds(request); + String sessionAlias = getCurrentSessionAlias(request); + return sessionIds.get(sessionAlias); + } - public String getCurrentSessionAlias(HttpServletRequest request) { - if(sessionParam == null) { - return DEFAULT_ALIAS; - } - String u = request.getParameter(sessionParam); - if(u == null) { - return DEFAULT_ALIAS; - } - if(!ALIAS_PATTERN.matcher(u).matches()) { - return DEFAULT_ALIAS; - } - return u; - } + public String getCurrentSessionAlias(HttpServletRequest request) { + if(sessionParam == null) { + return DEFAULT_ALIAS; + } + String u = request.getParameter(sessionParam); + if(u == null) { + return DEFAULT_ALIAS; + } + if(!ALIAS_PATTERN.matcher(u).matches()) { + return DEFAULT_ALIAS; + } + return u; + } - public String getNewSessionAlias(HttpServletRequest request) { - Set sessionAliases = getSessionIds(request).keySet(); - if(sessionAliases.isEmpty()) { - return DEFAULT_ALIAS; - } - long lastAlias = Long.decode(DEFAULT_ALIAS); - for(String alias : sessionAliases) { - long selectedAlias = safeParse(alias); - if(selectedAlias > lastAlias) { - lastAlias = selectedAlias; - } - } - return Long.toHexString(lastAlias + 1); - } + public String getNewSessionAlias(HttpServletRequest request) { + Set sessionAliases = getSessionIds(request).keySet(); + if(sessionAliases.isEmpty()) { + return DEFAULT_ALIAS; + } + long lastAlias = Long.decode(DEFAULT_ALIAS); + for(String alias : sessionAliases) { + long selectedAlias = safeParse(alias); + if(selectedAlias > lastAlias) { + lastAlias = selectedAlias; + } + } + return Long.toHexString(lastAlias + 1); + } - private long safeParse(String hex) { - try { - return Long.decode("0x" + hex); - } catch(NumberFormatException notNumber) { - return 0; - } - } + private long safeParse(String hex) { + try { + return Long.decode("0x" + hex); + } catch(NumberFormatException notNumber) { + return 0; + } + } - public void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response) { - Map sessionIds = getSessionIds(request); - String sessionAlias = getCurrentSessionAlias(request); - sessionIds.put(sessionAlias, session.getId()); - Cookie sessionCookie = createSessionCookie(request, sessionIds); - response.addCookie(sessionCookie); - } + public void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response) { + Map sessionIds = getSessionIds(request); + String sessionAlias = getCurrentSessionAlias(request); + sessionIds.put(sessionAlias, session.getId()); + Cookie sessionCookie = createSessionCookie(request, sessionIds); + response.addCookie(sessionCookie); + } - private Cookie createSessionCookie(HttpServletRequest request, - Map sessionIds) { - Cookie sessionCookie = new Cookie(cookieName,""); - sessionCookie.setHttpOnly(true); - sessionCookie.setSecure(request.isSecure()); - sessionCookie.setPath(cookiePath(request)); - // TODO set domain? + private Cookie createSessionCookie(HttpServletRequest request, + Map sessionIds) { + Cookie sessionCookie = new Cookie(cookieName,""); + sessionCookie.setHttpOnly(true); + sessionCookie.setSecure(request.isSecure()); + sessionCookie.setPath(cookiePath(request)); + // TODO set domain? - if(sessionIds.isEmpty()) { - sessionCookie.setMaxAge(0); - return sessionCookie; - } + if(sessionIds.isEmpty()) { + sessionCookie.setMaxAge(0); + return sessionCookie; + } - if(sessionIds.size() == 1) { - String cookieValue = sessionIds.values().iterator().next(); - sessionCookie.setValue(cookieValue); - return sessionCookie; - } - StringBuffer buffer = new StringBuffer(); - for(Map.Entry entry : sessionIds.entrySet()) { - String alias = entry.getKey(); - String id = entry.getValue(); + if(sessionIds.size() == 1) { + String cookieValue = sessionIds.values().iterator().next(); + sessionCookie.setValue(cookieValue); + return sessionCookie; + } + StringBuffer buffer = new StringBuffer(); + for(Map.Entry entry : sessionIds.entrySet()) { + String alias = entry.getKey(); + String id = entry.getValue(); - buffer.append(alias); - buffer.append(" "); - buffer.append(id); - buffer.append(" "); - } - buffer.deleteCharAt(buffer.length()-1); + buffer.append(alias); + buffer.append(" "); + buffer.append(id); + buffer.append(" "); + } + buffer.deleteCharAt(buffer.length()-1); - sessionCookie.setValue(buffer.toString()); - return sessionCookie; - } + sessionCookie.setValue(buffer.toString()); + return sessionCookie; + } - public void onInvalidateSession(HttpServletRequest request, HttpServletResponse response) { - Map sessionIds = getSessionIds(request); - String requestedAlias = getCurrentSessionAlias(request); - sessionIds.remove(requestedAlias); + public void onInvalidateSession(HttpServletRequest request, HttpServletResponse response) { + Map sessionIds = getSessionIds(request); + String requestedAlias = getCurrentSessionAlias(request); + sessionIds.remove(requestedAlias); - Cookie sessionCookie = createSessionCookie(request, sessionIds); - response.addCookie(sessionCookie); - } + Cookie sessionCookie = createSessionCookie(request, sessionIds); + response.addCookie(sessionCookie); + } - /** - * Sets the name of the HTTP parameter that is used to specify the session - * alias. If the value is null, then only a single session is supported per - * browser. - * - * @param sessionAliasParamName - * the name of the HTTP parameter used to specify the session - * alias. If null, then ony a single session is supported per - * browser. - */ - public void setSessionAliasParamName(String sessionAliasParamName) { - this.sessionParam = sessionAliasParamName; - } + /** + * Sets the name of the HTTP parameter that is used to specify the session + * alias. If the value is null, then only a single session is supported per + * browser. + * + * @param sessionAliasParamName + * the name of the HTTP parameter used to specify the session + * alias. If null, then ony a single session is supported per + * browser. + */ + public void setSessionAliasParamName(String sessionAliasParamName) { + this.sessionParam = sessionAliasParamName; + } - /** - * Sets the name of the cookie to be used - * @param cookieName the name of the cookie to be used - */ - public void setCookieName(String cookieName) { - if(cookieName == null) { - throw new IllegalArgumentException("cookieName cannot be null"); - } - this.cookieName = cookieName; - } + /** + * Sets the name of the cookie to be used + * @param cookieName the name of the cookie to be used + */ + public void setCookieName(String cookieName) { + if(cookieName == null) { + throw new IllegalArgumentException("cookieName cannot be null"); + } + this.cookieName = cookieName; + } - /** - * Retrieve the first cookie with the given name. Note that multiple - * cookies can have the same name but different paths or domains. - * @param request current servlet request - * @param name cookie name - * @return the first cookie with the given name, or {@code null} if none is found - */ - private static Cookie getCookie(HttpServletRequest request, String name) { - if(request == null) { - throw new IllegalArgumentException("request cannot be null"); - } - Cookie cookies[] = request.getCookies(); - if (cookies != null) { - for (Cookie cookie : cookies) { - if (name.equals(cookie.getName())) { - return cookie; - } - } - } - return null; - } + /** + * Retrieve the first cookie with the given name. Note that multiple + * cookies can have the same name but different paths or domains. + * @param request current servlet request + * @param name cookie name + * @return the first cookie with the given name, or {@code null} if none is found + */ + private static Cookie getCookie(HttpServletRequest request, String name) { + if(request == null) { + throw new IllegalArgumentException("request cannot be null"); + } + Cookie cookies[] = request.getCookies(); + if (cookies != null) { + for (Cookie cookie : cookies) { + if (name.equals(cookie.getName())) { + return cookie; + } + } + } + return null; + } - private static String cookiePath(HttpServletRequest request) { - return request.getContextPath() + "/"; - } + private static String cookiePath(HttpServletRequest request) { + return request.getContextPath() + "/"; + } - public Map getSessionIds(HttpServletRequest request) { - Cookie session = getCookie(request, cookieName); - String sessionCookieValue = session == null ? "" : session.getValue(); - Map result = new LinkedHashMap(); - StringTokenizer tokens = new StringTokenizer(sessionCookieValue, " "); - if(tokens.countTokens() == 1) { - result.put(DEFAULT_ALIAS, tokens.nextToken()); - return result; - } - while(tokens.hasMoreTokens()) { - String alias = tokens.nextToken(); - if(!tokens.hasMoreTokens()) { - break; - } - String id = tokens.nextToken(); - result.put(alias, id); - } - return result; - } + public Map getSessionIds(HttpServletRequest request) { + Cookie session = getCookie(request, cookieName); + String sessionCookieValue = session == null ? "" : session.getValue(); + Map result = new LinkedHashMap(); + StringTokenizer tokens = new StringTokenizer(sessionCookieValue, " "); + if(tokens.countTokens() == 1) { + result.put(DEFAULT_ALIAS, tokens.nextToken()); + return result; + } + while(tokens.hasMoreTokens()) { + String alias = tokens.nextToken(); + if(!tokens.hasMoreTokens()) { + break; + } + String id = tokens.nextToken(); + result.put(alias, id); + } + return result; + } - public HttpServletRequest wrapRequest(HttpServletRequest request, HttpServletResponse response) { - request.setAttribute(HttpSessionManager.class.getName(), this); - return request; - } + public HttpServletRequest wrapRequest(HttpServletRequest request, HttpServletResponse response) { + request.setAttribute(HttpSessionManager.class.getName(), this); + return request; + } - public HttpServletResponse wrapResponse(HttpServletRequest request, HttpServletResponse response) { - return new MultiSessionHttpServletResponse(response, request); - } + public HttpServletResponse wrapResponse(HttpServletRequest request, HttpServletResponse response) { + return new MultiSessionHttpServletResponse(response, request); + } - class MultiSessionHttpServletResponse extends HttpServletResponseWrapper { - private final HttpServletRequest request; + class MultiSessionHttpServletResponse extends HttpServletResponseWrapper { + private final HttpServletRequest request; - public MultiSessionHttpServletResponse(HttpServletResponse response, HttpServletRequest request) { - super(response); - this.request = request; - } + public MultiSessionHttpServletResponse(HttpServletResponse response, HttpServletRequest request) { + super(response); + this.request = request; + } - @Override - public String encodeRedirectURL(String url) { - url = super.encodeRedirectURL(url); - return CookieHttpSessionStrategy.this.encodeURL(url, getCurrentSessionAlias(request)); - } + @Override + public String encodeRedirectURL(String url) { + url = super.encodeRedirectURL(url); + return CookieHttpSessionStrategy.this.encodeURL(url, getCurrentSessionAlias(request)); + } - @Override - public String encodeURL(String url) { - url = super.encodeURL(url); + @Override + public String encodeURL(String url) { + url = super.encodeURL(url); - String alias = getCurrentSessionAlias(request); - return CookieHttpSessionStrategy.this.encodeURL(url, alias); - } - } + String alias = getCurrentSessionAlias(request); + return CookieHttpSessionStrategy.this.encodeURL(url, alias); + } + } - public String encodeURL(String url, String sessionAlias) { - String encodedSessionAlias = urlEncode(sessionAlias); - int queryStart = url.indexOf("?"); - boolean isDefaultAlias = DEFAULT_ALIAS.equals(encodedSessionAlias); - if(queryStart < 0) { - return isDefaultAlias ? url : url + "?" + sessionParam + "=" + encodedSessionAlias; - } - String path = url.substring(0, queryStart); - String query = url.substring(queryStart + 1, url.length()); - String replacement = isDefaultAlias ? "" : "$1"+encodedSessionAlias; - query = query.replaceFirst( "((^|&)" + sessionParam + "=)([^&]+)?", replacement); - if(!isDefaultAlias && url.endsWith(query)) { - // no existing alias - if(!(query.endsWith("&") || query.length() == 0)) { - query += "&"; - } - query += sessionParam + "=" + encodedSessionAlias; - } + public String encodeURL(String url, String sessionAlias) { + String encodedSessionAlias = urlEncode(sessionAlias); + int queryStart = url.indexOf("?"); + boolean isDefaultAlias = DEFAULT_ALIAS.equals(encodedSessionAlias); + if(queryStart < 0) { + return isDefaultAlias ? url : url + "?" + sessionParam + "=" + encodedSessionAlias; + } + String path = url.substring(0, queryStart); + String query = url.substring(queryStart + 1, url.length()); + String replacement = isDefaultAlias ? "" : "$1"+encodedSessionAlias; + query = query.replaceFirst( "((^|&)" + sessionParam + "=)([^&]+)?", replacement); + if(!isDefaultAlias && url.endsWith(query)) { + // no existing alias + if(!(query.endsWith("&") || query.length() == 0)) { + query += "&"; + } + query += sessionParam + "=" + encodedSessionAlias; + } - return path + "?" + query; - } + return path + "?" + query; + } - private String urlEncode(String value) { - try { - return URLEncoder.encode(value, "UTF-8"); - } catch (UnsupportedEncodingException e) { - throw new RuntimeException(e); - } - } + private String urlEncode(String value) { + try { + return URLEncoder.encode(value, "UTF-8"); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/web/http/HeaderHttpSessionStrategy.java b/spring-session/src/main/java/org/springframework/session/web/http/HeaderHttpSessionStrategy.java index 7b676ef7..e9dfc9f3 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/HeaderHttpSessionStrategy.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/HeaderHttpSessionStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -51,27 +51,27 @@ import javax.servlet.http.HttpServletResponse; * @author Rob Winch */ public class HeaderHttpSessionStrategy implements HttpSessionStrategy { - private String headerName = "x-auth-token"; + private String headerName = "x-auth-token"; - public String getRequestedSessionId(HttpServletRequest request) { - return request.getHeader(headerName); - } + public String getRequestedSessionId(HttpServletRequest request) { + return request.getHeader(headerName); + } - public void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response) { - response.setHeader(headerName, session.getId()); - } + public void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response) { + response.setHeader(headerName, session.getId()); + } - public void onInvalidateSession(HttpServletRequest request, HttpServletResponse response) { - response.setHeader(headerName, ""); - } + public void onInvalidateSession(HttpServletRequest request, HttpServletResponse response) { + response.setHeader(headerName, ""); + } - /** - * The name of the header to obtain the session id from. Default is "x-auth-token". - * - * @param headerName the name of the header to obtain the session id from. - */ - public void setHeaderName(String headerName) { - Assert.notNull(headerName, "headerName cannot be null"); - this.headerName = headerName; - } + /** + * The name of the header to obtain the session id from. Default is "x-auth-token". + * + * @param headerName the name of the header to obtain the session id from. + */ + public void setHeaderName(String headerName) { + Assert.notNull(headerName, "headerName cannot be null"); + this.headerName = headerName; + } } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionManager.java b/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionManager.java index 3948b12c..069a05db 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionManager.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionManager.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -29,44 +29,44 @@ import javax.servlet.http.HttpServletRequest; */ public interface HttpSessionManager { - /** - * Gets the current session's alias from the {@link HttpServletRequest}. - * - * @param request the {@link HttpServletRequest} to obtain the current session's alias from. - * @return the current sessions' alias. Cannot be null. - */ - String getCurrentSessionAlias(HttpServletRequest request); + /** + * Gets the current session's alias from the {@link HttpServletRequest}. + * + * @param request the {@link HttpServletRequest} to obtain the current session's alias from. + * @return the current sessions' alias. Cannot be null. + */ + String getCurrentSessionAlias(HttpServletRequest request); - /** - * Gets a mapping of the session alias to the session id from the - * {@link HttpServletRequest} - * - * @param request the {@link HttpServletRequest} to obtain the mapping from. Cannot be null. - * @return a mapping of the session alias to the session id from the - * {@link HttpServletRequest}. Cannot be null. - */ - Map getSessionIds(HttpServletRequest request); + /** + * Gets a mapping of the session alias to the session id from the + * {@link HttpServletRequest} + * + * @param request the {@link HttpServletRequest} to obtain the mapping from. Cannot be null. + * @return a mapping of the session alias to the session id from the + * {@link HttpServletRequest}. Cannot be null. + */ + Map getSessionIds(HttpServletRequest request); - /** - * Provides the ability to encode the URL for a given session alias. - * - * @param url the url to encode. - * @param sessionAlias the session alias to encode. - * @return the encoded URL - */ - String encodeURL(String url, String sessionAlias); + /** + * Provides the ability to encode the URL for a given session alias. + * + * @param url the url to encode. + * @param sessionAlias the session alias to encode. + * @return the encoded URL + */ + String encodeURL(String url, String sessionAlias); - /** - * Gets a new and unique Session alias. Typically this will be called to pass into - * {@code HttpSessionManager#encodeURL(java.lang.String)}. For example: - * - * - * String newAlias = httpSessionManager.getNewSessionAlias(request); - * String addAccountUrl = httpSessionManager.encodeURL("./", newAlias); - * - * - * @param request the {@link HttpServletRequest} to get a new alias from - * @return - */ - String getNewSessionAlias(HttpServletRequest request); + /** + * Gets a new and unique Session alias. Typically this will be called to pass into + * {@code HttpSessionManager#encodeURL(java.lang.String)}. For example: + * + * + * String newAlias = httpSessionManager.getNewSessionAlias(request); + * String addAccountUrl = httpSessionManager.encodeURL("./", newAlias); + * + * + * @param request the {@link HttpServletRequest} to get a new alias from + * @return + */ + String getNewSessionAlias(HttpServletRequest request); } diff --git a/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionStrategy.java b/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionStrategy.java index ec353ead..003d67ea 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionStrategy.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/HttpSessionStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -28,36 +28,36 @@ import javax.servlet.http.HttpServletResponse; */ public interface HttpSessionStrategy { - /** - * Obtains the requested session id from the provided {@link javax.servlet.http.HttpServletRequest}. For example, - * the session id might come from a cookie or a request header. - * - * @param request the {@link javax.servlet.http.HttpServletRequest} to obtain the session id from. Cannot be null. - * @return the {@link javax.servlet.http.HttpServletRequest} to obtain the session id from. - */ - String getRequestedSessionId(HttpServletRequest request); + /** + * Obtains the requested session id from the provided {@link javax.servlet.http.HttpServletRequest}. For example, + * the session id might come from a cookie or a request header. + * + * @param request the {@link javax.servlet.http.HttpServletRequest} to obtain the session id from. Cannot be null. + * @return the {@link javax.servlet.http.HttpServletRequest} to obtain the session id from. + */ + String getRequestedSessionId(HttpServletRequest request); - /** - * This method is invoked when a new session is created and should inform a client what the new session id is. For - * example, it might create a new cookie with the session id in it or set an HTTP response header with the value of - * the new session id. - * - * Some implementations may wish to associate additional information to the {@link Session} at this time. For example, they - * may wish to add the IP Address, browser headers, the username, etc to the {@link org.springframework.session.Session}. - * - * @param session the {@link org.springframework.session.Session} that is being sent to the client. Cannot be null. - * @param request the {@link javax.servlet.http.HttpServletRequest} that create the new {@link org.springframework.session.Session} Cannot be null. - * @param response the {@link javax.servlet.http.HttpServletResponse} that is associated with the {@link javax.servlet.http.HttpServletRequest} that created the new {@link org.springframework.session.Session} Cannot be null. - */ - void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response); + /** + * This method is invoked when a new session is created and should inform a client what the new session id is. For + * example, it might create a new cookie with the session id in it or set an HTTP response header with the value of + * the new session id. + * + * Some implementations may wish to associate additional information to the {@link Session} at this time. For example, they + * may wish to add the IP Address, browser headers, the username, etc to the {@link org.springframework.session.Session}. + * + * @param session the {@link org.springframework.session.Session} that is being sent to the client. Cannot be null. + * @param request the {@link javax.servlet.http.HttpServletRequest} that create the new {@link org.springframework.session.Session} Cannot be null. + * @param response the {@link javax.servlet.http.HttpServletResponse} that is associated with the {@link javax.servlet.http.HttpServletRequest} that created the new {@link org.springframework.session.Session} Cannot be null. + */ + void onNewSession(Session session, HttpServletRequest request, HttpServletResponse response); - /** - * This method is invoked when a session is invalidated and should inform a client that the session id is no longer valid. For - * example, it might remove a cookie with the session id in it or set an HTTP response header with an empty value indicating - * to the client to no longer submit that session id. - * - * @param request the {@link javax.servlet.http.HttpServletRequest} that invalidated the {@link org.springframework.session.Session} Cannot be null. - * @param response the {@link javax.servlet.http.HttpServletResponse} that is associated with the {@link javax.servlet.http.HttpServletRequest} that invalidated the {@link org.springframework.session.Session} Cannot be null. - */ - void onInvalidateSession(HttpServletRequest request, HttpServletResponse response); + /** + * This method is invoked when a session is invalidated and should inform a client that the session id is no longer valid. For + * example, it might remove a cookie with the session id in it or set an HTTP response header with an empty value indicating + * to the client to no longer submit that session id. + * + * @param request the {@link javax.servlet.http.HttpServletRequest} that invalidated the {@link org.springframework.session.Session} Cannot be null. + * @param response the {@link javax.servlet.http.HttpServletResponse} that is associated with the {@link javax.servlet.http.HttpServletRequest} that invalidated the {@link org.springframework.session.Session} Cannot be null. + */ + void onInvalidateSession(HttpServletRequest request, HttpServletResponse response); } diff --git a/spring-session/src/main/java/org/springframework/session/web/http/MultiHttpSessionStrategy.java b/spring-session/src/main/java/org/springframework/session/web/http/MultiHttpSessionStrategy.java index 895e9c08..522f0cc5 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/MultiHttpSessionStrategy.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/MultiHttpSessionStrategy.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. diff --git a/spring-session/src/main/java/org/springframework/session/web/http/OnCommittedResponseWrapper.java b/spring-session/src/main/java/org/springframework/session/web/http/OnCommittedResponseWrapper.java index ac9d6b0a..9feb5daf 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/OnCommittedResponseWrapper.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/OnCommittedResponseWrapper.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -30,520 +30,520 @@ import java.util.Locale; * @author Rob Winch */ abstract class OnCommittedResponseWrapper extends HttpServletResponseWrapper { - private final Log logger = LogFactory.getLog(getClass()); - - private boolean disableOnCommitted; - - /** - * The Content-Length response header. If this is greater than 0, then once {@link #contentWritten} is larger than - * or equal the response is considered committed. - */ - private long contentLength; - - /** - * The size of data written to the response body. - */ - private long contentWritten; - - /** - * @param response the response to be wrapped - */ - public OnCommittedResponseWrapper(HttpServletResponse response) { - super(response); - } - - @Override - public void addHeader(String name, String value) { - if("Content-Length".equalsIgnoreCase(name)) { - setContentLength(Long.parseLong(value)); - } - super.addHeader(name, value); - } - - @Override - public void setContentLength(int len) { - setContentLength((long) len); - super.setContentLength(len); - } - - private void setContentLength(long len) { - this.contentLength = len; - checkContentLength(0); - } - - /** - * Invoke this method to disable invoking {@link OnCommittedResponseWrapper#onResponseCommitted()} when the {@link javax.servlet.http.HttpServletResponse} is - * committed. This can be useful in the event that Async Web Requests are - * made. - */ - public void disableOnResponseCommitted() { - this.disableOnCommitted = true; - } - - /** - * Implement the logic for handling the {@link javax.servlet.http.HttpServletResponse} being committed - */ - protected abstract void onResponseCommitted(); - - /** - * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the - * superclass sendError() - */ - @Override - public final void sendError(int sc) throws IOException { - doOnResponseCommitted(); - super.sendError(sc); - } - - /** - * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the - * superclass sendError() - */ - @Override - public final void sendError(int sc, String msg) throws IOException { - doOnResponseCommitted(); - super.sendError(sc, msg); - } - - /** - * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the - * superclass sendRedirect() - */ - @Override - public final void sendRedirect(String location) throws IOException { - doOnResponseCommitted(); - super.sendRedirect(location); - } - - /** - * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the calling - * getOutputStream().close() or getOutputStream().flush() - */ - @Override - public ServletOutputStream getOutputStream() throws IOException { - return new SaveContextServletOutputStream(super.getOutputStream()); - } - - /** - * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the - * getWriter().close() or getWriter().flush() - */ - @Override - public PrintWriter getWriter() throws IOException { - return new SaveContextPrintWriter(super.getWriter()); - } - - /** - * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the - * superclass flushBuffer() - */ - @Override - public void flushBuffer() throws IOException { - doOnResponseCommitted(); - super.flushBuffer(); - } - - private void trackContentLength(boolean content) { - checkContentLength(content ? 4 : 5); // TODO Localization - } - - private void trackContentLength(char content) { - checkContentLength(1); - } - - private void trackContentLength(Object content) { - trackContentLength(String.valueOf(content)); - } - - private void trackContentLength(byte[] content) { - checkContentLength(content == null ? 0 : content.length); - } - - private void trackContentLength(char[] content) { - checkContentLength(content == null ? 0 : content.length); - } - - private void trackContentLength(int content) { - trackContentLength(String.valueOf(content)); - } - - private void trackContentLength(float content) { - trackContentLength(String.valueOf(content)); - } - - private void trackContentLength(double content) { - trackContentLength(String.valueOf(content)); - } - - private void trackContentLengthLn() { - trackContentLength("\r\n"); - } - - private void trackContentLength(String content) { - checkContentLength(content.length()); - } - - /** - * Adds the contentLengthToWrite to the total contentWritten size and checks to see if the response should be - * written. - * - * @param contentLengthToWrite the size of the content that is about to be written. - */ - private void checkContentLength(long contentLengthToWrite) { - contentWritten += contentLengthToWrite; - boolean isBodyFullyWritten = contentLength > 0 && contentWritten >= contentLength; - int bufferSize = getBufferSize(); - boolean requiresFlush = bufferSize > 0 && contentWritten >= bufferSize; - if(isBodyFullyWritten || requiresFlush) { - doOnResponseCommitted(); - } - } - - /** - * Calls onResponseCommmitted() with the current contents as long as - * {@link #disableOnResponseCommitted()()} was not invoked. - */ - private void doOnResponseCommitted() { - if(!disableOnCommitted) { - onResponseCommitted(); - disableOnResponseCommitted(); - } else if(logger.isDebugEnabled()){ - logger.debug("Skip invoking on"); - } - } - - /** - * Ensures {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the prior to methods that commit the response. We delegate all methods - * to the original {@link java.io.PrintWriter} to ensure that the behavior is as close to the original {@link java.io.PrintWriter} - * as possible. See SEC-2039 - * @author Rob Winch - */ - private class SaveContextPrintWriter extends PrintWriter { - private final PrintWriter delegate; - - public SaveContextPrintWriter(PrintWriter delegate) { - super(delegate); - this.delegate = delegate; - } - - public void flush() { - doOnResponseCommitted(); - delegate.flush(); - } - - public void close() { - doOnResponseCommitted(); - delegate.close(); - } - - public int hashCode() { - return delegate.hashCode(); - } - - public boolean equals(Object obj) { - return delegate.equals(obj); - } - - public String toString() { - return getClass().getName() + "[delegate=" + delegate.toString() + "]"; - } - - public boolean checkError() { - return delegate.checkError(); - } - - public void write(int c) { - trackContentLength(c); - delegate.write(c); - } - - public void write(char[] buf, int off, int len) { - checkContentLength(len); - delegate.write(buf, off, len); - } - - public void write(char[] buf) { - trackContentLength(buf); - delegate.write(buf); - } - - public void write(String s, int off, int len) { - checkContentLength(len); - delegate.write(s, off, len); - } - - public void write(String s) { - trackContentLength(s); - delegate.write(s); - } - - public void print(boolean b) { - trackContentLength(b); - delegate.print(b); - } - - public void print(char c) { - trackContentLength(c); - delegate.print(c); - } - - public void print(int i) { - trackContentLength(i); - delegate.print(i); - } - - public void print(long l) { - trackContentLength(l); - delegate.print(l); - } - - public void print(float f) { - trackContentLength(f); - delegate.print(f); - } - - public void print(double d) { - trackContentLength(d); - delegate.print(d); - } - - public void print(char[] s) { - trackContentLength(s); - delegate.print(s); - } - - public void print(String s) { - trackContentLength(s); - delegate.print(s); - } - - public void print(Object obj) { - trackContentLength(obj); - delegate.print(obj); - } - - public void println() { - trackContentLengthLn(); - delegate.println(); - } - - public void println(boolean x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(char x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(int x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(long x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(float x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(double x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(char[] x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(String x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public void println(Object x) { - trackContentLength(x); - trackContentLengthLn(); - delegate.println(x); - } - - public PrintWriter printf(String format, Object... args) { - return delegate.printf(format, args); - } - - public PrintWriter printf(Locale l, String format, Object... args) { - return delegate.printf(l, format, args); - } - - public PrintWriter format(String format, Object... args) { - return delegate.format(format, args); - } - - public PrintWriter format(Locale l, String format, Object... args) { - return delegate.format(l, format, args); - } - - public PrintWriter append(CharSequence csq) { - checkContentLength(csq.length()); - return delegate.append(csq); - } - - public PrintWriter append(CharSequence csq, int start, int end) { - checkContentLength(end - start); - return delegate.append(csq, start, end); - } - - public PrintWriter append(char c) { - trackContentLength(c); - return delegate.append(c); - } - } - - /** - * Ensures{@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling methods that commit the response. We delegate all methods - * to the original {@link javax.servlet.ServletOutputStream} to ensure that the behavior is as close to the original {@link javax.servlet.ServletOutputStream} - * as possible. See SEC-2039 - * - * @author Rob Winch - */ - private class SaveContextServletOutputStream extends ServletOutputStream { - private final ServletOutputStream delegate; - - public SaveContextServletOutputStream(ServletOutputStream delegate) { - this.delegate = delegate; - } - - public void write(int b) throws IOException { - trackContentLength(b); - this.delegate.write(b); - } - - public void flush() throws IOException { - doOnResponseCommitted(); - delegate.flush(); - } - - public void close() throws IOException { - doOnResponseCommitted(); - delegate.close(); - } - - public int hashCode() { - return delegate.hashCode(); - } - - public boolean equals(Object obj) { - return delegate.equals(obj); - } - - public void print(boolean b) throws IOException { - trackContentLength(b); - delegate.print(b); - } - - public void print(char c) throws IOException { - trackContentLength(c); - delegate.print(c); - } - - public void print(double d) throws IOException { - trackContentLength(d); - delegate.print(d); - } - - public void print(float f) throws IOException { - trackContentLength(f); - delegate.print(f); - } - - public void print(int i) throws IOException { - trackContentLength(i); - delegate.print(i); - } - - public void print(long l) throws IOException { - trackContentLength(l); - delegate.print(l); - } - - public void print(String s) throws IOException { - trackContentLength(s); - delegate.print(s); - } - - public void println() throws IOException { - trackContentLengthLn(); - delegate.println(); - } - - public void println(boolean b) throws IOException { - trackContentLength(b); - trackContentLengthLn(); - delegate.println(b); - } - - public void println(char c) throws IOException { - trackContentLength(c); - trackContentLengthLn(); - delegate.println(c); - } - - public void println(double d) throws IOException { - trackContentLength(d); - trackContentLengthLn(); - delegate.println(d); - } - - public void println(float f) throws IOException { - trackContentLength(f); - trackContentLengthLn(); - delegate.println(f); - } - - public void println(int i) throws IOException { - trackContentLength(i); - trackContentLengthLn(); - delegate.println(i); - } - - public void println(long l) throws IOException { - trackContentLength(l); - trackContentLengthLn(); - delegate.println(l); - } - - public void println(String s) throws IOException { - trackContentLength(s); - trackContentLengthLn(); - delegate.println(s); - } - - public void write(byte[] b) throws IOException { - trackContentLength(b); - delegate.write(b); - } - - public void write(byte[] b, int off, int len) throws IOException { - checkContentLength(len); - delegate.write(b, off, len); - } - - public String toString() { - return getClass().getName() + "[delegate=" + delegate.toString() + "]"; - } - } + private final Log logger = LogFactory.getLog(getClass()); + + private boolean disableOnCommitted; + + /** + * The Content-Length response header. If this is greater than 0, then once {@link #contentWritten} is larger than + * or equal the response is considered committed. + */ + private long contentLength; + + /** + * The size of data written to the response body. + */ + private long contentWritten; + + /** + * @param response the response to be wrapped + */ + public OnCommittedResponseWrapper(HttpServletResponse response) { + super(response); + } + + @Override + public void addHeader(String name, String value) { + if("Content-Length".equalsIgnoreCase(name)) { + setContentLength(Long.parseLong(value)); + } + super.addHeader(name, value); + } + + @Override + public void setContentLength(int len) { + setContentLength((long) len); + super.setContentLength(len); + } + + private void setContentLength(long len) { + this.contentLength = len; + checkContentLength(0); + } + + /** + * Invoke this method to disable invoking {@link OnCommittedResponseWrapper#onResponseCommitted()} when the {@link javax.servlet.http.HttpServletResponse} is + * committed. This can be useful in the event that Async Web Requests are + * made. + */ + public void disableOnResponseCommitted() { + this.disableOnCommitted = true; + } + + /** + * Implement the logic for handling the {@link javax.servlet.http.HttpServletResponse} being committed + */ + protected abstract void onResponseCommitted(); + + /** + * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the + * superclass sendError() + */ + @Override + public final void sendError(int sc) throws IOException { + doOnResponseCommitted(); + super.sendError(sc); + } + + /** + * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the + * superclass sendError() + */ + @Override + public final void sendError(int sc, String msg) throws IOException { + doOnResponseCommitted(); + super.sendError(sc, msg); + } + + /** + * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the + * superclass sendRedirect() + */ + @Override + public final void sendRedirect(String location) throws IOException { + doOnResponseCommitted(); + super.sendRedirect(location); + } + + /** + * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the calling + * getOutputStream().close() or getOutputStream().flush() + */ + @Override + public ServletOutputStream getOutputStream() throws IOException { + return new SaveContextServletOutputStream(super.getOutputStream()); + } + + /** + * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the + * getWriter().close() or getWriter().flush() + */ + @Override + public PrintWriter getWriter() throws IOException { + return new SaveContextPrintWriter(super.getWriter()); + } + + /** + * Makes sure {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the + * superclass flushBuffer() + */ + @Override + public void flushBuffer() throws IOException { + doOnResponseCommitted(); + super.flushBuffer(); + } + + private void trackContentLength(boolean content) { + checkContentLength(content ? 4 : 5); // TODO Localization + } + + private void trackContentLength(char content) { + checkContentLength(1); + } + + private void trackContentLength(Object content) { + trackContentLength(String.valueOf(content)); + } + + private void trackContentLength(byte[] content) { + checkContentLength(content == null ? 0 : content.length); + } + + private void trackContentLength(char[] content) { + checkContentLength(content == null ? 0 : content.length); + } + + private void trackContentLength(int content) { + trackContentLength(String.valueOf(content)); + } + + private void trackContentLength(float content) { + trackContentLength(String.valueOf(content)); + } + + private void trackContentLength(double content) { + trackContentLength(String.valueOf(content)); + } + + private void trackContentLengthLn() { + trackContentLength("\r\n"); + } + + private void trackContentLength(String content) { + checkContentLength(content.length()); + } + + /** + * Adds the contentLengthToWrite to the total contentWritten size and checks to see if the response should be + * written. + * + * @param contentLengthToWrite the size of the content that is about to be written. + */ + private void checkContentLength(long contentLengthToWrite) { + contentWritten += contentLengthToWrite; + boolean isBodyFullyWritten = contentLength > 0 && contentWritten >= contentLength; + int bufferSize = getBufferSize(); + boolean requiresFlush = bufferSize > 0 && contentWritten >= bufferSize; + if(isBodyFullyWritten || requiresFlush) { + doOnResponseCommitted(); + } + } + + /** + * Calls onResponseCommmitted() with the current contents as long as + * {@link #disableOnResponseCommitted()()} was not invoked. + */ + private void doOnResponseCommitted() { + if(!disableOnCommitted) { + onResponseCommitted(); + disableOnResponseCommitted(); + } else if(logger.isDebugEnabled()){ + logger.debug("Skip invoking on"); + } + } + + /** + * Ensures {@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling the prior to methods that commit the response. We delegate all methods + * to the original {@link java.io.PrintWriter} to ensure that the behavior is as close to the original {@link java.io.PrintWriter} + * as possible. See SEC-2039 + * @author Rob Winch + */ + private class SaveContextPrintWriter extends PrintWriter { + private final PrintWriter delegate; + + public SaveContextPrintWriter(PrintWriter delegate) { + super(delegate); + this.delegate = delegate; + } + + public void flush() { + doOnResponseCommitted(); + delegate.flush(); + } + + public void close() { + doOnResponseCommitted(); + delegate.close(); + } + + public int hashCode() { + return delegate.hashCode(); + } + + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + public String toString() { + return getClass().getName() + "[delegate=" + delegate.toString() + "]"; + } + + public boolean checkError() { + return delegate.checkError(); + } + + public void write(int c) { + trackContentLength(c); + delegate.write(c); + } + + public void write(char[] buf, int off, int len) { + checkContentLength(len); + delegate.write(buf, off, len); + } + + public void write(char[] buf) { + trackContentLength(buf); + delegate.write(buf); + } + + public void write(String s, int off, int len) { + checkContentLength(len); + delegate.write(s, off, len); + } + + public void write(String s) { + trackContentLength(s); + delegate.write(s); + } + + public void print(boolean b) { + trackContentLength(b); + delegate.print(b); + } + + public void print(char c) { + trackContentLength(c); + delegate.print(c); + } + + public void print(int i) { + trackContentLength(i); + delegate.print(i); + } + + public void print(long l) { + trackContentLength(l); + delegate.print(l); + } + + public void print(float f) { + trackContentLength(f); + delegate.print(f); + } + + public void print(double d) { + trackContentLength(d); + delegate.print(d); + } + + public void print(char[] s) { + trackContentLength(s); + delegate.print(s); + } + + public void print(String s) { + trackContentLength(s); + delegate.print(s); + } + + public void print(Object obj) { + trackContentLength(obj); + delegate.print(obj); + } + + public void println() { + trackContentLengthLn(); + delegate.println(); + } + + public void println(boolean x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(char x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(int x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(long x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(float x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(double x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(char[] x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(String x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public void println(Object x) { + trackContentLength(x); + trackContentLengthLn(); + delegate.println(x); + } + + public PrintWriter printf(String format, Object... args) { + return delegate.printf(format, args); + } + + public PrintWriter printf(Locale l, String format, Object... args) { + return delegate.printf(l, format, args); + } + + public PrintWriter format(String format, Object... args) { + return delegate.format(format, args); + } + + public PrintWriter format(Locale l, String format, Object... args) { + return delegate.format(l, format, args); + } + + public PrintWriter append(CharSequence csq) { + checkContentLength(csq.length()); + return delegate.append(csq); + } + + public PrintWriter append(CharSequence csq, int start, int end) { + checkContentLength(end - start); + return delegate.append(csq, start, end); + } + + public PrintWriter append(char c) { + trackContentLength(c); + return delegate.append(c); + } + } + + /** + * Ensures{@link OnCommittedResponseWrapper#onResponseCommitted()} is invoked before calling methods that commit the response. We delegate all methods + * to the original {@link javax.servlet.ServletOutputStream} to ensure that the behavior is as close to the original {@link javax.servlet.ServletOutputStream} + * as possible. See SEC-2039 + * + * @author Rob Winch + */ + private class SaveContextServletOutputStream extends ServletOutputStream { + private final ServletOutputStream delegate; + + public SaveContextServletOutputStream(ServletOutputStream delegate) { + this.delegate = delegate; + } + + public void write(int b) throws IOException { + trackContentLength(b); + this.delegate.write(b); + } + + public void flush() throws IOException { + doOnResponseCommitted(); + delegate.flush(); + } + + public void close() throws IOException { + doOnResponseCommitted(); + delegate.close(); + } + + public int hashCode() { + return delegate.hashCode(); + } + + public boolean equals(Object obj) { + return delegate.equals(obj); + } + + public void print(boolean b) throws IOException { + trackContentLength(b); + delegate.print(b); + } + + public void print(char c) throws IOException { + trackContentLength(c); + delegate.print(c); + } + + public void print(double d) throws IOException { + trackContentLength(d); + delegate.print(d); + } + + public void print(float f) throws IOException { + trackContentLength(f); + delegate.print(f); + } + + public void print(int i) throws IOException { + trackContentLength(i); + delegate.print(i); + } + + public void print(long l) throws IOException { + trackContentLength(l); + delegate.print(l); + } + + public void print(String s) throws IOException { + trackContentLength(s); + delegate.print(s); + } + + public void println() throws IOException { + trackContentLengthLn(); + delegate.println(); + } + + public void println(boolean b) throws IOException { + trackContentLength(b); + trackContentLengthLn(); + delegate.println(b); + } + + public void println(char c) throws IOException { + trackContentLength(c); + trackContentLengthLn(); + delegate.println(c); + } + + public void println(double d) throws IOException { + trackContentLength(d); + trackContentLengthLn(); + delegate.println(d); + } + + public void println(float f) throws IOException { + trackContentLength(f); + trackContentLengthLn(); + delegate.println(f); + } + + public void println(int i) throws IOException { + trackContentLength(i); + trackContentLengthLn(); + delegate.println(i); + } + + public void println(long l) throws IOException { + trackContentLength(l); + trackContentLengthLn(); + delegate.println(l); + } + + public void println(String s) throws IOException { + trackContentLength(s); + trackContentLengthLn(); + delegate.println(s); + } + + public void write(byte[] b) throws IOException { + trackContentLength(b); + delegate.write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + checkContentLength(len); + delegate.write(b, off, len); + } + + public String toString() { + return getClass().getName() + "[delegate=" + delegate.toString() + "]"; + } + } } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/web/http/OncePerRequestFilter.java b/spring-session/src/main/java/org/springframework/session/web/http/OncePerRequestFilter.java index 61bbbacf..2ded8ddb 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/OncePerRequestFilter.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/OncePerRequestFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -28,62 +28,62 @@ import java.io.IOException; * @author Rob Winch */ abstract class OncePerRequestFilter implements Filter { - /** - * Suffix that gets appended to the filter name for the - * "already filtered" request attribute. - */ - public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED"; + /** + * Suffix that gets appended to the filter name for the + * "already filtered" request attribute. + */ + public static final String ALREADY_FILTERED_SUFFIX = ".FILTERED"; - private String alreadyFilteredAttributeName = getClass().getName().concat(ALREADY_FILTERED_SUFFIX); + private String alreadyFilteredAttributeName = getClass().getName().concat(ALREADY_FILTERED_SUFFIX); - /** - * This {@code doFilter} implementation stores a request attribute for - * "already filtered", proceeding without filtering again if the - * attribute is already there. - */ - public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) - throws ServletException, IOException { + /** + * This {@code doFilter} implementation stores a request attribute for + * "already filtered", proceeding without filtering again if the + * attribute is already there. + */ + public final void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) + throws ServletException, IOException { - if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { - throw new ServletException("OncePerRequestFilter just supports HTTP requests"); - } - HttpServletRequest httpRequest = (HttpServletRequest) request; - HttpServletResponse httpResponse = (HttpServletResponse) response; - boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null; + if (!(request instanceof HttpServletRequest) || !(response instanceof HttpServletResponse)) { + throw new ServletException("OncePerRequestFilter just supports HTTP requests"); + } + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + boolean hasAlreadyFilteredAttribute = request.getAttribute(alreadyFilteredAttributeName) != null; - if (hasAlreadyFilteredAttribute) { + if (hasAlreadyFilteredAttribute) { - // Proceed without invoking this filter... - filterChain.doFilter(request, response); - } - else { - // Do invoke this filter... - request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE); - try { - doFilterInternal(httpRequest, httpResponse, filterChain); - } - finally { - // Remove the "already filtered" request attribute for this request. - request.removeAttribute(alreadyFilteredAttributeName); - } - } - } + // Proceed without invoking this filter... + filterChain.doFilter(request, response); + } + else { + // Do invoke this filter... + request.setAttribute(alreadyFilteredAttributeName, Boolean.TRUE); + try { + doFilterInternal(httpRequest, httpResponse, filterChain); + } + finally { + // Remove the "already filtered" request attribute for this request. + request.removeAttribute(alreadyFilteredAttributeName); + } + } + } - /** - * Same contract as for {@code doFilter}, but guaranteed to be - * just invoked once per request within a single request thread. - *

Provides HttpServletRequest and HttpServletResponse arguments instead of the - * default ServletRequest and ServletResponse ones. - * @see Filter#doFilter - */ - protected abstract void doFilterInternal( - HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) - throws ServletException, IOException; + /** + * Same contract as for {@code doFilter}, but guaranteed to be + * just invoked once per request within a single request thread. + *

Provides HttpServletRequest and HttpServletResponse arguments instead of the + * default ServletRequest and ServletResponse ones. + * @see Filter#doFilter + */ + protected abstract void doFilterInternal( + HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) + throws ServletException, IOException; - public void init(FilterConfig config) {} + public void init(FilterConfig config) {} - public void destroy() {} + public void destroy() {} } diff --git a/spring-session/src/main/java/org/springframework/session/web/http/RequestResponsePostProcessor.java b/spring-session/src/main/java/org/springframework/session/web/http/RequestResponsePostProcessor.java index c718ee8b..9c44effd 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/RequestResponsePostProcessor.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/RequestResponsePostProcessor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -27,33 +27,33 @@ import javax.servlet.http.HttpServletResponse; */ public interface RequestResponsePostProcessor { - /** - * Allows customizing the {@link HttpServletRequest}. - * - * @param request - * the original {@link HttpServletRequest}. Cannot be null. - * @param response - * the original {@link HttpServletResponse}. This is NOT the - * result of - * {@link #wrapResponse(HttpServletRequest, HttpServletResponse)} - * Cannot be null. . - * @return a non-null {@link HttpServletRequest} - */ - HttpServletRequest wrapRequest(HttpServletRequest request, - HttpServletResponse response); + /** + * Allows customizing the {@link HttpServletRequest}. + * + * @param request + * the original {@link HttpServletRequest}. Cannot be null. + * @param response + * the original {@link HttpServletResponse}. This is NOT the + * result of + * {@link #wrapResponse(HttpServletRequest, HttpServletResponse)} + * Cannot be null. . + * @return a non-null {@link HttpServletRequest} + */ + HttpServletRequest wrapRequest(HttpServletRequest request, + HttpServletResponse response); - /** - * Allows customizing the {@link HttpServletResponse}. - * - * @param request - * the original {@link HttpServletRequest}. This is NOT the - * result of - * {@link #wrapRequest(HttpServletRequest, HttpServletResponse)}. - * Cannot be null. - * @param response - * the original {@link HttpServletResponse}. Cannot be null. - * @return a non-null {@link HttpServletResponse} - */ - HttpServletResponse wrapResponse(HttpServletRequest request, - HttpServletResponse response); + /** + * Allows customizing the {@link HttpServletResponse}. + * + * @param request + * the original {@link HttpServletRequest}. This is NOT the + * result of + * {@link #wrapRequest(HttpServletRequest, HttpServletResponse)}. + * Cannot be null. + * @param response + * the original {@link HttpServletResponse}. Cannot be null. + * @return a non-null {@link HttpServletResponse} + */ + HttpServletResponse wrapResponse(HttpServletRequest request, + HttpServletResponse response); } diff --git a/spring-session/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java b/spring-session/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java index ee89cf21..4bcecc23 100644 --- a/spring-session/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java +++ b/spring-session/src/main/java/org/springframework/session/web/http/SessionRepositoryFilter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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 @@ -54,342 +54,342 @@ import java.util.Set; */ @Order(SessionRepositoryFilter.DEFAULT_ORDER) public class SessionRepositoryFilter extends OncePerRequestFilter { - public static final String SESSION_REPOSITORY_ATTR = SessionRepository.class.getName(); + public static final String SESSION_REPOSITORY_ATTR = SessionRepository.class.getName(); - public static final int DEFAULT_ORDER = Integer.MIN_VALUE + 50; + public static final int DEFAULT_ORDER = Integer.MIN_VALUE + 50; - private final SessionRepository sessionRepository; + private final SessionRepository sessionRepository; - private MultiHttpSessionStrategy httpSessionStrategy = new CookieHttpSessionStrategy(); + private MultiHttpSessionStrategy httpSessionStrategy = new CookieHttpSessionStrategy(); - /** - * Creates a new instance - * - * @param sessionRepository the SessionRepository to use. Cannot be null. - */ - public SessionRepositoryFilter(SessionRepository sessionRepository) { - if(sessionRepository == null) { - throw new IllegalArgumentException("SessionRepository cannot be null"); - } - this.sessionRepository = sessionRepository; - } + /** + * Creates a new instance + * + * @param sessionRepository the SessionRepository to use. Cannot be null. + */ + public SessionRepositoryFilter(SessionRepository sessionRepository) { + if(sessionRepository == null) { + throw new IllegalArgumentException("SessionRepository cannot be null"); + } + this.sessionRepository = sessionRepository; + } - /** - * Sets the {@link HttpSessionStrategy} to be used. The default is a {@link CookieHttpSessionStrategy}. - * - * @param httpSessionStrategy the {@link HttpSessionStrategy} to use. Cannot be null. - */ - public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) { - if(sessionRepository == null) { - throw new IllegalArgumentException("httpSessionIdStrategy cannot be null"); - } - this.httpSessionStrategy = new MultiHttpSessionStrategyAdapter(httpSessionStrategy); - } + /** + * Sets the {@link HttpSessionStrategy} to be used. The default is a {@link CookieHttpSessionStrategy}. + * + * @param httpSessionStrategy the {@link HttpSessionStrategy} to use. Cannot be null. + */ + public void setHttpSessionStrategy(HttpSessionStrategy httpSessionStrategy) { + if(sessionRepository == null) { + throw new IllegalArgumentException("httpSessionIdStrategy cannot be null"); + } + this.httpSessionStrategy = new MultiHttpSessionStrategyAdapter(httpSessionStrategy); + } - /** - * Sets the {@link MultiHttpSessionStrategy} to be used. The default is a {@link CookieHttpSessionStrategy}. - * - * @param httpSessionStrategy the {@link MultiHttpSessionStrategy} to use. Cannot be null. - */ - public void setHttpSessionStrategy(MultiHttpSessionStrategy httpSessionStrategy) { - if(sessionRepository == null) { - throw new IllegalArgumentException("httpSessionIdStrategy cannot be null"); - } - this.httpSessionStrategy = httpSessionStrategy; - } + /** + * Sets the {@link MultiHttpSessionStrategy} to be used. The default is a {@link CookieHttpSessionStrategy}. + * + * @param httpSessionStrategy the {@link MultiHttpSessionStrategy} to use. Cannot be null. + */ + public void setHttpSessionStrategy(MultiHttpSessionStrategy httpSessionStrategy) { + if(sessionRepository == null) { + throw new IllegalArgumentException("httpSessionIdStrategy cannot be null"); + } + this.httpSessionStrategy = httpSessionStrategy; + } - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - request.setAttribute(SESSION_REPOSITORY_ATTR, sessionRepository); + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + request.setAttribute(SESSION_REPOSITORY_ATTR, sessionRepository); - SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response); - SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(wrappedRequest,response); + SessionRepositoryRequestWrapper wrappedRequest = new SessionRepositoryRequestWrapper(request, response); + SessionRepositoryResponseWrapper wrappedResponse = new SessionRepositoryResponseWrapper(wrappedRequest,response); - HttpServletRequest strategyRequest = httpSessionStrategy.wrapRequest(wrappedRequest, wrappedResponse); - HttpServletResponse strategyResponse = httpSessionStrategy.wrapResponse(wrappedRequest, wrappedResponse); + HttpServletRequest strategyRequest = httpSessionStrategy.wrapRequest(wrappedRequest, wrappedResponse); + HttpServletResponse strategyResponse = httpSessionStrategy.wrapResponse(wrappedRequest, wrappedResponse); - try { - filterChain.doFilter(strategyRequest, strategyResponse); - } finally { - wrappedRequest.commitSession(); - } - } + try { + filterChain.doFilter(strategyRequest, strategyResponse); + } finally { + wrappedRequest.commitSession(); + } + } - /** - * Allows ensuring that the session is saved if the response is committed. - * - * @author Rob Winch - * @since 1.0 - */ - private final class SessionRepositoryResponseWrapper extends OnCommittedResponseWrapper { + /** + * Allows ensuring that the session is saved if the response is committed. + * + * @author Rob Winch + * @since 1.0 + */ + private final class SessionRepositoryResponseWrapper extends OnCommittedResponseWrapper { - private final SessionRepositoryRequestWrapper request; + private final SessionRepositoryRequestWrapper request; - /** - * @param response the response to be wrapped - */ - public SessionRepositoryResponseWrapper(SessionRepositoryRequestWrapper request, HttpServletResponse response) { - super(response); - if(request == null) { - throw new IllegalArgumentException("request cannot be null"); - } - this.request = request; - } + /** + * @param response the response to be wrapped + */ + public SessionRepositoryResponseWrapper(SessionRepositoryRequestWrapper request, HttpServletResponse response) { + super(response); + if(request == null) { + throw new IllegalArgumentException("request cannot be null"); + } + this.request = request; + } - @Override - protected void onResponseCommitted() { - request.commitSession(); - } - } + @Override + protected void onResponseCommitted() { + request.commitSession(); + } + } - /** - * A {@link javax.servlet.http.HttpServletRequest} that retrieves the {@link javax.servlet.http.HttpSession} using a - * {@link org.springframework.session.SessionRepository}. - * - * @author Rob Winch - * @since 1.0 - */ - private final class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper { - private HttpSessionWrapper currentSession; - private Boolean requestedSessionIdValid; - private final HttpServletResponse response; + /** + * A {@link javax.servlet.http.HttpServletRequest} that retrieves the {@link javax.servlet.http.HttpSession} using a + * {@link org.springframework.session.SessionRepository}. + * + * @author Rob Winch + * @since 1.0 + */ + private final class SessionRepositoryRequestWrapper extends HttpServletRequestWrapper { + private HttpSessionWrapper currentSession; + private Boolean requestedSessionIdValid; + private final HttpServletResponse response; - private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletResponse response) { - super(request); - this.response = response; - } + private SessionRepositoryRequestWrapper(HttpServletRequest request, HttpServletResponse response) { + super(request); + this.response = response; + } - /** - * Uses the HttpSessionStrategy to write the session id tot he response and persist the Session. - */ - private void commitSession() { - HttpSessionWrapper wrappedSession = currentSession; - if(wrappedSession == null) { - if(isInvalidateClientSession()) { - httpSessionStrategy.onInvalidateSession(this, response); - } - } else { - S session = wrappedSession.session; - sessionRepository.save(session); - if(!isRequestedSessionIdValid() || !session.getId().equals(getRequestedSessionId())) { - httpSessionStrategy.onNewSession(session, this, response); - } - } - } + /** + * Uses the HttpSessionStrategy to write the session id tot he response and persist the Session. + */ + private void commitSession() { + HttpSessionWrapper wrappedSession = currentSession; + if(wrappedSession == null) { + if(isInvalidateClientSession()) { + httpSessionStrategy.onInvalidateSession(this, response); + } + } else { + S session = wrappedSession.session; + sessionRepository.save(session); + if(!isRequestedSessionIdValid() || !session.getId().equals(getRequestedSessionId())) { + httpSessionStrategy.onNewSession(session, this, response); + } + } + } - public boolean isRequestedSessionIdValid() { - if(requestedSessionIdValid == null) { - String sessionId = getRequestedSessionId(); - S session = sessionId == null ? null : sessionRepository.getSession(sessionId); - return isRequestedSessionIdValid(session); - } + public boolean isRequestedSessionIdValid() { + if(requestedSessionIdValid == null) { + String sessionId = getRequestedSessionId(); + S session = sessionId == null ? null : sessionRepository.getSession(sessionId); + return isRequestedSessionIdValid(session); + } - return requestedSessionIdValid; - } + return requestedSessionIdValid; + } - private boolean isRequestedSessionIdValid(S session) { - if(requestedSessionIdValid == null) { - requestedSessionIdValid = session != null; - } - return requestedSessionIdValid; - } + private boolean isRequestedSessionIdValid(S session) { + if(requestedSessionIdValid == null) { + requestedSessionIdValid = session != null; + } + return requestedSessionIdValid; + } - private boolean isInvalidateClientSession() { - return currentSession == null && isRequestedSessionIdValid(); - } + private boolean isInvalidateClientSession() { + return currentSession == null && isRequestedSessionIdValid(); + } - @Override - public HttpSession getSession(boolean create) { - if(currentSession != null) { - return currentSession; - } - String requestedSessionId = getRequestedSessionId(); - if(requestedSessionId != null) { - S session = sessionRepository.getSession(requestedSessionId); - if(session != null) { - this.requestedSessionIdValid = true; - currentSession = new HttpSessionWrapper(session, getServletContext()); - currentSession.setNew(false); - return currentSession; - } - } - if(!create) { - return null; - } - S session = sessionRepository.createSession(); - currentSession = new HttpSessionWrapper(session, getServletContext()); - return currentSession; - } + @Override + public HttpSession getSession(boolean create) { + if(currentSession != null) { + return currentSession; + } + String requestedSessionId = getRequestedSessionId(); + if(requestedSessionId != null) { + S session = sessionRepository.getSession(requestedSessionId); + if(session != null) { + this.requestedSessionIdValid = true; + currentSession = new HttpSessionWrapper(session, getServletContext()); + currentSession.setNew(false); + return currentSession; + } + } + if(!create) { + return null; + } + S session = sessionRepository.createSession(); + currentSession = new HttpSessionWrapper(session, getServletContext()); + return currentSession; + } - @Override - public HttpSession getSession() { - return getSession(true); - } + @Override + public HttpSession getSession() { + return getSession(true); + } - @Override - public String getRequestedSessionId() { - return httpSessionStrategy.getRequestedSessionId(this); - } + @Override + public String getRequestedSessionId() { + return httpSessionStrategy.getRequestedSessionId(this); + } - /** - * Allows creating an HttpSession from a Session instance. - * - * @author Rob Winch - * @since 1.0 - */ - private final class HttpSessionWrapper implements HttpSession { - private final S session; - private final ServletContext servletContext; - private boolean invalidated; - private boolean old; + /** + * Allows creating an HttpSession from a Session instance. + * + * @author Rob Winch + * @since 1.0 + */ + private final class HttpSessionWrapper implements HttpSession { + private final S session; + private final ServletContext servletContext; + private boolean invalidated; + private boolean old; - public HttpSessionWrapper(S session, ServletContext servletContext) { - this.session = session; - this.servletContext = servletContext; - } + public HttpSessionWrapper(S session, ServletContext servletContext) { + this.session = session; + this.servletContext = servletContext; + } - public long getCreationTime() { - checkState(); - return session.getCreationTime(); - } + public long getCreationTime() { + checkState(); + return session.getCreationTime(); + } - public String getId() { - return session.getId(); - } + public String getId() { + return session.getId(); + } - public long getLastAccessedTime() { - checkState(); - return session.getLastAccessedTime(); - } + public long getLastAccessedTime() { + checkState(); + return session.getLastAccessedTime(); + } - public ServletContext getServletContext() { - return servletContext; - } + public ServletContext getServletContext() { + return servletContext; + } - public void setMaxInactiveInterval(int interval) { - session.setMaxInactiveIntervalInSeconds(interval); - } + public void setMaxInactiveInterval(int interval) { + session.setMaxInactiveIntervalInSeconds(interval); + } - public int getMaxInactiveInterval() { - return session.getMaxInactiveIntervalInSeconds(); - } + public int getMaxInactiveInterval() { + return session.getMaxInactiveIntervalInSeconds(); + } - @SuppressWarnings("deprecation") - public HttpSessionContext getSessionContext() { - return NOOP_SESSION_CONTEXT; - } + @SuppressWarnings("deprecation") + public HttpSessionContext getSessionContext() { + return NOOP_SESSION_CONTEXT; + } - public Object getAttribute(String name) { - checkState(); - return session.getAttribute(name); - } + public Object getAttribute(String name) { + checkState(); + return session.getAttribute(name); + } - public Object getValue(String name) { - return getAttribute(name); - } + public Object getValue(String name) { + return getAttribute(name); + } - public Enumeration getAttributeNames() { - checkState(); - return Collections.enumeration(session.getAttributeNames()); - } + public Enumeration getAttributeNames() { + checkState(); + return Collections.enumeration(session.getAttributeNames()); + } - public String[] getValueNames() { - checkState(); - Set attrs = session.getAttributeNames(); - return attrs.toArray(new String[0]); - } + public String[] getValueNames() { + checkState(); + Set attrs = session.getAttributeNames(); + return attrs.toArray(new String[0]); + } - public void setAttribute(String name, Object value) { - checkState(); - session.setAttribute(name, value); - } + public void setAttribute(String name, Object value) { + checkState(); + session.setAttribute(name, value); + } - public void putValue(String name, Object value) { - setAttribute(name, value); - } + public void putValue(String name, Object value) { + setAttribute(name, value); + } - public void removeAttribute(String name) { - checkState(); - session.removeAttribute(name); - } + public void removeAttribute(String name) { + checkState(); + session.removeAttribute(name); + } - public void removeValue(String name) { - removeAttribute(name); - } + public void removeValue(String name) { + removeAttribute(name); + } - public void invalidate() { - checkState(); - this.invalidated = true; - currentSession = null; - sessionRepository.delete(getId()); - } + public void invalidate() { + checkState(); + this.invalidated = true; + currentSession = null; + sessionRepository.delete(getId()); + } - public void setNew(boolean isNew) { - this.old = !isNew; - } + public void setNew(boolean isNew) { + this.old = !isNew; + } - public boolean isNew() { - checkState(); - return !old; - } + public boolean isNew() { + checkState(); + return !old; + } - private void checkState() { - if(invalidated) { - throw new IllegalStateException("The HttpSession has already be invalidated."); - } - } - } - } + private void checkState() { + if(invalidated) { + throw new IllegalStateException("The HttpSession has already be invalidated."); + } + } + } + } - @SuppressWarnings("deprecation") - private static final HttpSessionContext NOOP_SESSION_CONTEXT = new HttpSessionContext() { - public HttpSession getSession(String sessionId) { - return null; - } + @SuppressWarnings("deprecation") + private static final HttpSessionContext NOOP_SESSION_CONTEXT = new HttpSessionContext() { + public HttpSession getSession(String sessionId) { + return null; + } - public Enumeration getIds() { - return EMPTY_ENUMERATION; - } - }; + public Enumeration getIds() { + return EMPTY_ENUMERATION; + } + }; - private static final Enumeration EMPTY_ENUMERATION = new Enumeration() { - public boolean hasMoreElements() { - return false; - } + private static final Enumeration EMPTY_ENUMERATION = new Enumeration() { + public boolean hasMoreElements() { + return false; + } - public String nextElement() { - throw new NoSuchElementException("a"); - } - }; + public String nextElement() { + throw new NoSuchElementException("a"); + } + }; - static class MultiHttpSessionStrategyAdapter implements MultiHttpSessionStrategy { - private HttpSessionStrategy delegate; + static class MultiHttpSessionStrategyAdapter implements MultiHttpSessionStrategy { + private HttpSessionStrategy delegate; - public MultiHttpSessionStrategyAdapter(HttpSessionStrategy delegate) { - this.delegate = delegate; - } + public MultiHttpSessionStrategyAdapter(HttpSessionStrategy delegate) { + this.delegate = delegate; + } - public String getRequestedSessionId(HttpServletRequest request) { - return delegate.getRequestedSessionId(request); - } + public String getRequestedSessionId(HttpServletRequest request) { + return delegate.getRequestedSessionId(request); + } - public void onNewSession(Session session, HttpServletRequest request, - HttpServletResponse response) { - delegate.onNewSession(session, request, response); - } + public void onNewSession(Session session, HttpServletRequest request, + HttpServletResponse response) { + delegate.onNewSession(session, request, response); + } - public void onInvalidateSession(HttpServletRequest request, - HttpServletResponse response) { - delegate.onInvalidateSession(request, response); - } + public void onInvalidateSession(HttpServletRequest request, + HttpServletResponse response) { + delegate.onInvalidateSession(request, response); + } - public HttpServletRequest wrapRequest(HttpServletRequest request, - HttpServletResponse response) { - return request; - } + public HttpServletRequest wrapRequest(HttpServletRequest request, + HttpServletResponse response) { + return request; + } - public HttpServletResponse wrapResponse(HttpServletRequest request, - HttpServletResponse response) { - return response; - } - } + public HttpServletResponse wrapResponse(HttpServletRequest request, + HttpServletResponse response) { + return response; + } + } } diff --git a/spring-session/src/main/java/org/springframework/session/web/socket/config/annotation/AbstractSessionWebSocketMessageBrokerConfigurer.java b/spring-session/src/main/java/org/springframework/session/web/socket/config/annotation/AbstractSessionWebSocketMessageBrokerConfigurer.java index 4cd7b599..e16de01c 100644 --- a/spring-session/src/main/java/org/springframework/session/web/socket/config/annotation/AbstractSessionWebSocketMessageBrokerConfigurer.java +++ b/spring-session/src/main/java/org/springframework/session/web/socket/config/annotation/AbstractSessionWebSocketMessageBrokerConfigurer.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -74,71 +74,71 @@ import org.springframework.web.socket.server.HandshakeInterceptor; */ public abstract class AbstractSessionWebSocketMessageBrokerConfigurer extends AbstractWebSocketMessageBrokerConfigurer { - @Autowired - @SuppressWarnings("rawtypes") - private SessionRepository sessionRepository; + @Autowired + @SuppressWarnings("rawtypes") + private SessionRepository sessionRepository; - @Autowired - private ApplicationEventPublisher eventPublisher; + @Autowired + private ApplicationEventPublisher eventPublisher; - @Override - public void configureClientInboundChannel(ChannelRegistration registration) { - registration.setInterceptors(sessionRepositoryInterceptor()); - } + @Override + public void configureClientInboundChannel(ChannelRegistration registration) { + registration.setInterceptors(sessionRepositoryInterceptor()); + } - public final void registerStompEndpoints(StompEndpointRegistry registry) { - configureStompEndpoints(new SessionStompEndpointRegistry(registry, sessionRepositoryInterceptor())); - } + public final void registerStompEndpoints(StompEndpointRegistry registry) { + configureStompEndpoints(new SessionStompEndpointRegistry(registry, sessionRepositoryInterceptor())); + } - /** - * Register STOMP endpoints mapping each to a specific URL and (optionally) - * enabling and configuring SockJS fallback options with a - * {@link SessionRepositoryMessageInterceptor} automatically added as an - * interceptor. - * - * @param registry - * the {@link StompEndpointRegistry} which automatically has a - * {@link SessionRepositoryMessageInterceptor} added to it. - */ - protected abstract void configureStompEndpoints(StompEndpointRegistry registry); + /** + * Register STOMP endpoints mapping each to a specific URL and (optionally) + * enabling and configuring SockJS fallback options with a + * {@link SessionRepositoryMessageInterceptor} automatically added as an + * interceptor. + * + * @param registry + * the {@link StompEndpointRegistry} which automatically has a + * {@link SessionRepositoryMessageInterceptor} added to it. + */ + protected abstract void configureStompEndpoints(StompEndpointRegistry registry); - @Override - public void configureWebSocketTransport( - WebSocketTransportRegistration registration) { - registration.addDecoratorFactory(wsConnectHandlerDecoratorFactory()); - } + @Override + public void configureWebSocketTransport( + WebSocketTransportRegistration registration) { + registration.addDecoratorFactory(wsConnectHandlerDecoratorFactory()); + } - @Bean - public WebSocketRegistryListener webSocketRegistryListener() { - return new WebSocketRegistryListener(); - } + @Bean + public WebSocketRegistryListener webSocketRegistryListener() { + return new WebSocketRegistryListener(); + } - @Bean - public WebSocketConnectHandlerDecoratorFactory wsConnectHandlerDecoratorFactory() { - return new WebSocketConnectHandlerDecoratorFactory(eventPublisher); - } + @Bean + public WebSocketConnectHandlerDecoratorFactory wsConnectHandlerDecoratorFactory() { + return new WebSocketConnectHandlerDecoratorFactory(eventPublisher); + } - @Bean - @SuppressWarnings("unchecked") - public SessionRepositoryMessageInterceptor sessionRepositoryInterceptor() { - return new SessionRepositoryMessageInterceptor(sessionRepository); - } + @Bean + @SuppressWarnings("unchecked") + public SessionRepositoryMessageInterceptor sessionRepositoryInterceptor() { + return new SessionRepositoryMessageInterceptor(sessionRepository); + } - static class SessionStompEndpointRegistry implements StompEndpointRegistry { - private final StompEndpointRegistry registry; - private final HandshakeInterceptor interceptor; + static class SessionStompEndpointRegistry implements StompEndpointRegistry { + private final StompEndpointRegistry registry; + private final HandshakeInterceptor interceptor; - public SessionStompEndpointRegistry(StompEndpointRegistry registry, - HandshakeInterceptor interceptor) { - this.registry = registry; - this.interceptor = interceptor; - } + public SessionStompEndpointRegistry(StompEndpointRegistry registry, + HandshakeInterceptor interceptor) { + this.registry = registry; + this.interceptor = interceptor; + } - public StompWebSocketEndpointRegistration addEndpoint(String... paths) { - StompWebSocketEndpointRegistration endpoints = registry.addEndpoint(paths); - endpoints.addInterceptors(interceptor); - return endpoints; - } - } + public StompWebSocketEndpointRegistration addEndpoint(String... paths) { + StompWebSocketEndpointRegistration endpoints = registry.addEndpoint(paths); + endpoints.addInterceptors(interceptor); + return endpoints; + } + } } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/web/socket/events/SessionConnectEvent.java b/spring-session/src/main/java/org/springframework/session/web/socket/events/SessionConnectEvent.java index c4bf3408..fec9c23c 100644 --- a/spring-session/src/main/java/org/springframework/session/web/socket/events/SessionConnectEvent.java +++ b/spring-session/src/main/java/org/springframework/session/web/socket/events/SessionConnectEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -34,14 +34,14 @@ import org.springframework.web.socket.WebSocketSession; @SuppressWarnings("serial") public class SessionConnectEvent extends ApplicationEvent { - private final WebSocketSession webSocketSession; + private final WebSocketSession webSocketSession; - public SessionConnectEvent(Object source, WebSocketSession webSocketSession) { - super(source); - this.webSocketSession = webSocketSession; - } + public SessionConnectEvent(Object source, WebSocketSession webSocketSession) { + super(source); + this.webSocketSession = webSocketSession; + } - public WebSocketSession getWebSocketSession() { - return webSocketSession; - } + public WebSocketSession getWebSocketSession() { + return webSocketSession; + } } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactory.java b/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactory.java index 476b92cc..43b2f5bf 100644 --- a/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactory.java +++ b/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactory.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -42,46 +42,46 @@ import org.springframework.web.socket.handler.WebSocketHandlerDecoratorFactory; */ public final class WebSocketConnectHandlerDecoratorFactory implements WebSocketHandlerDecoratorFactory { - private static final Log logger = LogFactory.getLog(WebSocketConnectHandlerDecoratorFactory.class); + private static final Log logger = LogFactory.getLog(WebSocketConnectHandlerDecoratorFactory.class); - private final ApplicationEventPublisher eventPublisher; + private final ApplicationEventPublisher eventPublisher; - /** - * Creates a new instance - * - * @param eventPublisher the {@link ApplicationEventPublisher} to use. Cannot be null. - */ - public WebSocketConnectHandlerDecoratorFactory( - ApplicationEventPublisher eventPublisher) { - Assert.notNull(eventPublisher, "eventPublisher cannot be null"); - this.eventPublisher = eventPublisher; - } + /** + * Creates a new instance + * + * @param eventPublisher the {@link ApplicationEventPublisher} to use. Cannot be null. + */ + public WebSocketConnectHandlerDecoratorFactory( + ApplicationEventPublisher eventPublisher) { + Assert.notNull(eventPublisher, "eventPublisher cannot be null"); + this.eventPublisher = eventPublisher; + } - public WebSocketHandler decorate(WebSocketHandler handler) { - return new SessionWebSocketHandler(handler); - } + public WebSocketHandler decorate(WebSocketHandler handler) { + return new SessionWebSocketHandler(handler); + } - private final class SessionWebSocketHandler extends WebSocketHandlerDecorator { + private final class SessionWebSocketHandler extends WebSocketHandlerDecorator { - public SessionWebSocketHandler(WebSocketHandler delegate) { - super(delegate); - } + public SessionWebSocketHandler(WebSocketHandler delegate) { + super(delegate); + } - @Override - public void afterConnectionEstablished(WebSocketSession wsSession) - throws Exception { - super.afterConnectionEstablished(wsSession); + @Override + public void afterConnectionEstablished(WebSocketSession wsSession) + throws Exception { + super.afterConnectionEstablished(wsSession); - publishEvent(new SessionConnectEvent(this,wsSession)); - } + publishEvent(new SessionConnectEvent(this,wsSession)); + } - private void publishEvent(ApplicationEvent event) { - try { - eventPublisher.publishEvent(event); - } - catch (Throwable ex) { - logger.error("Error publishing " + event + ".", ex); - } - } - } + private void publishEvent(ApplicationEvent event) { + try { + eventPublisher.publishEvent(event); + } + catch (Throwable ex) { + logger.error("Error publishing " + event + ".", ex); + } + } + } } diff --git a/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketRegistryListener.java b/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketRegistryListener.java index b3341785..ebc02ac1 100644 --- a/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketRegistryListener.java +++ b/spring-session/src/main/java/org/springframework/session/web/socket/handler/WebSocketRegistryListener.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -45,88 +45,88 @@ import org.springframework.web.socket.messaging.SessionDisconnectEvent; */ public final class WebSocketRegistryListener implements ApplicationListener { - private static final Log logger = LogFactory.getLog(WebSocketRegistryListener.class); + private static final Log logger = LogFactory.getLog(WebSocketRegistryListener.class); - static final CloseStatus SESSION_EXPIRED_STATUS = new CloseStatus(CloseStatus.POLICY_VIOLATION.getCode(), - "This connection was established under an authenticated HTTP Session that has expired"); + static final CloseStatus SESSION_EXPIRED_STATUS = new CloseStatus(CloseStatus.POLICY_VIOLATION.getCode(), + "This connection was established under an authenticated HTTP Session that has expired"); - private final ConcurrentHashMap> httpSessionIdToWsSessions = new ConcurrentHashMap>(); + private final ConcurrentHashMap> httpSessionIdToWsSessions = new ConcurrentHashMap>(); - public void onApplicationEvent(ApplicationEvent event) { - if(event instanceof SessionDestroyedEvent) { - SessionDestroyedEvent e = (SessionDestroyedEvent) event; - closeWsSessions(e.getSessionId()); - } else if(event instanceof SessionConnectEvent) { - SessionConnectEvent e = (SessionConnectEvent) event; - afterConnectionEstablished(e.getWebSocketSession()); - } else if(event instanceof SessionDisconnectEvent) { - SessionDisconnectEvent e = (SessionDisconnectEvent) event; - Map sessionAttributes = SimpMessageHeaderAccessor.getSessionAttributes(e.getMessage().getHeaders()); - String httpSessionId = sessionAttributes == null ? null : SessionRepositoryMessageInterceptor.getSessionId(sessionAttributes); - afterConnectionClosed(httpSessionId, e.getSessionId()); - } - } + public void onApplicationEvent(ApplicationEvent event) { + if(event instanceof SessionDestroyedEvent) { + SessionDestroyedEvent e = (SessionDestroyedEvent) event; + closeWsSessions(e.getSessionId()); + } else if(event instanceof SessionConnectEvent) { + SessionConnectEvent e = (SessionConnectEvent) event; + afterConnectionEstablished(e.getWebSocketSession()); + } else if(event instanceof SessionDisconnectEvent) { + SessionDisconnectEvent e = (SessionDisconnectEvent) event; + Map sessionAttributes = SimpMessageHeaderAccessor.getSessionAttributes(e.getMessage().getHeaders()); + String httpSessionId = sessionAttributes == null ? null : SessionRepositoryMessageInterceptor.getSessionId(sessionAttributes); + afterConnectionClosed(httpSessionId, e.getSessionId()); + } + } - private void afterConnectionEstablished(WebSocketSession wsSession) { - Principal principal = wsSession.getPrincipal(); - if(principal == null) { - return; - } + private void afterConnectionEstablished(WebSocketSession wsSession) { + Principal principal = wsSession.getPrincipal(); + if(principal == null) { + return; + } - String httpSessionId = getHttpSessionId(wsSession); - registerWsSession(httpSessionId, wsSession); - } + String httpSessionId = getHttpSessionId(wsSession); + registerWsSession(httpSessionId, wsSession); + } - private String getHttpSessionId(WebSocketSession wsSession) { - Map attributes = wsSession.getAttributes(); - return SessionRepositoryMessageInterceptor.getSessionId(attributes); - } + private String getHttpSessionId(WebSocketSession wsSession) { + Map attributes = wsSession.getAttributes(); + return SessionRepositoryMessageInterceptor.getSessionId(attributes); + } - private void afterConnectionClosed(String httpSessionId, String wsSessionId) { - if(httpSessionId == null) { - return; - } + private void afterConnectionClosed(String httpSessionId, String wsSessionId) { + if(httpSessionId == null) { + return; + } - Map sessions = httpSessionIdToWsSessions.get(httpSessionId); - if(sessions != null) { - boolean result = sessions.remove(wsSessionId) != null; - if(logger.isDebugEnabled()) { - logger.debug("Removal of " + wsSessionId + " was " + result); - } - if(sessions.isEmpty()) { - httpSessionIdToWsSessions.remove(httpSessionId); - if(logger.isDebugEnabled()) { - logger.debug("Removed the corresponding HTTP Session for " + wsSessionId + " since it contained no WebSocket mappings"); - } - } - } - } + Map sessions = httpSessionIdToWsSessions.get(httpSessionId); + if(sessions != null) { + boolean result = sessions.remove(wsSessionId) != null; + if(logger.isDebugEnabled()) { + logger.debug("Removal of " + wsSessionId + " was " + result); + } + if(sessions.isEmpty()) { + httpSessionIdToWsSessions.remove(httpSessionId); + if(logger.isDebugEnabled()) { + logger.debug("Removed the corresponding HTTP Session for " + wsSessionId + " since it contained no WebSocket mappings"); + } + } + } + } - private void registerWsSession(String httpSessionId, WebSocketSession wsSession) { - Map sessions = httpSessionIdToWsSessions.get(httpSessionId); - if(sessions == null) { - sessions = - new ConcurrentHashMap(); - httpSessionIdToWsSessions.putIfAbsent(httpSessionId, sessions); - sessions = httpSessionIdToWsSessions.get(httpSessionId); - } - sessions.put(wsSession.getId(), wsSession); - } + private void registerWsSession(String httpSessionId, WebSocketSession wsSession) { + Map sessions = httpSessionIdToWsSessions.get(httpSessionId); + if(sessions == null) { + sessions = + new ConcurrentHashMap(); + httpSessionIdToWsSessions.putIfAbsent(httpSessionId, sessions); + sessions = httpSessionIdToWsSessions.get(httpSessionId); + } + sessions.put(wsSession.getId(), wsSession); + } - private void closeWsSessions(String httpSessionId) { - Map sessionsToClose = httpSessionIdToWsSessions.remove(httpSessionId); - if(sessionsToClose == null) { - return; - } - if(logger.isDebugEnabled()) { - logger.debug("Closing WebSocket connections associated to expired HTTP Session " + httpSessionId); - } - for(WebSocketSession toClose : sessionsToClose.values()) { - try { - toClose.close(SESSION_EXPIRED_STATUS); - } catch (IOException e) { - logger.debug("Failed to close WebSocketSession (this is nothing to worry about but for debugging only)",e); - } - } - } + private void closeWsSessions(String httpSessionId) { + Map sessionsToClose = httpSessionIdToWsSessions.remove(httpSessionId); + if(sessionsToClose == null) { + return; + } + if(logger.isDebugEnabled()) { + logger.debug("Closing WebSocket connections associated to expired HTTP Session " + httpSessionId); + } + for(WebSocketSession toClose : sessionsToClose.values()) { + try { + toClose.close(SESSION_EXPIRED_STATUS); + } catch (IOException e) { + logger.debug("Failed to close WebSocketSession (this is nothing to worry about but for debugging only)",e); + } + } + } } \ No newline at end of file diff --git a/spring-session/src/main/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptor.java b/spring-session/src/main/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptor.java index 5d04a698..a6cd44ee 100644 --- a/spring-session/src/main/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptor.java +++ b/spring-session/src/main/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptor.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2014 the original author or authors. + * Copyright 2002-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. @@ -66,93 +66,93 @@ import org.springframework.web.socket.server.HandshakeInterceptor; * @since 1.0 */ public final class SessionRepositoryMessageInterceptor extends ChannelInterceptorAdapter - implements HandshakeInterceptor { + implements HandshakeInterceptor { - private static final String SPRING_SESSION_ID_ATTR_NAME = "SPRING.SESSION.ID"; + private static final String SPRING_SESSION_ID_ATTR_NAME = "SPRING.SESSION.ID"; - private final SessionRepository sessionRepository; + private final SessionRepository sessionRepository; - private Set matchingMessageTypes; + private Set matchingMessageTypes; - /** - * Creates a new instance - * - * @param sessionRepository the {@link SessionRepository} to use. Cannot be null. - */ - public SessionRepositoryMessageInterceptor(SessionRepository sessionRepository) { - Assert.notNull(sessionRepository, "sessionRepository cannot be null"); - this.sessionRepository = sessionRepository; - this.matchingMessageTypes = EnumSet.of(SimpMessageType.CONNECT, SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE); - } + /** + * Creates a new instance + * + * @param sessionRepository the {@link SessionRepository} to use. Cannot be null. + */ + public SessionRepositoryMessageInterceptor(SessionRepository sessionRepository) { + Assert.notNull(sessionRepository, "sessionRepository cannot be null"); + this.sessionRepository = sessionRepository; + this.matchingMessageTypes = EnumSet.of(SimpMessageType.CONNECT, SimpMessageType.MESSAGE, SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE); + } - /** - *

- * Sets the {@link SimpMessageType} to match on. If the {@link Message} - * matches, then {@link #preSend(Message, MessageChannel)} ensures the - * {@link Session} is not expired and updates the - * {@link ExpiringSession#getLastAccessedTime()} - *

- * - *

- * The default is: SimpMessageType.CONNECT, SimpMessageType.MESSAGE, - * SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE. - *

- * - * @param matchingMessageTypes - * the {@link SimpMessageType} to match on in - * {@link #preSend(Message, MessageChannel)}, else the - * {@link Message} is continued without accessing or updating the - * {@link Session} - */ - public void setMatchingMessageTypes(Set matchingMessageTypes) { - Assert.notEmpty(matchingMessageTypes,"matchingMessageTypes cannot be null or empty"); - this.matchingMessageTypes = matchingMessageTypes; - } + /** + *

+ * Sets the {@link SimpMessageType} to match on. If the {@link Message} + * matches, then {@link #preSend(Message, MessageChannel)} ensures the + * {@link Session} is not expired and updates the + * {@link ExpiringSession#getLastAccessedTime()} + *

+ * + *

+ * The default is: SimpMessageType.CONNECT, SimpMessageType.MESSAGE, + * SimpMessageType.SUBSCRIBE, SimpMessageType.UNSUBSCRIBE. + *

+ * + * @param matchingMessageTypes + * the {@link SimpMessageType} to match on in + * {@link #preSend(Message, MessageChannel)}, else the + * {@link Message} is continued without accessing or updating the + * {@link Session} + */ + public void setMatchingMessageTypes(Set matchingMessageTypes) { + Assert.notEmpty(matchingMessageTypes,"matchingMessageTypes cannot be null or empty"); + this.matchingMessageTypes = matchingMessageTypes; + } - @Override - public Message preSend(Message message, MessageChannel channel) { - if(message == null) { - return message; - } - SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(message.getHeaders()); - if(!this.matchingMessageTypes.contains(messageType)) { - return super.preSend(message, channel); - } - Map sessionHeaders = SimpMessageHeaderAccessor.getSessionAttributes(message.getHeaders()); - String sessionId = sessionHeaders == null ? null : (String) sessionHeaders.get(SPRING_SESSION_ID_ATTR_NAME); - if (sessionId != null) { - S session = sessionRepository.getSession(sessionId); - if (session != null) { - // update the last accessed time - sessionRepository.save(session); - } - } - return super.preSend(message, channel); - } + @Override + public Message preSend(Message message, MessageChannel channel) { + if(message == null) { + return message; + } + SimpMessageType messageType = SimpMessageHeaderAccessor.getMessageType(message.getHeaders()); + if(!this.matchingMessageTypes.contains(messageType)) { + return super.preSend(message, channel); + } + Map sessionHeaders = SimpMessageHeaderAccessor.getSessionAttributes(message.getHeaders()); + String sessionId = sessionHeaders == null ? null : (String) sessionHeaders.get(SPRING_SESSION_ID_ATTR_NAME); + if (sessionId != null) { + S session = sessionRepository.getSession(sessionId); + if (session != null) { + // update the last accessed time + sessionRepository.save(session); + } + } + return super.preSend(message, channel); + } - public boolean beforeHandshake(ServerHttpRequest request, - ServerHttpResponse response, WebSocketHandler wsHandler, - Map attributes) throws Exception { - if (request instanceof ServletServerHttpRequest) { - ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; - HttpSession session = servletRequest.getServletRequest().getSession(false); - if (session != null) { - setSessionId(attributes, session.getId()); - } - } - return true; - } + public boolean beforeHandshake(ServerHttpRequest request, + ServerHttpResponse response, WebSocketHandler wsHandler, + Map attributes) throws Exception { + if (request instanceof ServletServerHttpRequest) { + ServletServerHttpRequest servletRequest = (ServletServerHttpRequest) request; + HttpSession session = servletRequest.getServletRequest().getSession(false); + if (session != null) { + setSessionId(attributes, session.getId()); + } + } + return true; + } - public void afterHandshake(ServerHttpRequest request, - ServerHttpResponse response, WebSocketHandler wsHandler, - Exception exception) { - } + public void afterHandshake(ServerHttpRequest request, + ServerHttpResponse response, WebSocketHandler wsHandler, + Exception exception) { + } - public static String getSessionId(Map attributes) { - return (String) attributes.get(SPRING_SESSION_ID_ATTR_NAME); - } + public static String getSessionId(Map attributes) { + return (String) attributes.get(SPRING_SESSION_ID_ATTR_NAME); + } - public static void setSessionId(Map attributes, String sessionId) { - attributes.put(SPRING_SESSION_ID_ATTR_NAME, sessionId); - } + public static void setSessionId(Map attributes, String sessionId) { + attributes.put(SPRING_SESSION_ID_ATTR_NAME, sessionId); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/MapSessionRepositoryTests.java b/spring-session/src/test/java/org/springframework/session/MapSessionRepositoryTests.java index 51eaa5b6..cdfa2da6 100644 --- a/spring-session/src/test/java/org/springframework/session/MapSessionRepositoryTests.java +++ b/spring-session/src/test/java/org/springframework/session/MapSessionRepositoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -23,40 +23,40 @@ import org.junit.Before; import org.junit.Test; public class MapSessionRepositoryTests { - MapSessionRepository repository; + MapSessionRepository repository; - MapSession session; + MapSession session; - @Before - public void setup() { - repository = new MapSessionRepository(); - session = new MapSession(); - } + @Before + public void setup() { + repository = new MapSessionRepository(); + session = new MapSession(); + } - @Test - public void getSessionExpired() { - session.setMaxInactiveIntervalInSeconds(1); - session.setLastAccessedTime(System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5)); - repository.save(session); + @Test + public void getSessionExpired() { + session.setMaxInactiveIntervalInSeconds(1); + session.setLastAccessedTime(System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5)); + repository.save(session); - assertThat(repository.getSession(session.getId())).isNull(); - } + assertThat(repository.getSession(session.getId())).isNull(); + } - @Test - public void createSessionDefaultExpiration() { - ExpiringSession session = repository.createSession(); + @Test + public void createSessionDefaultExpiration() { + ExpiringSession session = repository.createSession(); - assertThat(session).isInstanceOf(MapSession.class); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(new MapSession().getMaxInactiveIntervalInSeconds()); - } + assertThat(session).isInstanceOf(MapSession.class); + assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(new MapSession().getMaxInactiveIntervalInSeconds()); + } - @Test - public void createSessionCustomDefaultExpiration() { - final int expectedMaxInterval = new MapSession().getMaxInactiveIntervalInSeconds() + 10; - repository.setDefaultMaxInactiveInterval(expectedMaxInterval); + @Test + public void createSessionCustomDefaultExpiration() { + final int expectedMaxInterval = new MapSession().getMaxInactiveIntervalInSeconds() + 10; + repository.setDefaultMaxInactiveInterval(expectedMaxInterval); - ExpiringSession session = repository.createSession(); + ExpiringSession session = repository.createSession(); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInterval); - } + assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInterval); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/MapSessionTests.java b/spring-session/src/test/java/org/springframework/session/MapSessionTests.java index 2f3c7b40..9ccbc325 100644 --- a/spring-session/src/test/java/org/springframework/session/MapSessionTests.java +++ b/spring-session/src/test/java/org/springframework/session/MapSessionTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session; import static org.fest.assertions.Assertions.assertThat; @@ -9,107 +24,107 @@ import org.junit.Test; public class MapSessionTests { - private MapSession session; + private MapSession session; - @Before - public void setup() { - session = new MapSession(); - session.setLastAccessedTime(1413258262962L); - } + @Before + public void setup() { + session = new MapSession(); + session.setLastAccessedTime(1413258262962L); + } - @Test(expected = IllegalArgumentException.class) - public void constructorNullSession() { - new MapSession(null); - } + @Test(expected = IllegalArgumentException.class) + public void constructorNullSession() { + new MapSession(null); + } - /** - * Ensure conforms to the javadoc of {@link Session} - */ - @Test - public void setAttributeNullObjectRemoves() { - String attr = "attr"; - session.setAttribute(attr, new Object()); - session.setAttribute(attr, null); - assertThat(session.getAttributeNames()).isEmpty(); - } + /** + * Ensure conforms to the javadoc of {@link Session} + */ + @Test + public void setAttributeNullObjectRemoves() { + String attr = "attr"; + session.setAttribute(attr, new Object()); + session.setAttribute(attr, null); + assertThat(session.getAttributeNames()).isEmpty(); + } - @Test - public void equalsNonSessionFalse() { - assertThat(session.equals(new Object())).isFalse(); - } + @Test + public void equalsNonSessionFalse() { + assertThat(session.equals(new Object())).isFalse(); + } - @Test - public void equalsCustomSession() { - CustomSession other = new CustomSession(); - session.setId(other.getId()); - assertThat(session.equals(other)).isTrue(); - } + @Test + public void equalsCustomSession() { + CustomSession other = new CustomSession(); + session.setId(other.getId()); + assertThat(session.equals(other)).isTrue(); + } - @Test - public void hashCodeEqualsIdHashCode() { - session.setId("constantId"); - assertThat(session.hashCode()).isEqualTo(session.getId().hashCode()); - } + @Test + public void hashCodeEqualsIdHashCode() { + session.setId("constantId"); + assertThat(session.hashCode()).isEqualTo(session.getId().hashCode()); + } - @Test - public void isExpiredExact() { - long now = 1413260062962L; - assertThat(session.isExpired(now)).isTrue(); - } + @Test + public void isExpiredExact() { + long now = 1413260062962L; + assertThat(session.isExpired(now)).isTrue(); + } - @Test - public void isExpiredOneMsTooSoon() { - long now = 1413260062961L; - assertThat(session.isExpired(now)).isFalse(); - } + @Test + public void isExpiredOneMsTooSoon() { + long now = 1413260062961L; + assertThat(session.isExpired(now)).isFalse(); + } - @Test - public void isExpiredOneMsAfter() { - long now = 1413260062963L; - assertThat(session.isExpired(now)).isTrue(); - } + @Test + public void isExpiredOneMsAfter() { + long now = 1413260062963L; + assertThat(session.isExpired(now)).isTrue(); + } - static class CustomSession implements ExpiringSession { + static class CustomSession implements ExpiringSession { - public long getCreationTime() { - return 0; - } + public long getCreationTime() { + return 0; + } - public String getId() { - return "id"; - } + public String getId() { + return "id"; + } - public long getLastAccessedTime() { - return 0; - } + public long getLastAccessedTime() { + return 0; + } - public void setMaxInactiveIntervalInSeconds(int interval) { + public void setMaxInactiveIntervalInSeconds(int interval) { - } + } - public int getMaxInactiveIntervalInSeconds() { - return 0; - } + public int getMaxInactiveIntervalInSeconds() { + return 0; + } - public Object getAttribute(String attributeName) { - return null; - } + public Object getAttribute(String attributeName) { + return null; + } - public Set getAttributeNames() { - return null; - } + public Set getAttributeNames() { + return null; + } - public void setAttribute(String attributeName, Object attributeValue) { + public void setAttribute(String attributeName, Object attributeValue) { - } + } - public void removeAttribute(String attributeName) { + public void removeAttribute(String attributeName) { - } + } - public boolean isExpired() { - return false; - } - } + public boolean isExpired() { + return false; + } + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java b/spring-session/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java index da0c75d2..80d38de8 100644 --- a/spring-session/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java +++ b/spring-session/src/test/java/org/springframework/session/data/redis/RedisOperationsSessionRepositoryTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.data.redis; import static org.fest.assertions.Assertions.assertThat; @@ -34,234 +49,231 @@ import org.springframework.session.data.redis.RedisOperationsSessionRepository.R @RunWith(MockitoJUnitRunner.class) +@SuppressWarnings({"unchecked","rawtypes"}) public class RedisOperationsSessionRepositoryTests { - @Mock - RedisConnectionFactory factory; - @Mock - RedisConnection connection; - @Mock - RedisOperations redisOperations; - @Mock - BoundHashOperations boundHashOperations; - @Mock - BoundSetOperations boundSetOperations; - @Captor - ArgumentCaptor> delta; + @Mock + RedisConnectionFactory factory; + @Mock + RedisConnection connection; + @Mock + RedisOperations redisOperations; + @Mock + BoundHashOperations boundHashOperations; + @Mock + BoundSetOperations boundSetOperations; + @Captor + ArgumentCaptor> delta; - private RedisOperationsSessionRepository redisRepository; + private RedisOperationsSessionRepository redisRepository; - @Before - public void setup() { - this.redisRepository = new RedisOperationsSessionRepository(redisOperations); - } + @Before + public void setup() { + this.redisRepository = new RedisOperationsSessionRepository(redisOperations); + } - @Test(expected=IllegalArgumentException.class) - public void constructorNullConnectionFactory() { - new RedisOperationsSessionRepository((RedisConnectionFactory)null); - } + @Test(expected=IllegalArgumentException.class) + public void constructorNullConnectionFactory() { + new RedisOperationsSessionRepository((RedisConnectionFactory)null); + } - // gh-61 - @Test - public void constructorConnectionFactory() { - redisRepository = new RedisOperationsSessionRepository(factory); - RedisSession session = redisRepository.createSession(); + // gh-61 + @Test + public void constructorConnectionFactory() { + redisRepository = new RedisOperationsSessionRepository(factory); + RedisSession session = redisRepository.createSession(); - when(factory.getConnection()).thenReturn(connection); + when(factory.getConnection()).thenReturn(connection); - redisRepository.save(session); - } + redisRepository.save(session); + } - @Test - public void createSessionDefaultMaxInactiveInterval() throws Exception { - ExpiringSession session = redisRepository.createSession(); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(new MapSession().getMaxInactiveIntervalInSeconds()); - } + @Test + public void createSessionDefaultMaxInactiveInterval() throws Exception { + ExpiringSession session = redisRepository.createSession(); + assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(new MapSession().getMaxInactiveIntervalInSeconds()); + } - @Test - public void createSessionCustomMaxInactiveInterval() throws Exception { - int interval = 1; - redisRepository.setDefaultMaxInactiveInterval(interval); - ExpiringSession session = redisRepository.createSession(); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(interval); - } + @Test + public void createSessionCustomMaxInactiveInterval() throws Exception { + int interval = 1; + redisRepository.setDefaultMaxInactiveInterval(interval); + ExpiringSession session = redisRepository.createSession(); + assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(interval); + } - @Test - public void saveNewSession() { - RedisSession session = redisRepository.createSession(); - when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); - when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); + @Test + public void saveNewSession() { + RedisSession session = redisRepository.createSession(); + when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); + when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); - redisRepository.save(session); + redisRepository.save(session); - Map delta = getDelta(); - assertThat(delta.size()).isEqualTo(3); - Object creationTime = delta.get(CREATION_TIME_ATTR); - assertThat(creationTime).isInstanceOf(Long.class); - assertThat(delta.get(MAX_INACTIVE_ATTR)).isEqualTo(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS); - assertThat(delta.get(LAST_ACCESSED_ATTR)).isEqualTo(creationTime); - } + Map delta = getDelta(); + assertThat(delta.size()).isEqualTo(3); + Object creationTime = delta.get(CREATION_TIME_ATTR); + assertThat(creationTime).isInstanceOf(Long.class); + assertThat(delta.get(MAX_INACTIVE_ATTR)).isEqualTo(MapSession.DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS); + assertThat(delta.get(LAST_ACCESSED_ATTR)).isEqualTo(creationTime); + } - @Test - public void saveLastAccessChanged() { - RedisSession session = redisRepository.new RedisSession(new MapSession()); - session.setLastAccessedTime(12345678L); - when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); - when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); + @Test + public void saveLastAccessChanged() { + RedisSession session = redisRepository.new RedisSession(new MapSession()); + session.setLastAccessedTime(12345678L); + when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); + when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); - redisRepository.save(session); + redisRepository.save(session); - assertThat(getDelta()).isEqualTo(map(LAST_ACCESSED_ATTR, session.getLastAccessedTime())); - } + assertThat(getDelta()).isEqualTo(map(LAST_ACCESSED_ATTR, session.getLastAccessedTime())); + } - @Test - public void saveSetAttribute() { - String attrName = "attrName"; - RedisSession session = redisRepository.new RedisSession(new MapSession()); - session.setAttribute(attrName, "attrValue"); - when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); - when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); + @Test + public void saveSetAttribute() { + String attrName = "attrName"; + RedisSession session = redisRepository.new RedisSession(new MapSession()); + session.setAttribute(attrName, "attrValue"); + when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); + when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); - redisRepository.save(session); + redisRepository.save(session); - assertThat(getDelta()).isEqualTo(map(getSessionAttrNameKey(attrName), session.getAttribute(attrName))); - } + assertThat(getDelta()).isEqualTo(map(getSessionAttrNameKey(attrName), session.getAttribute(attrName))); + } - @Test - public void saveRemoveAttribute() { - String attrName = "attrName"; - RedisSession session = redisRepository.new RedisSession(new MapSession()); - session.removeAttribute(attrName); - when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); - when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); + @Test + public void saveRemoveAttribute() { + String attrName = "attrName"; + RedisSession session = redisRepository.new RedisSession(new MapSession()); + session.removeAttribute(attrName); + when(redisOperations.boundHashOps(getKey(session.getId()))).thenReturn(boundHashOperations); + when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); - redisRepository.save(session); + redisRepository.save(session); - assertThat(getDelta()).isEqualTo(map(getSessionAttrNameKey(attrName), null)); - } + assertThat(getDelta()).isEqualTo(map(getSessionAttrNameKey(attrName), null)); + } - @Test - public void redisSessionGetAttributes() { - String attrName = "attrName"; - RedisSession session = redisRepository.new RedisSession(new MapSession()); - assertThat(session.getAttributeNames()).isEmpty(); - session.setAttribute(attrName, "attrValue"); - assertThat(session.getAttributeNames()).containsOnly(attrName); - session.removeAttribute(attrName); - assertThat(session.getAttributeNames()).isEmpty(); - } + @Test + public void redisSessionGetAttributes() { + String attrName = "attrName"; + RedisSession session = redisRepository.new RedisSession(new MapSession()); + assertThat(session.getAttributeNames()).isEmpty(); + session.setAttribute(attrName, "attrValue"); + assertThat(session.getAttributeNames()).containsOnly(attrName); + session.removeAttribute(attrName); + assertThat(session.getAttributeNames()).isEmpty(); + } - @Test - public void delete() { - String attrName = "attrName"; - MapSession expected = new MapSession(); - expected.setLastAccessedTime(System.currentTimeMillis() - 60000); - expected.setAttribute(attrName, "attrValue"); - when(redisOperations.boundHashOps(getKey(expected.getId()))).thenReturn(boundHashOperations); - Map map = map( - getSessionAttrNameKey(attrName), expected.getAttribute(attrName), - CREATION_TIME_ATTR, expected.getCreationTime(), - MAX_INACTIVE_ATTR, expected.getMaxInactiveIntervalInSeconds(), - LAST_ACCESSED_ATTR, expected.getLastAccessedTime()); - when(boundHashOperations.entries()).thenReturn(map); - when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); + @Test + public void delete() { + String attrName = "attrName"; + MapSession expected = new MapSession(); + expected.setLastAccessedTime(System.currentTimeMillis() - 60000); + expected.setAttribute(attrName, "attrValue"); + when(redisOperations.boundHashOps(getKey(expected.getId()))).thenReturn(boundHashOperations); + Map map = map( + getSessionAttrNameKey(attrName), expected.getAttribute(attrName), + CREATION_TIME_ATTR, expected.getCreationTime(), + MAX_INACTIVE_ATTR, expected.getMaxInactiveIntervalInSeconds(), + LAST_ACCESSED_ATTR, expected.getLastAccessedTime()); + when(boundHashOperations.entries()).thenReturn(map); + when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); - String id = expected.getId(); - redisRepository.delete(id); - verify(redisOperations).delete(getKey(id)); - } + String id = expected.getId(); + redisRepository.delete(id); + verify(redisOperations).delete(getKey(id)); + } - @Test - public void deleteNullSession() { - when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); - when(redisOperations.boundHashOps(anyString())).thenReturn(boundHashOperations); + @Test + public void deleteNullSession() { + when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); + when(redisOperations.boundHashOps(anyString())).thenReturn(boundHashOperations); - String id = "abc"; - redisRepository.delete(id); - verify(redisOperations,times(0)).delete(anyString()); - verify(redisOperations,times(0)).delete(anyString()); - } + String id = "abc"; + redisRepository.delete(id); + verify(redisOperations,times(0)).delete(anyString()); + verify(redisOperations,times(0)).delete(anyString()); + } - @Test - @SuppressWarnings("unchecked") - public void getSessionNotFound() { - String id = "abc"; - when(redisOperations.boundHashOps(getKey(id))).thenReturn(boundHashOperations); - when(boundHashOperations.entries()).thenReturn(map()); + @Test + public void getSessionNotFound() { + String id = "abc"; + when(redisOperations.boundHashOps(getKey(id))).thenReturn(boundHashOperations); + when(boundHashOperations.entries()).thenReturn(map()); - assertThat(redisRepository.getSession(id)).isNull(); - } + assertThat(redisRepository.getSession(id)).isNull(); + } - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void getSessionFound() { - String attrName = "attrName"; - MapSession expected = new MapSession(); - expected.setLastAccessedTime(System.currentTimeMillis() - 60000); - expected.setAttribute(attrName, "attrValue"); - when(redisOperations.boundHashOps(getKey(expected.getId()))).thenReturn(boundHashOperations); - Map map = map( - getSessionAttrNameKey(attrName), expected.getAttribute(attrName), - CREATION_TIME_ATTR, expected.getCreationTime(), - MAX_INACTIVE_ATTR, expected.getMaxInactiveIntervalInSeconds(), - LAST_ACCESSED_ATTR, expected.getLastAccessedTime()); - when(boundHashOperations.entries()).thenReturn(map); + @Test + public void getSessionFound() { + String attrName = "attrName"; + MapSession expected = new MapSession(); + expected.setLastAccessedTime(System.currentTimeMillis() - 60000); + expected.setAttribute(attrName, "attrValue"); + when(redisOperations.boundHashOps(getKey(expected.getId()))).thenReturn(boundHashOperations); + Map map = map( + getSessionAttrNameKey(attrName), expected.getAttribute(attrName), + CREATION_TIME_ATTR, expected.getCreationTime(), + MAX_INACTIVE_ATTR, expected.getMaxInactiveIntervalInSeconds(), + LAST_ACCESSED_ATTR, expected.getLastAccessedTime()); + when(boundHashOperations.entries()).thenReturn(map); - long now = System.currentTimeMillis(); - RedisSession session = redisRepository.getSession(expected.getId()); - assertThat(session.getId()).isEqualTo(expected.getId()); - assertThat(session.getAttributeNames()).isEqualTo(expected.getAttributeNames()); - assertThat(session.getAttribute(attrName)).isEqualTo(expected.getAttribute(attrName)); - assertThat(session.getCreationTime()).isEqualTo(expected.getCreationTime()); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expected.getMaxInactiveIntervalInSeconds()); - assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(now); + long now = System.currentTimeMillis(); + RedisSession session = redisRepository.getSession(expected.getId()); + assertThat(session.getId()).isEqualTo(expected.getId()); + assertThat(session.getAttributeNames()).isEqualTo(expected.getAttributeNames()); + assertThat(session.getAttribute(attrName)).isEqualTo(expected.getAttribute(attrName)); + assertThat(session.getCreationTime()).isEqualTo(expected.getCreationTime()); + assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expected.getMaxInactiveIntervalInSeconds()); + assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(now); - } + } - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void getSessionExpired() { - String expiredId = "expired-id"; - when(redisOperations.boundHashOps(getKey(expiredId))).thenReturn(boundHashOperations); - Map map = map( - MAX_INACTIVE_ATTR, 1, - LAST_ACCESSED_ATTR, System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5)); - when(boundHashOperations.entries()).thenReturn(map); + @Test + public void getSessionExpired() { + String expiredId = "expired-id"; + when(redisOperations.boundHashOps(getKey(expiredId))).thenReturn(boundHashOperations); + Map map = map( + MAX_INACTIVE_ATTR, 1, + LAST_ACCESSED_ATTR, System.currentTimeMillis() - TimeUnit.MINUTES.toMillis(5)); + when(boundHashOperations.entries()).thenReturn(map); - assertThat(redisRepository.getSession(expiredId)).isNull(); - } + assertThat(redisRepository.getSession(expiredId)).isNull(); + } - @Test - public void cleanupExpiredSessions() { - String expiredId = "expired-id"; - when(redisOperations.boundHashOps(getKey(expiredId))).thenReturn(boundHashOperations); - when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); + @Test + public void cleanupExpiredSessions() { + String expiredId = "expired-id"; + when(redisOperations.boundHashOps(getKey(expiredId))).thenReturn(boundHashOperations); + when(redisOperations.boundSetOps(anyString())).thenReturn(boundSetOperations); - Set expiredIds = new HashSet(Arrays.asList("expired-key1","expired-key2")); - when(boundSetOperations.members()).thenReturn(expiredIds); + Set expiredIds = new HashSet(Arrays.asList("expired-key1","expired-key2")); + when(boundSetOperations.members()).thenReturn(expiredIds); - redisRepository.cleanupExpiredSessions(); + redisRepository.cleanupExpiredSessions(); - for(String id : expiredIds) { - String expiredKey = RedisOperationsSessionRepository.BOUNDED_HASH_KEY_PREFIX + id; - // https://github.com/spring-projects/spring-session/issues/93 - verify(redisOperations).hasKey(expiredKey); - } - } + for(String id : expiredIds) { + String expiredKey = RedisOperationsSessionRepository.BOUNDED_HASH_KEY_PREFIX + id; + // https://github.com/spring-projects/spring-session/issues/93 + verify(redisOperations).hasKey(expiredKey); + } + } - @SuppressWarnings("rawtypes") - private Map map(Object...objects) { - Map result = new HashMap(); - if(objects == null) { - return result; - } - for(int i = 0; i < objects.length; i += 2) { - result.put((String)objects[i], objects[i+1]); - } - return result; - } + private Map map(Object...objects) { + Map result = new HashMap(); + if(objects == null) { + return result; + } + for(int i = 0; i < objects.length; i += 2) { + result.put((String)objects[i], objects[i+1]); + } + return result; + } - private Map getDelta() { - verify(boundHashOperations).putAll(delta.capture()); - return delta.getValue(); - } + private Map getDelta() { + verify(boundHashOperations).putAll(delta.capture()); + return delta.getValue(); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/data/redis/SessionMessageListenerTests.java b/spring-session/src/test/java/org/springframework/session/data/redis/SessionMessageListenerTests.java index a1b564d5..d2b7a4ac 100644 --- a/spring-session/src/test/java/org/springframework/session/data/redis/SessionMessageListenerTests.java +++ b/spring-session/src/test/java/org/springframework/session/data/redis/SessionMessageListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -40,109 +40,109 @@ import org.springframework.session.events.SessionDestroyedEvent; */ @RunWith(MockitoJUnitRunner.class) public class SessionMessageListenerTests { - @Mock - ApplicationEventPublisher eventPublisher; + @Mock + ApplicationEventPublisher eventPublisher; - @Mock - Message message; + @Mock + Message message; - @Captor - ArgumentCaptor event; + @Captor + ArgumentCaptor event; - byte[] pattern; + byte[] pattern; - SessionMessageListener listener; + SessionMessageListener listener; - @Before - public void setup() { - listener = new SessionMessageListener(eventPublisher); - } + @Before + public void setup() { + listener = new SessionMessageListener(eventPublisher); + } - @Test(expected = IllegalArgumentException.class) - public void constructorNullEventPublisher() { - new SessionMessageListener(null); - } + @Test(expected = IllegalArgumentException.class) + public void constructorNullEventPublisher() { + new SessionMessageListener(null); + } - @Test - public void onMessageNullBody() throws Exception { - listener.onMessage(message, pattern); + @Test + public void onMessageNullBody() throws Exception { + listener.onMessage(message, pattern); - verifyZeroInteractions(eventPublisher); - } + verifyZeroInteractions(eventPublisher); + } - @Test - public void onMessageDel() throws Exception { - mockMessage("__keyevent@0__:del", "spring:session:sessions:123"); + @Test + public void onMessageDel() throws Exception { + mockMessage("__keyevent@0__:del", "spring:session:sessions:123"); - listener.onMessage(message, pattern); + listener.onMessage(message, pattern); - verify(eventPublisher).publishEvent(event.capture()); - assertThat(event.getValue().getSessionId()).isEqualTo("123"); - } + verify(eventPublisher).publishEvent(event.capture()); + assertThat(event.getValue().getSessionId()).isEqualTo("123"); + } - @Test - public void onMessageSource() throws Exception { - mockMessage("__keyevent@0__:del","spring:session:sessions:123"); + @Test + public void onMessageSource() throws Exception { + mockMessage("__keyevent@0__:del","spring:session:sessions:123"); - listener.onMessage(message, pattern); + listener.onMessage(message, pattern); - verify(eventPublisher).publishEvent(event.capture()); - assertThat(event.getValue().getSource()).isEqualTo(listener); - } + verify(eventPublisher).publishEvent(event.capture()); + assertThat(event.getValue().getSource()).isEqualTo(listener); + } - @Test - public void onMessageExpired() throws Exception { - mockMessage("__keyevent@0__:expired","spring:session:sessions:543"); + @Test + public void onMessageExpired() throws Exception { + mockMessage("__keyevent@0__:expired","spring:session:sessions:543"); - listener.onMessage(message, pattern); + listener.onMessage(message, pattern); - verify(eventPublisher).publishEvent(event.capture()); - assertThat(event.getValue().getSessionId()).isEqualTo("543"); - } + verify(eventPublisher).publishEvent(event.capture()); + assertThat(event.getValue().getSessionId()).isEqualTo("543"); + } - @Test - public void onMessageHset() throws Exception { - mockMessage("__keyevent@0__:hset","spring:session:sessions:123"); + @Test + public void onMessageHset() throws Exception { + mockMessage("__keyevent@0__:hset","spring:session:sessions:123"); - listener.onMessage(message, pattern); + listener.onMessage(message, pattern); - verifyZeroInteractions(eventPublisher); - } + verifyZeroInteractions(eventPublisher); + } - @Test - public void onMessageWrongKeyPrefix() throws Exception { - mockMessage("__keyevent@0__:del","spring:session:sessionsNo:123"); + @Test + public void onMessageWrongKeyPrefix() throws Exception { + mockMessage("__keyevent@0__:del","spring:session:sessionsNo:123"); - listener.onMessage(message, pattern); + listener.onMessage(message, pattern); - verifyZeroInteractions(eventPublisher); - } + verifyZeroInteractions(eventPublisher); + } - @Test - public void onMessageRename() throws Exception { - mockMessage("__keyevent@0__:rename","spring:session:sessions:123"); + @Test + public void onMessageRename() throws Exception { + mockMessage("__keyevent@0__:rename","spring:session:sessions:123"); - listener.onMessage(message, pattern); + listener.onMessage(message, pattern); - verifyZeroInteractions(eventPublisher); - } + verifyZeroInteractions(eventPublisher); + } - @Test - public void onMessageEventPublisherErrorCaught() throws Exception { - mockMessage("__keyevent@0__:del","spring:session:sessions:123"); - doThrow(new IllegalStateException("Test Exceptions are caught")).when(eventPublisher).publishEvent(any(ApplicationEvent.class)); + @Test + public void onMessageEventPublisherErrorCaught() throws Exception { + mockMessage("__keyevent@0__:del","spring:session:sessions:123"); + doThrow(new IllegalStateException("Test Exceptions are caught")).when(eventPublisher).publishEvent(any(ApplicationEvent.class)); - listener.onMessage(message, pattern); + listener.onMessage(message, pattern); - verify(eventPublisher).publishEvent(any(ApplicationEvent.class)); - } + verify(eventPublisher).publishEvent(any(ApplicationEvent.class)); + } - private void mockMessage(String channel, String body) throws UnsupportedEncodingException { - when(message.getBody()).thenReturn(bytes(body)); - when(message.getChannel()).thenReturn(bytes(channel)); - } + private void mockMessage(String channel, String body) throws UnsupportedEncodingException { + when(message.getBody()).thenReturn(bytes(body)); + when(message.getChannel()).thenReturn(bytes(channel)); + } - private static byte[] bytes(String s) throws UnsupportedEncodingException { - return s.getBytes("UTF-8"); - } + private static byte[] bytes(String s) throws UnsupportedEncodingException { + return s.getBytes("UTF-8"); + } } diff --git a/spring-session/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisKeyspaceNotificationsInitializerTests.java b/spring-session/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisKeyspaceNotificationsInitializerTests.java index 7456cab0..dcf691ae 100644 --- a/spring-session/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisKeyspaceNotificationsInitializerTests.java +++ b/spring-session/src/test/java/org/springframework/session/data/redis/config/annotation/web/http/EnableRedisKeyspaceNotificationsInitializerTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.data.redis.config.annotation.web.http; import static org.fest.assertions.Assertions.assertThat; @@ -20,132 +35,132 @@ import java.util.Arrays; @RunWith(MockitoJUnitRunner.class) public class EnableRedisKeyspaceNotificationsInitializerTests { - static final String CONFIG_NOTIFY_KEYSPACE_EVENTS = "notify-keyspace-events"; + static final String CONFIG_NOTIFY_KEYSPACE_EVENTS = "notify-keyspace-events"; - @Mock - RedisConnectionFactory connectionFactory; - @Mock - RedisConnection connection; - @Captor - ArgumentCaptor options; + @Mock + RedisConnectionFactory connectionFactory; + @Mock + RedisConnection connection; + @Captor + ArgumentCaptor options; - EnableRedisKeyspaceNotificationsInitializer initializer; + EnableRedisKeyspaceNotificationsInitializer initializer; - @Before - public void setup() { - when(connectionFactory.getConnection()).thenReturn(connection); + @Before + public void setup() { + when(connectionFactory.getConnection()).thenReturn(connection); - initializer = new EnableRedisKeyspaceNotificationsInitializer(connectionFactory); - } + initializer = new EnableRedisKeyspaceNotificationsInitializer(connectionFactory); + } - @Test - public void afterPropertiesSetUnset() throws Exception { - setConfigNotification(""); + @Test + public void afterPropertiesSetUnset() throws Exception { + setConfigNotification(""); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("E","g","x"); - } + assertOptionsContains("E","g","x"); + } - @Test - public void afterPropertiesSetA() throws Exception { - setConfigNotification("A"); + @Test + public void afterPropertiesSetA() throws Exception { + setConfigNotification("A"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("A", "E"); - } + assertOptionsContains("A", "E"); + } - @Test - public void afterPropertiesSetE() throws Exception { - setConfigNotification("E"); + @Test + public void afterPropertiesSetE() throws Exception { + setConfigNotification("E"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("E", "g", "x"); - } + assertOptionsContains("E", "g", "x"); + } - @Test - public void afterPropertiesSetK() throws Exception { - setConfigNotification("K"); + @Test + public void afterPropertiesSetK() throws Exception { + setConfigNotification("K"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("K", "E", "g", "x"); - } + assertOptionsContains("K", "E", "g", "x"); + } - @Test - public void afterPropertiesSetAE() throws Exception { - setConfigNotification("AE"); + @Test + public void afterPropertiesSetAE() throws Exception { + setConfigNotification("AE"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - verify(connection, never()).setConfig(anyString(), anyString()); - } + verify(connection, never()).setConfig(anyString(), anyString()); + } - @Test - public void afterPropertiesSetAK() throws Exception { - setConfigNotification("AK"); + @Test + public void afterPropertiesSetAK() throws Exception { + setConfigNotification("AK"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("A", "K", "E"); - } + assertOptionsContains("A", "K", "E"); + } - @Test - public void afterPropertiesSetEK() throws Exception { - setConfigNotification("EK"); + @Test + public void afterPropertiesSetEK() throws Exception { + setConfigNotification("EK"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("E", "K", "g", "x"); - } + assertOptionsContains("E", "K", "g", "x"); + } - @Test - public void afterPropertiesSetEg() throws Exception { - setConfigNotification("Eg"); + @Test + public void afterPropertiesSetEg() throws Exception { + setConfigNotification("Eg"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("E", "g", "x"); - } + assertOptionsContains("E", "g", "x"); + } - @Test - public void afterPropertiesSetE$() throws Exception { - setConfigNotification("E$"); + @Test + public void afterPropertiesSetE$() throws Exception { + setConfigNotification("E$"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("E", "$", "g", "x"); - } + assertOptionsContains("E", "$", "g", "x"); + } - @Test - public void afterPropertiesSetKg() throws Exception { - setConfigNotification("Kg"); + @Test + public void afterPropertiesSetKg() throws Exception { + setConfigNotification("Kg"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - assertOptionsContains("K", "g", "E", "x"); - } + assertOptionsContains("K", "g", "E", "x"); + } - @Test - public void afterPropertiesSetAEK() throws Exception { - setConfigNotification("AEK"); + @Test + public void afterPropertiesSetAEK() throws Exception { + setConfigNotification("AEK"); - initializer.afterPropertiesSet(); + initializer.afterPropertiesSet(); - verify(connection, never()).setConfig(anyString(), anyString()); - } + verify(connection, never()).setConfig(anyString(), anyString()); + } - private void assertOptionsContains(String... expectedValues) { - verify(connection).setConfig(eq(CONFIG_NOTIFY_KEYSPACE_EVENTS), options.capture()); - for(String expectedValue : expectedValues) { - assertThat(options.getValue()).contains(expectedValue); - } - assertThat(options.getValue().length()).isEqualTo(expectedValues.length); - } + private void assertOptionsContains(String... expectedValues) { + verify(connection).setConfig(eq(CONFIG_NOTIFY_KEYSPACE_EVENTS), options.capture()); + for(String expectedValue : expectedValues) { + assertThat(options.getValue()).contains(expectedValue); + } + assertThat(options.getValue().length()).isEqualTo(expectedValues.length); + } - private void setConfigNotification(String value) { - when(connection.getConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS)).thenReturn(Arrays.asList(CONFIG_NOTIFY_KEYSPACE_EVENTS, value)); - } + private void setConfigNotification(String value) { + when(connection.getConfig(CONFIG_NOTIFY_KEYSPACE_EVENTS)).thenReturn(Arrays.asList(CONFIG_NOTIFY_KEYSPACE_EVENTS, value)); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/web/http/CookieHttpSessionStrategyTests.java b/spring-session/src/test/java/org/springframework/session/web/http/CookieHttpSessionStrategyTests.java index b5b6878c..1cb33f3b 100644 --- a/spring-session/src/test/java/org/springframework/session/web/http/CookieHttpSessionStrategyTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/http/CookieHttpSessionStrategyTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.web.http; import static org.fest.assertions.Assertions.*; @@ -13,405 +28,405 @@ import javax.servlet.http.Cookie; import java.util.Map; public class CookieHttpSessionStrategyTests { - private MockHttpServletRequest request; - private MockHttpServletResponse response; - - private CookieHttpSessionStrategy strategy; - private String cookieName; - private Session session; - - @Before - public void setup() throws Exception { - cookieName = "SESSION"; - session = new MapSession(); - request = new MockHttpServletRequest(); - response = new MockHttpServletResponse(); - strategy = new CookieHttpSessionStrategy(); - } - - @Test - public void getRequestedSessionIdNull() throws Exception { - assertThat(strategy.getRequestedSessionId(request)).isNull(); - } - - @Test - public void getRequestedSessionIdNotNull() throws Exception { - setSessionCookie(session.getId()); - assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); - } - - @Test - public void getRequestedSessionIdNotNullCustomCookieName() throws Exception { - setCookieName("CUSTOM"); - setSessionCookie(session.getId()); - assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); - } - - @Test - public void onNewSession() throws Exception { - strategy.onNewSession(session, request, response); - assertThat(getSessionId()).isEqualTo(session.getId()); - } - - @Test - public void onNewSessionExistingSessionSameAlias() throws Exception { - Session existing = new MapSession(); - setSessionCookie(existing.getId()); - strategy.onNewSession(session, request, response); - assertThat(getSessionId()).isEqualTo(session.getId()); - } - - @Test - public void onNewSessionExistingSessionNewAlias() throws Exception { - Session existing = new MapSession(); - setSessionCookie(existing.getId()); - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "new"); - strategy.onNewSession(session, request, response); - assertThat(getSessionId()).isEqualTo("0 " + existing.getId() + " new " + session.getId()); - } - - @Test - public void onNewSessionCookiePath() throws Exception { - request.setContextPath("/somethingunique"); - strategy.onNewSession(session, request, response); - - Cookie sessionCookie = response.getCookie(cookieName); - assertThat(sessionCookie.getPath()).isEqualTo(request.getContextPath() + "/"); - } - - @Test - public void onNewSessionCustomCookieName() throws Exception { - setCookieName("CUSTOM"); - strategy.onNewSession(session, request, response); - assertThat(getSessionId()).isEqualTo(session.getId()); - } - - @Test - public void onDeleteSession() throws Exception { - strategy.onInvalidateSession(request, response); - assertThat(getSessionId()).isEmpty(); - } - - @Test - public void onDeleteSessionCookiePath() throws Exception { - request.setContextPath("/somethingunique"); - strategy.onInvalidateSession(request, response); - - Cookie sessionCookie = response.getCookie(cookieName); - assertThat(sessionCookie.getPath()).isEqualTo(request.getContextPath() + "/"); - } - - @Test - public void onDeleteSessionCustomCookieName() throws Exception { - setCookieName("CUSTOM"); - strategy.onInvalidateSession(request, response); - assertThat(getSessionId()).isEmpty(); - } - - @Test - public void onDeleteSessionExistingSessionSameAlias() throws Exception { - Session existing = new MapSession(); - setSessionCookie("0 " + existing.getId() + " new " + session.getId()); - strategy.onInvalidateSession(request, response); - assertThat(getSessionId()).isEqualTo(session.getId()); - } - - @Test - public void onDeleteSessionExistingSessionNewAlias() throws Exception { - Session existing = new MapSession(); - setSessionCookie("0 " + existing.getId() + " new " + session.getId()); - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "new"); - strategy.onInvalidateSession(request, response); - assertThat(getSessionId()).isEqualTo(existing.getId()); - } - - @Test(expected = IllegalArgumentException.class) - public void setCookieNameNull() throws Exception { - strategy.setCookieName(null); - } - - @Test - public void encodeURLNoExistingQuery() { - assertThat(strategy.encodeURL("/url", "2")).isEqualTo("/url?_s=2"); - } - - @Test - public void encodeURLNoExistingQueryEmpty() { - assertThat(strategy.encodeURL("/url?", "2")).isEqualTo("/url?_s=2"); - } - - @Test - public void encodeURLExistingQueryNoAlias() { - assertThat(strategy.encodeURL("/url?a=b", "2")).isEqualTo("/url?a=b&_s=2"); - } - - @Test - public void encodeURLExistingQueryExistingAliasStart() { - assertThat(strategy.encodeURL("/url?_s=1&y=z", "2")).isEqualTo("/url?_s=2&y=z"); - } - - @Test - public void encodeURLExistingQueryExistingAliasMiddle() { - assertThat(strategy.encodeURL("/url?a=b&_s=1&y=z", "2")).isEqualTo("/url?a=b&_s=2&y=z"); - } - - @Test - public void encodeURLExistingQueryExistingAliasEnd() { - assertThat(strategy.encodeURL("/url?a=b&_s=1", "2")).isEqualTo("/url?a=b&_s=2"); - } - - // - - @Test - public void encodeURLExistingQueryParamEndsWithActualParamStart() { - assertThat(strategy.encodeURL("/url?x_s=1&y=z", "2")).isEqualTo("/url?x_s=1&y=z&_s=2"); - } - - @Test - public void encodeURLExistingQueryParamEndsWithActualParamMiddle() { - assertThat(strategy.encodeURL("/url?a=b&x_s=1&y=z", "2")).isEqualTo("/url?a=b&x_s=1&y=z&_s=2"); - } - - @Test - public void encodeURLExistingQueryParamEndsWithActualParamEnd() { - assertThat(strategy.encodeURL("/url?a=b&x_s=1", "2")).isEqualTo("/url?a=b&x_s=1&_s=2"); - } - - // - - @Test - public void encodeURLNoExistingQueryDefaultAlias() { - assertThat(strategy.encodeURL("/url", "0")).isEqualTo("/url"); - } - - @Test - public void encodeURLNoExistingQueryEmptyDefaultAlias() { - assertThat(strategy.encodeURL("/url?", "0")).isEqualTo("/url?"); - } - - @Test - public void encodeURLExistingQueryNoAliasDefaultAlias() { - assertThat(strategy.encodeURL("/url?a=b", "0")).isEqualTo("/url?a=b"); - } - - @Test - public void encodeURLExistingQueryExistingAliasStartDefaultAlias() { - // relaxed constraint as result /url?&y=z does not hurt anything (ideally should remove the &) - assertThat(strategy.encodeURL("/url?_s=1&y=z", "0")).doesNotContain("_s=0&_s=1"); - } - - @Test - public void encodeURLExistingQueryExistingAliasMiddleDefaultAlias() { - assertThat(strategy.encodeURL("/url?a=b&_s=1&y=z", "0")).isEqualTo("/url?a=b&y=z"); - } - - @Test - public void encodeURLExistingQueryExistingAliasEndDefaultAlias() { - assertThat(strategy.encodeURL("/url?a=b&_s=1", "0")).isEqualTo("/url?a=b"); - } - - @Test - public void encodeURLMaliciousAlias() { - assertThat(strategy.encodeURL("/url?a=b&_s=1", "\"> ")).isEqualTo("/url?a=b&_s=%22%3E+%3Cscript%3Ealert%28%27hi%27%29%3C%2Fscript%3E"); - } - - // --- getCurrentSessionAlias - - @Test - public void getCurrentSessionAliasNull() { - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } - - @Test - public void getCurrentSessionAliasNullParamName() { - strategy.setSessionAliasParamName(null); - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "NOT USED"); - - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } - - // protect against malicious users - @Test - public void getCurrentSessionAliasContainsQuote() { - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "here\"this"); + private MockHttpServletRequest request; + private MockHttpServletResponse response; + + private CookieHttpSessionStrategy strategy; + private String cookieName; + private Session session; + + @Before + public void setup() throws Exception { + cookieName = "SESSION"; + session = new MapSession(); + request = new MockHttpServletRequest(); + response = new MockHttpServletResponse(); + strategy = new CookieHttpSessionStrategy(); + } + + @Test + public void getRequestedSessionIdNull() throws Exception { + assertThat(strategy.getRequestedSessionId(request)).isNull(); + } + + @Test + public void getRequestedSessionIdNotNull() throws Exception { + setSessionCookie(session.getId()); + assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); + } + + @Test + public void getRequestedSessionIdNotNullCustomCookieName() throws Exception { + setCookieName("CUSTOM"); + setSessionCookie(session.getId()); + assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); + } + + @Test + public void onNewSession() throws Exception { + strategy.onNewSession(session, request, response); + assertThat(getSessionId()).isEqualTo(session.getId()); + } + + @Test + public void onNewSessionExistingSessionSameAlias() throws Exception { + Session existing = new MapSession(); + setSessionCookie(existing.getId()); + strategy.onNewSession(session, request, response); + assertThat(getSessionId()).isEqualTo(session.getId()); + } + + @Test + public void onNewSessionExistingSessionNewAlias() throws Exception { + Session existing = new MapSession(); + setSessionCookie(existing.getId()); + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "new"); + strategy.onNewSession(session, request, response); + assertThat(getSessionId()).isEqualTo("0 " + existing.getId() + " new " + session.getId()); + } + + @Test + public void onNewSessionCookiePath() throws Exception { + request.setContextPath("/somethingunique"); + strategy.onNewSession(session, request, response); + + Cookie sessionCookie = response.getCookie(cookieName); + assertThat(sessionCookie.getPath()).isEqualTo(request.getContextPath() + "/"); + } + + @Test + public void onNewSessionCustomCookieName() throws Exception { + setCookieName("CUSTOM"); + strategy.onNewSession(session, request, response); + assertThat(getSessionId()).isEqualTo(session.getId()); + } + + @Test + public void onDeleteSession() throws Exception { + strategy.onInvalidateSession(request, response); + assertThat(getSessionId()).isEmpty(); + } + + @Test + public void onDeleteSessionCookiePath() throws Exception { + request.setContextPath("/somethingunique"); + strategy.onInvalidateSession(request, response); + + Cookie sessionCookie = response.getCookie(cookieName); + assertThat(sessionCookie.getPath()).isEqualTo(request.getContextPath() + "/"); + } + + @Test + public void onDeleteSessionCustomCookieName() throws Exception { + setCookieName("CUSTOM"); + strategy.onInvalidateSession(request, response); + assertThat(getSessionId()).isEmpty(); + } + + @Test + public void onDeleteSessionExistingSessionSameAlias() throws Exception { + Session existing = new MapSession(); + setSessionCookie("0 " + existing.getId() + " new " + session.getId()); + strategy.onInvalidateSession(request, response); + assertThat(getSessionId()).isEqualTo(session.getId()); + } + + @Test + public void onDeleteSessionExistingSessionNewAlias() throws Exception { + Session existing = new MapSession(); + setSessionCookie("0 " + existing.getId() + " new " + session.getId()); + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "new"); + strategy.onInvalidateSession(request, response); + assertThat(getSessionId()).isEqualTo(existing.getId()); + } + + @Test(expected = IllegalArgumentException.class) + public void setCookieNameNull() throws Exception { + strategy.setCookieName(null); + } + + @Test + public void encodeURLNoExistingQuery() { + assertThat(strategy.encodeURL("/url", "2")).isEqualTo("/url?_s=2"); + } + + @Test + public void encodeURLNoExistingQueryEmpty() { + assertThat(strategy.encodeURL("/url?", "2")).isEqualTo("/url?_s=2"); + } + + @Test + public void encodeURLExistingQueryNoAlias() { + assertThat(strategy.encodeURL("/url?a=b", "2")).isEqualTo("/url?a=b&_s=2"); + } + + @Test + public void encodeURLExistingQueryExistingAliasStart() { + assertThat(strategy.encodeURL("/url?_s=1&y=z", "2")).isEqualTo("/url?_s=2&y=z"); + } + + @Test + public void encodeURLExistingQueryExistingAliasMiddle() { + assertThat(strategy.encodeURL("/url?a=b&_s=1&y=z", "2")).isEqualTo("/url?a=b&_s=2&y=z"); + } + + @Test + public void encodeURLExistingQueryExistingAliasEnd() { + assertThat(strategy.encodeURL("/url?a=b&_s=1", "2")).isEqualTo("/url?a=b&_s=2"); + } + + // + + @Test + public void encodeURLExistingQueryParamEndsWithActualParamStart() { + assertThat(strategy.encodeURL("/url?x_s=1&y=z", "2")).isEqualTo("/url?x_s=1&y=z&_s=2"); + } + + @Test + public void encodeURLExistingQueryParamEndsWithActualParamMiddle() { + assertThat(strategy.encodeURL("/url?a=b&x_s=1&y=z", "2")).isEqualTo("/url?a=b&x_s=1&y=z&_s=2"); + } + + @Test + public void encodeURLExistingQueryParamEndsWithActualParamEnd() { + assertThat(strategy.encodeURL("/url?a=b&x_s=1", "2")).isEqualTo("/url?a=b&x_s=1&_s=2"); + } + + // + + @Test + public void encodeURLNoExistingQueryDefaultAlias() { + assertThat(strategy.encodeURL("/url", "0")).isEqualTo("/url"); + } + + @Test + public void encodeURLNoExistingQueryEmptyDefaultAlias() { + assertThat(strategy.encodeURL("/url?", "0")).isEqualTo("/url?"); + } + + @Test + public void encodeURLExistingQueryNoAliasDefaultAlias() { + assertThat(strategy.encodeURL("/url?a=b", "0")).isEqualTo("/url?a=b"); + } + + @Test + public void encodeURLExistingQueryExistingAliasStartDefaultAlias() { + // relaxed constraint as result /url?&y=z does not hurt anything (ideally should remove the &) + assertThat(strategy.encodeURL("/url?_s=1&y=z", "0")).doesNotContain("_s=0&_s=1"); + } + + @Test + public void encodeURLExistingQueryExistingAliasMiddleDefaultAlias() { + assertThat(strategy.encodeURL("/url?a=b&_s=1&y=z", "0")).isEqualTo("/url?a=b&y=z"); + } + + @Test + public void encodeURLExistingQueryExistingAliasEndDefaultAlias() { + assertThat(strategy.encodeURL("/url?a=b&_s=1", "0")).isEqualTo("/url?a=b"); + } + + @Test + public void encodeURLMaliciousAlias() { + assertThat(strategy.encodeURL("/url?a=b&_s=1", "\"> ")).isEqualTo("/url?a=b&_s=%22%3E+%3Cscript%3Ealert%28%27hi%27%29%3C%2Fscript%3E"); + } + + // --- getCurrentSessionAlias + + @Test + public void getCurrentSessionAliasNull() { + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } + + @Test + public void getCurrentSessionAliasNullParamName() { + strategy.setSessionAliasParamName(null); + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "NOT USED"); + + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } + + // protect against malicious users + @Test + public void getCurrentSessionAliasContainsQuote() { + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "here\"this"); - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } - @Test - public void getCurrentSessionAliasContainsSingleQuote() { - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "here'this"); + @Test + public void getCurrentSessionAliasContainsSingleQuote() { + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "here'this"); - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } - @Test - public void getCurrentSessionAliasContainsSpace() { - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "here this"); + @Test + public void getCurrentSessionAliasContainsSpace() { + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "here this"); - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } - @Test - public void getCurrentSessionAliasContainsLt() { - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "herethis"); - - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } + @Test + public void getCurrentSessionAliasContainsGt() { + strategy.setSessionAliasParamName(null); + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "here>this"); + + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } - @Test - public void getCurrentSessionAliasTooLong() { - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "012345678901234567890123456789012345678901234567890"); + @Test + public void getCurrentSessionAliasTooLong() { + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "012345678901234567890123456789012345678901234567890"); - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } - - // We want some sort of length restrictions, but want to ensure some sort of length Technically no hard limit, but chose 50 - @Test - public void getCurrentSessionAliasAllows50() { - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "01234567890123456789012345678901234567890123456789"); + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } + + // We want some sort of length restrictions, but want to ensure some sort of length Technically no hard limit, but chose 50 + @Test + public void getCurrentSessionAliasAllows50() { + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, "01234567890123456789012345678901234567890123456789"); - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo("01234567890123456789012345678901234567890123456789"); - } + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo("01234567890123456789012345678901234567890123456789"); + } - @Test - public void getCurrentSession() { - String expectedAlias = "1"; - request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, expectedAlias); - assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(expectedAlias); - } + @Test + public void getCurrentSession() { + String expectedAlias = "1"; + request.setParameter(CookieHttpSessionStrategy.DEFAULT_SESSION_ALIAS_PARAM_NAME, expectedAlias); + assertThat(strategy.getCurrentSessionAlias(request)).isEqualTo(expectedAlias); + } - // --- getNewSessionAlias + // --- getNewSessionAlias - @Test - public void getNewSessionAliasNoSessions() { - assertThat(strategy.getNewSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); - } - - @Test - public void getNewSessionAliasSingleSession() { - setSessionCookie("abc"); + @Test + public void getNewSessionAliasNoSessions() { + assertThat(strategy.getNewSessionAlias(request)).isEqualTo(CookieHttpSessionStrategy.DEFAULT_ALIAS); + } + + @Test + public void getNewSessionAliasSingleSession() { + setSessionCookie("abc"); - assertThat(strategy.getNewSessionAlias(request)).isEqualTo("1"); - } + assertThat(strategy.getNewSessionAlias(request)).isEqualTo("1"); + } - @Test - public void getNewSessionAlias2Sessions() { - setCookieWithNSessions(2); + @Test + public void getNewSessionAlias2Sessions() { + setCookieWithNSessions(2); - assertThat(strategy.getNewSessionAlias(request)).isEqualTo("2"); - } + assertThat(strategy.getNewSessionAlias(request)).isEqualTo("2"); + } - @Test - public void getNewSessionAlias9Sessions() { - setCookieWithNSessions(9); + @Test + public void getNewSessionAlias9Sessions() { + setCookieWithNSessions(9); - assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("9"); - } + assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("9"); + } - @Test - public void getNewSessionAlias10Sessions() { - setCookieWithNSessions(10); + @Test + public void getNewSessionAlias10Sessions() { + setCookieWithNSessions(10); - assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("a"); - } + assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("a"); + } - @Test - public void getNewSessionAlias16Sessions() { - setCookieWithNSessions(16); + @Test + public void getNewSessionAlias16Sessions() { + setCookieWithNSessions(16); - assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("10"); - } - - @Test - public void getNewSessionAliasInvalidAlias() { - setSessionCookie("0 1 $ b"); + assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("10"); + } + + @Test + public void getNewSessionAliasInvalidAlias() { + setSessionCookie("0 1 $ b"); - assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("1"); - } + assertThat(strategy.getNewSessionAlias(request)).isEqualToIgnoringCase("1"); + } - // --- getSessionIds + // --- getSessionIds - @Test - public void getSessionIdsNone() { - assertThat(strategy.getSessionIds(request)).isEmpty(); - } + @Test + public void getSessionIdsNone() { + assertThat(strategy.getSessionIds(request)).isEmpty(); + } - @Test - public void getSessionIdsSingle() { - String expectedId = "a"; - setSessionCookie(expectedId); - - Map sessionIds = strategy.getSessionIds(request); - assertThat(sessionIds.size()).isEqualTo(1); - assertThat(sessionIds.get("0")).isEqualTo(expectedId); - } - - @Test - public void getSessionIdsMulti() { - setSessionCookie("0 a 1 b"); - - Map sessionIds = strategy.getSessionIds(request); - assertThat(sessionIds.size()).isEqualTo(2); - assertThat(sessionIds.get("0")).isEqualTo("a"); - assertThat(sessionIds.get("1")).isEqualTo("b"); - } - - @Test - public void getSessionIdsDangling() { - setSessionCookie("0 a 1 b noValue"); - - Map sessionIds = strategy.getSessionIds(request); - assertThat(sessionIds.size()).isEqualTo(2); - assertThat(sessionIds.get("0")).isEqualTo("a"); - assertThat(sessionIds.get("1")).isEqualTo("b"); - } - - // --- helper - - @Test - public void createSessionCookieValue() { - assertThat(createSessionCookieValue(17)).isEqualToIgnoringCase("0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 a 10 b 11 c 12 d 13 e 14 f 15 10 16"); - } - - private void setCookieWithNSessions(long size) { - setSessionCookie(createSessionCookieValue(size)); - } - - private String createSessionCookieValue(long size) { - StringBuffer buffer = new StringBuffer(); + @Test + public void getSessionIdsSingle() { + String expectedId = "a"; + setSessionCookie(expectedId); + + Map sessionIds = strategy.getSessionIds(request); + assertThat(sessionIds.size()).isEqualTo(1); + assertThat(sessionIds.get("0")).isEqualTo(expectedId); + } + + @Test + public void getSessionIdsMulti() { + setSessionCookie("0 a 1 b"); + + Map sessionIds = strategy.getSessionIds(request); + assertThat(sessionIds.size()).isEqualTo(2); + assertThat(sessionIds.get("0")).isEqualTo("a"); + assertThat(sessionIds.get("1")).isEqualTo("b"); + } + + @Test + public void getSessionIdsDangling() { + setSessionCookie("0 a 1 b noValue"); + + Map sessionIds = strategy.getSessionIds(request); + assertThat(sessionIds.size()).isEqualTo(2); + assertThat(sessionIds.get("0")).isEqualTo("a"); + assertThat(sessionIds.get("1")).isEqualTo("b"); + } + + // --- helper + + @Test + public void createSessionCookieValue() { + assertThat(createSessionCookieValue(17)).isEqualToIgnoringCase("0 0 1 1 2 2 3 3 4 4 5 5 6 6 7 7 8 8 9 9 a 10 b 11 c 12 d 13 e 14 f 15 10 16"); + } + + private void setCookieWithNSessions(long size) { + setSessionCookie(createSessionCookieValue(size)); + } + + private String createSessionCookieValue(long size) { + StringBuffer buffer = new StringBuffer(); - for(long i=0;i < size; i++) { - String hex = Long.toHexString(i); - buffer.append(hex); - buffer.append(" "); - buffer.append(i); - if(i < size - 1) { - buffer.append(" "); - } - } - - return buffer.toString(); - } - - public void setCookieName(String cookieName) { - strategy.setCookieName(cookieName); - this.cookieName = cookieName; - } - - public void setSessionCookie(String value) { - request.setCookies(new Cookie(cookieName, value)); - } - - public String getSessionId() { - return response.getCookie(cookieName).getValue(); - } + for(long i=0;i < size; i++) { + String hex = Long.toHexString(i); + buffer.append(hex); + buffer.append(" "); + buffer.append(i); + if(i < size - 1) { + buffer.append(" "); + } + } + + return buffer.toString(); + } + + public void setCookieName(String cookieName) { + strategy.setCookieName(cookieName); + this.cookieName = cookieName; + } + + public void setSessionCookie(String value) { + request.setCookies(new Cookie(cookieName, value)); + } + + public String getSessionId() { + return response.getCookie(cookieName).getValue(); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/web/http/HeaderSessionStrategyTests.java b/spring-session/src/test/java/org/springframework/session/web/http/HeaderSessionStrategyTests.java index 455f5317..b154cc42 100644 --- a/spring-session/src/test/java/org/springframework/session/web/http/HeaderSessionStrategyTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/http/HeaderSessionStrategyTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.web.http; import org.junit.Before; @@ -11,102 +26,102 @@ import org.springframework.session.web.http.HeaderHttpSessionStrategy; import static org.fest.assertions.Assertions.assertThat; public class HeaderSessionStrategyTests { - private MockHttpServletRequest request; - private MockHttpServletResponse response; + private MockHttpServletRequest request; + private MockHttpServletResponse response; - private HeaderHttpSessionStrategy strategy; - private String headerName; - private Session session; + private HeaderHttpSessionStrategy strategy; + private String headerName; + private Session session; - @Before - public void setup() throws Exception { - headerName = "x-auth-token"; - session = new MapSession(); - request = new MockHttpServletRequest(); - response = new MockHttpServletResponse(); - strategy = new HeaderHttpSessionStrategy(); - } + @Before + public void setup() throws Exception { + headerName = "x-auth-token"; + session = new MapSession(); + request = new MockHttpServletRequest(); + response = new MockHttpServletResponse(); + strategy = new HeaderHttpSessionStrategy(); + } - @Test - public void getRequestedSessionIdNull() throws Exception { - assertThat(strategy.getRequestedSessionId(request)).isNull(); - } + @Test + public void getRequestedSessionIdNull() throws Exception { + assertThat(strategy.getRequestedSessionId(request)).isNull(); + } - @Test - public void getRequestedSessionIdNotNull() throws Exception { - setSessionId(session.getId()); - assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); - } + @Test + public void getRequestedSessionIdNotNull() throws Exception { + setSessionId(session.getId()); + assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); + } - @Test - public void getRequestedSessionIdNotNullCustomHeaderName() throws Exception { - setHeaderName("CUSTOM"); - setSessionId(session.getId()); - assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); - } + @Test + public void getRequestedSessionIdNotNullCustomHeaderName() throws Exception { + setHeaderName("CUSTOM"); + setSessionId(session.getId()); + assertThat(strategy.getRequestedSessionId(request)).isEqualTo(session.getId()); + } - @Test - public void onNewSession() throws Exception { - strategy.onNewSession(session, request, response); - assertThat(getSessionId()).isEqualTo(session.getId()); - } + @Test + public void onNewSession() throws Exception { + strategy.onNewSession(session, request, response); + assertThat(getSessionId()).isEqualTo(session.getId()); + } - // the header is set as apposed to added - @Test - public void onNewSessionMulti() throws Exception { - strategy.onNewSession(session, request, response); - strategy.onNewSession(session, request, response); + // the header is set as apposed to added + @Test + public void onNewSessionMulti() throws Exception { + strategy.onNewSession(session, request, response); + strategy.onNewSession(session, request, response); - assertThat(response.getHeaders(headerName).size()).isEqualTo(1); - assertThat(response.getHeaders(headerName)).containsOnly(session.getId()); - } + assertThat(response.getHeaders(headerName).size()).isEqualTo(1); + assertThat(response.getHeaders(headerName)).containsOnly(session.getId()); + } - @Test - public void onNewSessionCustomHeaderName() throws Exception { - setHeaderName("CUSTOM"); - strategy.onNewSession(session, request, response); - assertThat(getSessionId()).isEqualTo(session.getId()); - } + @Test + public void onNewSessionCustomHeaderName() throws Exception { + setHeaderName("CUSTOM"); + strategy.onNewSession(session, request, response); + assertThat(getSessionId()).isEqualTo(session.getId()); + } - @Test - public void onDeleteSession() throws Exception { - strategy.onInvalidateSession(request, response); - assertThat(getSessionId()).isEmpty(); - } + @Test + public void onDeleteSession() throws Exception { + strategy.onInvalidateSession(request, response); + assertThat(getSessionId()).isEmpty(); + } - // the header is set as apposed to added - @Test - public void onDeleteSessionMulti() throws Exception { - strategy.onInvalidateSession(request, response); - strategy.onInvalidateSession(request, response); + // the header is set as apposed to added + @Test + public void onDeleteSessionMulti() throws Exception { + strategy.onInvalidateSession(request, response); + strategy.onInvalidateSession(request, response); - assertThat(response.getHeaders(headerName).size()).isEqualTo(1); - assertThat(getSessionId()).isEmpty(); - } + assertThat(response.getHeaders(headerName).size()).isEqualTo(1); + assertThat(getSessionId()).isEmpty(); + } - @Test - public void onDeleteSessionCustomHeaderName() throws Exception { - setHeaderName("CUSTOM"); - strategy.onInvalidateSession(request, response); - assertThat(getSessionId()).isEmpty(); - } + @Test + public void onDeleteSessionCustomHeaderName() throws Exception { + setHeaderName("CUSTOM"); + strategy.onInvalidateSession(request, response); + assertThat(getSessionId()).isEmpty(); + } - @Test(expected = IllegalArgumentException.class) - public void setHeaderNameNull() throws Exception { - strategy.setHeaderName(null); - } + @Test(expected = IllegalArgumentException.class) + public void setHeaderNameNull() throws Exception { + strategy.setHeaderName(null); + } - public void setHeaderName(String headerName) { - strategy.setHeaderName(headerName); - this.headerName = headerName; - } + public void setHeaderName(String headerName) { + strategy.setHeaderName(headerName); + this.headerName = headerName; + } - public void setSessionId(String id) { - request.addHeader(headerName, id); - } + public void setSessionId(String id) { + request.addHeader(headerName, id); + } - public String getSessionId() { - return response.getHeader(headerName); - } + public String getSessionId() { + return response.getHeader(headerName); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/web/http/OnCommittedResponseWrapperTests.java b/spring-session/src/test/java/org/springframework/session/web/http/OnCommittedResponseWrapperTests.java index 2612b638..b7e7f550 100644 --- a/spring-session/src/test/java/org/springframework/session/web/http/OnCommittedResponseWrapperTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/http/OnCommittedResponseWrapperTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.web.http; import java.io.IOException; @@ -19,1089 +34,1089 @@ import static org.mockito.Mockito.when; @RunWith(MockitoJUnitRunner.class) public class OnCommittedResponseWrapperTests { - private static final String NL = "\r\n"; + private static final String NL = "\r\n"; - @Mock - HttpServletResponse delegate; - @Mock - PrintWriter writer; - @Mock - ServletOutputStream out; + @Mock + HttpServletResponse delegate; + @Mock + PrintWriter writer; + @Mock + ServletOutputStream out; - OnCommittedResponseWrapper response; + OnCommittedResponseWrapper response; - boolean committed; + boolean committed; - @Before - public void setup() throws Exception { - response = new OnCommittedResponseWrapper(delegate) { - @Override - protected void onResponseCommitted() { - committed = true; - } - }; - when(delegate.getWriter()).thenReturn(writer); - when(delegate.getOutputStream()).thenReturn(out); - } + @Before + public void setup() throws Exception { + response = new OnCommittedResponseWrapper(delegate) { + @Override + protected void onResponseCommitted() { + committed = true; + } + }; + when(delegate.getWriter()).thenReturn(writer); + when(delegate.getOutputStream()).thenReturn(out); + } - // --- printwriter + // --- printwriter - @Test - public void printWriterHashCode() throws Exception { - int expected = writer.hashCode(); + @Test + public void printWriterHashCode() throws Exception { + int expected = writer.hashCode(); - assertThat(response.getWriter().hashCode()).isEqualTo(expected); - } + assertThat(response.getWriter().hashCode()).isEqualTo(expected); + } - @Test - public void printWriterCheckError() throws Exception { - boolean expected = true; - when(writer.checkError()).thenReturn(expected); + @Test + public void printWriterCheckError() throws Exception { + boolean expected = true; + when(writer.checkError()).thenReturn(expected); - assertThat(response.getWriter().checkError()).isEqualTo(expected); - } + assertThat(response.getWriter().checkError()).isEqualTo(expected); + } - @Test - public void printWriterWriteInt() throws Exception { - int expected = 1; + @Test + public void printWriterWriteInt() throws Exception { + int expected = 1; - response.getWriter().write(expected); + response.getWriter().write(expected); - verify(writer).write(expected); - } + verify(writer).write(expected); + } - @Test - public void printWriterWriteCharIntInt() throws Exception { - char[] buff = new char[0]; - int off = 2; - int len = 3; + @Test + public void printWriterWriteCharIntInt() throws Exception { + char[] buff = new char[0]; + int off = 2; + int len = 3; - response.getWriter().write(buff,off,len); + response.getWriter().write(buff,off,len); - verify(writer).write(buff,off,len); - } + verify(writer).write(buff,off,len); + } - @Test - public void printWriterWriteChar() throws Exception { - char[] buff = new char[0]; + @Test + public void printWriterWriteChar() throws Exception { + char[] buff = new char[0]; - response.getWriter().write(buff); + response.getWriter().write(buff); - verify(writer).write(buff); - } + verify(writer).write(buff); + } - @Test - public void printWriterWriteStringIntInt() throws Exception { - String s = ""; - int off = 2; - int len = 3; + @Test + public void printWriterWriteStringIntInt() throws Exception { + String s = ""; + int off = 2; + int len = 3; - response.getWriter().write(s,off,len); + response.getWriter().write(s,off,len); - verify(writer).write(s,off,len); - } + verify(writer).write(s,off,len); + } - @Test - public void printWriterWriteString() throws Exception { - String s = ""; + @Test + public void printWriterWriteString() throws Exception { + String s = ""; - response.getWriter().write(s); + response.getWriter().write(s); - verify(writer).write(s); - } + verify(writer).write(s); + } - @Test - public void printWriterPrintBoolean() throws Exception { - boolean b = true; + @Test + public void printWriterPrintBoolean() throws Exception { + boolean b = true; - response.getWriter().print(b); + response.getWriter().print(b); - verify(writer).print(b); - } + verify(writer).print(b); + } - @Test - public void printWriterPrintChar() throws Exception { - char c = 1; + @Test + public void printWriterPrintChar() throws Exception { + char c = 1; - response.getWriter().print(c); + response.getWriter().print(c); - verify(writer).print(c); - } + verify(writer).print(c); + } - @Test - public void printWriterPrintInt() throws Exception { - int i = 1; + @Test + public void printWriterPrintInt() throws Exception { + int i = 1; - response.getWriter().print(i); + response.getWriter().print(i); - verify(writer).print(i); - } + verify(writer).print(i); + } - @Test - public void printWriterPrintLong() throws Exception { - long l = 1; + @Test + public void printWriterPrintLong() throws Exception { + long l = 1; - response.getWriter().print(l); + response.getWriter().print(l); - verify(writer).print(l); - } + verify(writer).print(l); + } - @Test - public void printWriterPrintFloat() throws Exception { - float f = 1; + @Test + public void printWriterPrintFloat() throws Exception { + float f = 1; - response.getWriter().print(f); + response.getWriter().print(f); - verify(writer).print(f); - } + verify(writer).print(f); + } - @Test - public void printWriterPrintDouble() throws Exception { - double x = 1; + @Test + public void printWriterPrintDouble() throws Exception { + double x = 1; - response.getWriter().print(x); + response.getWriter().print(x); - verify(writer).print(x); - } + verify(writer).print(x); + } - @Test - public void printWriterPrintCharArray() throws Exception { - char[] x = new char[0]; + @Test + public void printWriterPrintCharArray() throws Exception { + char[] x = new char[0]; - response.getWriter().print(x); + response.getWriter().print(x); - verify(writer).print(x); - } + verify(writer).print(x); + } - @Test - public void printWriterPrintString() throws Exception { - String x = "1"; + @Test + public void printWriterPrintString() throws Exception { + String x = "1"; - response.getWriter().print(x); + response.getWriter().print(x); - verify(writer).print(x); - } + verify(writer).print(x); + } - @Test - public void printWriterPrintObject() throws Exception { - Object x = "1"; + @Test + public void printWriterPrintObject() throws Exception { + Object x = "1"; - response.getWriter().print(x); + response.getWriter().print(x); - verify(writer).print(x); - } + verify(writer).print(x); + } - @Test - public void printWriterPrintln() throws Exception { - response.getWriter().println(); + @Test + public void printWriterPrintln() throws Exception { + response.getWriter().println(); - verify(writer).println(); - } + verify(writer).println(); + } - @Test - public void printWriterPrintlnBoolean() throws Exception { - boolean b = true; + @Test + public void printWriterPrintlnBoolean() throws Exception { + boolean b = true; - response.getWriter().println(b); + response.getWriter().println(b); - verify(writer).println(b); - } + verify(writer).println(b); + } - @Test - public void printWriterPrintlnChar() throws Exception { - char c = 1; + @Test + public void printWriterPrintlnChar() throws Exception { + char c = 1; - response.getWriter().println(c); + response.getWriter().println(c); - verify(writer).println(c); - } + verify(writer).println(c); + } - @Test - public void printWriterPrintlnInt() throws Exception { - int i = 1; + @Test + public void printWriterPrintlnInt() throws Exception { + int i = 1; - response.getWriter().println(i); + response.getWriter().println(i); - verify(writer).println(i); - } + verify(writer).println(i); + } - @Test - public void printWriterPrintlnLong() throws Exception { - long l = 1; + @Test + public void printWriterPrintlnLong() throws Exception { + long l = 1; - response.getWriter().println(l); + response.getWriter().println(l); - verify(writer).println(l); - } + verify(writer).println(l); + } - @Test - public void printWriterPrintlnFloat() throws Exception { - float f = 1; + @Test + public void printWriterPrintlnFloat() throws Exception { + float f = 1; - response.getWriter().println(f); + response.getWriter().println(f); - verify(writer).println(f); - } + verify(writer).println(f); + } - @Test - public void printWriterPrintlnDouble() throws Exception { - double x = 1; + @Test + public void printWriterPrintlnDouble() throws Exception { + double x = 1; - response.getWriter().println(x); + response.getWriter().println(x); - verify(writer).println(x); - } + verify(writer).println(x); + } - @Test - public void printWriterPrintlnCharArray() throws Exception { - char[] x = new char[0]; + @Test + public void printWriterPrintlnCharArray() throws Exception { + char[] x = new char[0]; - response.getWriter().println(x); + response.getWriter().println(x); - verify(writer).println(x); - } + verify(writer).println(x); + } - @Test - public void printWriterPrintlnString() throws Exception { - String x = "1"; + @Test + public void printWriterPrintlnString() throws Exception { + String x = "1"; - response.getWriter().println(x); + response.getWriter().println(x); - verify(writer).println(x); - } + verify(writer).println(x); + } - @Test - public void printWriterPrintlnObject() throws Exception { - Object x = "1"; + @Test + public void printWriterPrintlnObject() throws Exception { + Object x = "1"; - response.getWriter().println(x); + response.getWriter().println(x); - verify(writer).println(x); - } + verify(writer).println(x); + } - @Test - public void printWriterPrintfStringObjectVargs() throws Exception { - String format = "format"; - Object[] args = new Object[] { "1" }; + @Test + public void printWriterPrintfStringObjectVargs() throws Exception { + String format = "format"; + Object[] args = new Object[] { "1" }; - response.getWriter().printf(format, args); + response.getWriter().printf(format, args); - verify(writer).printf(format, args); - } + verify(writer).printf(format, args); + } - @Test - public void printWriterPrintfLocaleStringObjectVargs() throws Exception { - Locale l = Locale.US; - String format = "format"; - Object[] args = new Object[] { "1" }; + @Test + public void printWriterPrintfLocaleStringObjectVargs() throws Exception { + Locale l = Locale.US; + String format = "format"; + Object[] args = new Object[] { "1" }; - response.getWriter().printf(l, format, args); + response.getWriter().printf(l, format, args); - verify(writer).printf(l, format, args); - } + verify(writer).printf(l, format, args); + } - @Test - public void printWriterFormatStringObjectVargs() throws Exception { - String format = "format"; - Object[] args = new Object[] { "1" }; + @Test + public void printWriterFormatStringObjectVargs() throws Exception { + String format = "format"; + Object[] args = new Object[] { "1" }; - response.getWriter().format(format, args); + response.getWriter().format(format, args); - verify(writer).format(format, args); - } + verify(writer).format(format, args); + } - @Test - public void printWriterFormatLocaleStringObjectVargs() throws Exception { - Locale l = Locale.US; - String format = "format"; - Object[] args = new Object[] { "1" }; + @Test + public void printWriterFormatLocaleStringObjectVargs() throws Exception { + Locale l = Locale.US; + String format = "format"; + Object[] args = new Object[] { "1" }; - response.getWriter().format(l, format, args); + response.getWriter().format(l, format, args); - verify(writer).format(l, format, args); - } + verify(writer).format(l, format, args); + } - @Test - public void printWriterAppendCharSequence() throws Exception { - String x = "a"; + @Test + public void printWriterAppendCharSequence() throws Exception { + String x = "a"; - response.getWriter().append(x); + response.getWriter().append(x); - verify(writer).append(x); - } + verify(writer).append(x); + } - @Test - public void printWriterAppendCharSequenceIntInt() throws Exception { - String x = "abcdef"; - int start = 1; - int end = 3; + @Test + public void printWriterAppendCharSequenceIntInt() throws Exception { + String x = "abcdef"; + int start = 1; + int end = 3; - response.getWriter().append(x, start, end); + response.getWriter().append(x, start, end); - verify(writer).append(x, start, end); - } + verify(writer).append(x, start, end); + } - @Test - public void printWriterAppendChar() throws Exception { - char x = 1; + @Test + public void printWriterAppendChar() throws Exception { + char x = 1; - response.getWriter().append(x); + response.getWriter().append(x); - verify(writer).append(x); - } + verify(writer).append(x); + } - // servletoutputstream + // servletoutputstream - @Test - public void outputStreamHashCode() throws Exception { - int expected = out.hashCode(); + @Test + public void outputStreamHashCode() throws Exception { + int expected = out.hashCode(); - assertThat(response.getOutputStream().hashCode()).isEqualTo(expected); - } + assertThat(response.getOutputStream().hashCode()).isEqualTo(expected); + } - @Test - public void outputStreamWriteInt() throws Exception { - int expected = 1; + @Test + public void outputStreamWriteInt() throws Exception { + int expected = 1; - response.getOutputStream().write(expected); + response.getOutputStream().write(expected); - verify(out).write(expected); - } + verify(out).write(expected); + } - @Test - public void outputStreamWriteByte() throws Exception { - byte[] expected = new byte[0]; + @Test + public void outputStreamWriteByte() throws Exception { + byte[] expected = new byte[0]; - response.getOutputStream().write(expected); + response.getOutputStream().write(expected); - verify(out).write(expected); - } + verify(out).write(expected); + } - @Test - public void outputStreamWriteByteIntInt() throws Exception { - int start = 1; - int end = 2; - byte[] expected = new byte[0]; + @Test + public void outputStreamWriteByteIntInt() throws Exception { + int start = 1; + int end = 2; + byte[] expected = new byte[0]; - response.getOutputStream().write(expected, start, end); + response.getOutputStream().write(expected, start, end); - verify(out).write(expected, start, end); - } + verify(out).write(expected, start, end); + } - @Test - public void outputStreamPrintBoolean() throws Exception { - boolean b = true; + @Test + public void outputStreamPrintBoolean() throws Exception { + boolean b = true; - response.getOutputStream().print(b); + response.getOutputStream().print(b); - verify(out).print(b); - } + verify(out).print(b); + } - @Test - public void outputStreamPrintChar() throws Exception { - char c = 1; + @Test + public void outputStreamPrintChar() throws Exception { + char c = 1; - response.getOutputStream().print(c); + response.getOutputStream().print(c); - verify(out).print(c); - } + verify(out).print(c); + } - @Test - public void outputStreamPrintInt() throws Exception { - int i = 1; + @Test + public void outputStreamPrintInt() throws Exception { + int i = 1; - response.getOutputStream().print(i); + response.getOutputStream().print(i); - verify(out).print(i); - } + verify(out).print(i); + } - @Test - public void outputStreamPrintLong() throws Exception { - long l = 1; + @Test + public void outputStreamPrintLong() throws Exception { + long l = 1; - response.getOutputStream().print(l); + response.getOutputStream().print(l); - verify(out).print(l); - } + verify(out).print(l); + } - @Test - public void outputStreamPrintFloat() throws Exception { - float f = 1; + @Test + public void outputStreamPrintFloat() throws Exception { + float f = 1; - response.getOutputStream().print(f); + response.getOutputStream().print(f); - verify(out).print(f); - } + verify(out).print(f); + } - @Test - public void outputStreamPrintDouble() throws Exception { - double x = 1; + @Test + public void outputStreamPrintDouble() throws Exception { + double x = 1; - response.getOutputStream().print(x); + response.getOutputStream().print(x); - verify(out).print(x); - } + verify(out).print(x); + } - @Test - public void outputStreamPrintString() throws Exception { - String x = "1"; + @Test + public void outputStreamPrintString() throws Exception { + String x = "1"; - response.getOutputStream().print(x); + response.getOutputStream().print(x); - verify(out).print(x); - } + verify(out).print(x); + } - @Test - public void outputStreamPrintln() throws Exception { - response.getOutputStream().println(); + @Test + public void outputStreamPrintln() throws Exception { + response.getOutputStream().println(); - verify(out).println(); - } + verify(out).println(); + } - @Test - public void outputStreamPrintlnBoolean() throws Exception { - boolean b = true; + @Test + public void outputStreamPrintlnBoolean() throws Exception { + boolean b = true; - response.getOutputStream().println(b); + response.getOutputStream().println(b); - verify(out).println(b); - } + verify(out).println(b); + } - @Test - public void outputStreamPrintlnChar() throws Exception { - char c = 1; + @Test + public void outputStreamPrintlnChar() throws Exception { + char c = 1; - response.getOutputStream().println(c); + response.getOutputStream().println(c); - verify(out).println(c); - } + verify(out).println(c); + } - @Test - public void outputStreamPrintlnInt() throws Exception { - int i = 1; + @Test + public void outputStreamPrintlnInt() throws Exception { + int i = 1; - response.getOutputStream().println(i); + response.getOutputStream().println(i); - verify(out).println(i); - } + verify(out).println(i); + } - @Test - public void outputStreamPrintlnLong() throws Exception { - long l = 1; + @Test + public void outputStreamPrintlnLong() throws Exception { + long l = 1; - response.getOutputStream().println(l); + response.getOutputStream().println(l); - verify(out).println(l); - } + verify(out).println(l); + } - @Test - public void outputStreamPrintlnFloat() throws Exception { - float f = 1; + @Test + public void outputStreamPrintlnFloat() throws Exception { + float f = 1; - response.getOutputStream().println(f); + response.getOutputStream().println(f); - verify(out).println(f); - } + verify(out).println(f); + } - @Test - public void outputStreamPrintlnDouble() throws Exception { - double x = 1; + @Test + public void outputStreamPrintlnDouble() throws Exception { + double x = 1; - response.getOutputStream().println(x); + response.getOutputStream().println(x); - verify(out).println(x); - } + verify(out).println(x); + } - @Test - public void outputStreamPrintlnString() throws Exception { - String x = "1"; + @Test + public void outputStreamPrintlnString() throws Exception { + String x = "1"; - response.getOutputStream().println(x); + response.getOutputStream().println(x); - verify(out).println(x); - } + verify(out).println(x); + } - // The amount of content specified in the setContentLength method of the response - // has been greater than zero and has been written to the response. + // The amount of content specified in the setContentLength method of the response + // has been greater than zero and has been written to the response. - @Test - public void contentLengthPrintWriterWriteIntCommits() throws Exception { - int expected = 1; - response.setContentLength(String.valueOf(expected).length()); + @Test + public void contentLengthPrintWriterWriteIntCommits() throws Exception { + int expected = 1; + response.setContentLength(String.valueOf(expected).length()); - response.getWriter().write(expected); + response.getWriter().write(expected); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterWriteIntMultiDigitCommits() throws Exception { - int expected = 10000; - response.setContentLength(String.valueOf(expected).length()); + @Test + public void contentLengthPrintWriterWriteIntMultiDigitCommits() throws Exception { + int expected = 10000; + response.setContentLength(String.valueOf(expected).length()); - response.getWriter().write(expected); + response.getWriter().write(expected); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPlus1PrintWriterWriteIntMultiDigitCommits() throws Exception { - int expected = 10000; - response.setContentLength(String.valueOf(expected).length() + 1); + @Test + public void contentLengthPlus1PrintWriterWriteIntMultiDigitCommits() throws Exception { + int expected = 10000; + response.setContentLength(String.valueOf(expected).length() + 1); - response.getWriter().write(expected); + response.getWriter().write(expected); - assertThat(committed).isFalse(); + assertThat(committed).isFalse(); - response.getWriter().write(1); + response.getWriter().write(1); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterWriteCharIntIntCommits() throws Exception { - char[] buff = new char[0]; - int off = 2; - int len = 3; - response.setContentLength(3); + @Test + public void contentLengthPrintWriterWriteCharIntIntCommits() throws Exception { + char[] buff = new char[0]; + int off = 2; + int len = 3; + response.setContentLength(3); - response.getWriter().write(buff,off,len); + response.getWriter().write(buff,off,len); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterWriteCharCommits() throws Exception { - char[] buff = new char[4]; - response.setContentLength(buff.length); + @Test + public void contentLengthPrintWriterWriteCharCommits() throws Exception { + char[] buff = new char[4]; + response.setContentLength(buff.length); - response.getWriter().write(buff); + response.getWriter().write(buff); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterWriteStringIntIntCommits() throws Exception { - String s = ""; - int off = 2; - int len = 3; - response.setContentLength(3); + @Test + public void contentLengthPrintWriterWriteStringIntIntCommits() throws Exception { + String s = ""; + int off = 2; + int len = 3; + response.setContentLength(3); - response.getWriter().write(s,off,len); + response.getWriter().write(s,off,len); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterWriteStringCommits() throws IOException { - String body = "something"; - response.setContentLength(body.length()); + @Test + public void contentLengthPrintWriterWriteStringCommits() throws IOException { + String body = "something"; + response.setContentLength(body.length()); - response.getWriter().write(body); + response.getWriter().write(body); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void printWriterWriteStringContentLengthCommits() throws IOException { - String body = "something"; - response.getWriter().write(body); + @Test + public void printWriterWriteStringContentLengthCommits() throws IOException { + String body = "something"; + response.getWriter().write(body); - response.setContentLength(body.length()); + response.setContentLength(body.length()); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void printWriterWriteStringDoesNotCommit() throws IOException { - String body = "something"; + @Test + public void printWriterWriteStringDoesNotCommit() throws IOException { + String body = "something"; - response.getWriter().write(body); + response.getWriter().write(body); - assertThat(committed).isFalse(); - } + assertThat(committed).isFalse(); + } - @Test - public void contentLengthPrintWriterPrintBooleanCommits() throws Exception { - boolean b = true; - response.setContentLength(1); + @Test + public void contentLengthPrintWriterPrintBooleanCommits() throws Exception { + boolean b = true; + response.setContentLength(1); - response.getWriter().print(b); + response.getWriter().print(b); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintCharCommits() throws Exception { - char c = 1; - response.setContentLength(1); + @Test + public void contentLengthPrintWriterPrintCharCommits() throws Exception { + char c = 1; + response.setContentLength(1); - response.getWriter().print(c); + response.getWriter().print(c); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintIntCommits() throws Exception { - int i = 1234; - response.setContentLength(String.valueOf(i).length()); + @Test + public void contentLengthPrintWriterPrintIntCommits() throws Exception { + int i = 1234; + response.setContentLength(String.valueOf(i).length()); - response.getWriter().print(i); + response.getWriter().print(i); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintLongCommits() throws Exception { - long l = 12345; - response.setContentLength(String.valueOf(l).length()); + @Test + public void contentLengthPrintWriterPrintLongCommits() throws Exception { + long l = 12345; + response.setContentLength(String.valueOf(l).length()); - response.getWriter().print(l); + response.getWriter().print(l); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintFloatCommits() throws Exception { - float f = 12345; - response.setContentLength(String.valueOf(f).length()); + @Test + public void contentLengthPrintWriterPrintFloatCommits() throws Exception { + float f = 12345; + response.setContentLength(String.valueOf(f).length()); - response.getWriter().print(f); + response.getWriter().print(f); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintDoubleCommits() throws Exception { - double x = 1.2345; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthPrintWriterPrintDoubleCommits() throws Exception { + double x = 1.2345; + response.setContentLength(String.valueOf(x).length()); - response.getWriter().print(x); + response.getWriter().print(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintCharArrayCommits() throws Exception { - char[] x = new char[10]; - response.setContentLength(x.length); + @Test + public void contentLengthPrintWriterPrintCharArrayCommits() throws Exception { + char[] x = new char[10]; + response.setContentLength(x.length); - response.getWriter().print(x); + response.getWriter().print(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintStringCommits() throws Exception { - String x = "12345"; - response.setContentLength(x.length()); + @Test + public void contentLengthPrintWriterPrintStringCommits() throws Exception { + String x = "12345"; + response.setContentLength(x.length()); - response.getWriter().print(x); + response.getWriter().print(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintObjectCommits() throws Exception { - Object x = "12345"; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthPrintWriterPrintObjectCommits() throws Exception { + Object x = "12345"; + response.setContentLength(String.valueOf(x).length()); - response.getWriter().print(x); + response.getWriter().print(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnCommits() throws Exception { - response.setContentLength(NL.length()); + @Test + public void contentLengthPrintWriterPrintlnCommits() throws Exception { + response.setContentLength(NL.length()); - response.getWriter().println(); + response.getWriter().println(); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnBooleanCommits() throws Exception { - boolean b = true; - response.setContentLength(1); + @Test + public void contentLengthPrintWriterPrintlnBooleanCommits() throws Exception { + boolean b = true; + response.setContentLength(1); - response.getWriter().println(b); + response.getWriter().println(b); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnCharCommits() throws Exception { - char c = 1; - response.setContentLength(1); + @Test + public void contentLengthPrintWriterPrintlnCharCommits() throws Exception { + char c = 1; + response.setContentLength(1); - response.getWriter().println(c); + response.getWriter().println(c); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnIntCommits() throws Exception { - int i = 12345; - response.setContentLength(String.valueOf(i).length()); + @Test + public void contentLengthPrintWriterPrintlnIntCommits() throws Exception { + int i = 12345; + response.setContentLength(String.valueOf(i).length()); - response.getWriter().println(i); + response.getWriter().println(i); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnLongCommits() throws Exception { - long l = 12345678; - response.setContentLength(String.valueOf(l).length()); + @Test + public void contentLengthPrintWriterPrintlnLongCommits() throws Exception { + long l = 12345678; + response.setContentLength(String.valueOf(l).length()); - response.getWriter().println(l); + response.getWriter().println(l); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnFloatCommits() throws Exception { - float f = 1234; - response.setContentLength(String.valueOf(f).length()); + @Test + public void contentLengthPrintWriterPrintlnFloatCommits() throws Exception { + float f = 1234; + response.setContentLength(String.valueOf(f).length()); - response.getWriter().println(f); + response.getWriter().println(f); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnDoubleCommits() throws Exception { - double x = 1; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthPrintWriterPrintlnDoubleCommits() throws Exception { + double x = 1; + response.setContentLength(String.valueOf(x).length()); - response.getWriter().println(x); + response.getWriter().println(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnCharArrayCommits() throws Exception { - char[] x = new char[20]; - response.setContentLength(x.length); + @Test + public void contentLengthPrintWriterPrintlnCharArrayCommits() throws Exception { + char[] x = new char[20]; + response.setContentLength(x.length); - response.getWriter().println(x); + response.getWriter().println(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnStringCommits() throws Exception { - String x = "1"; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthPrintWriterPrintlnStringCommits() throws Exception { + String x = "1"; + response.setContentLength(String.valueOf(x).length()); - response.getWriter().println(x); + response.getWriter().println(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterPrintlnObjectCommits() throws Exception { - Object x = "1"; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthPrintWriterPrintlnObjectCommits() throws Exception { + Object x = "1"; + response.setContentLength(String.valueOf(x).length()); - response.getWriter().println(x); + response.getWriter().println(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterAppendCharSequenceCommits() throws Exception { - String x = "a"; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthPrintWriterAppendCharSequenceCommits() throws Exception { + String x = "a"; + response.setContentLength(String.valueOf(x).length()); - response.getWriter().append(x); + response.getWriter().append(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterAppendCharSequenceIntIntCommits() throws Exception { - String x = "abcdef"; - int start = 1; - int end = 3; - response.setContentLength(end - start); + @Test + public void contentLengthPrintWriterAppendCharSequenceIntIntCommits() throws Exception { + String x = "abcdef"; + int start = 1; + int end = 3; + response.setContentLength(end - start); - response.getWriter().append(x, start, end); + response.getWriter().append(x, start, end); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPrintWriterAppendCharCommits() throws Exception { - char x = 1; - response.setContentLength(1); + @Test + public void contentLengthPrintWriterAppendCharCommits() throws Exception { + char x = 1; + response.setContentLength(1); - response.getWriter().append(x); + response.getWriter().append(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamWriteIntCommits() throws Exception { - int expected = 1; - response.setContentLength(String.valueOf(expected).length()); + @Test + public void contentLengthOutputStreamWriteIntCommits() throws Exception { + int expected = 1; + response.setContentLength(String.valueOf(expected).length()); - response.getOutputStream().write(expected); + response.getOutputStream().write(expected); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamWriteIntMultiDigitCommits() throws Exception { - int expected = 10000; - response.setContentLength(String.valueOf(expected).length()); + @Test + public void contentLengthOutputStreamWriteIntMultiDigitCommits() throws Exception { + int expected = 10000; + response.setContentLength(String.valueOf(expected).length()); - response.getOutputStream().write(expected); + response.getOutputStream().write(expected); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthPlus1OutputStreamWriteIntMultiDigitCommits() throws Exception { - int expected = 10000; - response.setContentLength(String.valueOf(expected).length() + 1); + @Test + public void contentLengthPlus1OutputStreamWriteIntMultiDigitCommits() throws Exception { + int expected = 10000; + response.setContentLength(String.valueOf(expected).length() + 1); - response.getOutputStream().write(expected); + response.getOutputStream().write(expected); - assertThat(committed).isFalse(); + assertThat(committed).isFalse(); - response.getOutputStream().write(1); + response.getOutputStream().write(1); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - // gh-171 - @Test - public void contentLengthPlus1OutputStreamWriteByteArrayMultiDigitCommits() throws Exception { - String expected = "{\n" + - " \"parameterName\" : \"_csrf\",\n" + - " \"token\" : \"06300b65-c4aa-4c8f-8cda-39ee17f545a0\",\n" + - " \"headerName\" : \"X-CSRF-TOKEN\"\n" + - "}"; - response.setContentLength(expected.length() + 1); + // gh-171 + @Test + public void contentLengthPlus1OutputStreamWriteByteArrayMultiDigitCommits() throws Exception { + String expected = "{\n" + + " \"parameterName\" : \"_csrf\",\n" + + " \"token\" : \"06300b65-c4aa-4c8f-8cda-39ee17f545a0\",\n" + + " \"headerName\" : \"X-CSRF-TOKEN\"\n" + + "}"; + response.setContentLength(expected.length() + 1); - response.getOutputStream().write(expected.getBytes()); + response.getOutputStream().write(expected.getBytes()); - assertThat(committed).isFalse(); + assertThat(committed).isFalse(); - response.getOutputStream().write("1".getBytes("UTF-8")); + response.getOutputStream().write("1".getBytes("UTF-8")); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintBooleanCommits() throws Exception { - boolean b = true; - response.setContentLength(1); + @Test + public void contentLengthOutputStreamPrintBooleanCommits() throws Exception { + boolean b = true; + response.setContentLength(1); - response.getOutputStream().print(b); + response.getOutputStream().print(b); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintCharCommits() throws Exception { - char c = 1; - response.setContentLength(1); + @Test + public void contentLengthOutputStreamPrintCharCommits() throws Exception { + char c = 1; + response.setContentLength(1); - response.getOutputStream().print(c); + response.getOutputStream().print(c); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintIntCommits() throws Exception { - int i = 1234; - response.setContentLength(String.valueOf(i).length()); + @Test + public void contentLengthOutputStreamPrintIntCommits() throws Exception { + int i = 1234; + response.setContentLength(String.valueOf(i).length()); - response.getOutputStream().print(i); + response.getOutputStream().print(i); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintLongCommits() throws Exception { - long l = 12345; - response.setContentLength(String.valueOf(l).length()); + @Test + public void contentLengthOutputStreamPrintLongCommits() throws Exception { + long l = 12345; + response.setContentLength(String.valueOf(l).length()); - response.getOutputStream().print(l); + response.getOutputStream().print(l); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintFloatCommits() throws Exception { - float f = 12345; - response.setContentLength(String.valueOf(f).length()); + @Test + public void contentLengthOutputStreamPrintFloatCommits() throws Exception { + float f = 12345; + response.setContentLength(String.valueOf(f).length()); - response.getOutputStream().print(f); + response.getOutputStream().print(f); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintDoubleCommits() throws Exception { - double x = 1.2345; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthOutputStreamPrintDoubleCommits() throws Exception { + double x = 1.2345; + response.setContentLength(String.valueOf(x).length()); - response.getOutputStream().print(x); + response.getOutputStream().print(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintStringCommits() throws Exception { - String x = "12345"; - response.setContentLength(x.length()); + @Test + public void contentLengthOutputStreamPrintStringCommits() throws Exception { + String x = "12345"; + response.setContentLength(x.length()); - response.getOutputStream().print(x); + response.getOutputStream().print(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnCommits() throws Exception { - response.setContentLength(NL.length()); + @Test + public void contentLengthOutputStreamPrintlnCommits() throws Exception { + response.setContentLength(NL.length()); - response.getOutputStream().println(); + response.getOutputStream().println(); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnBooleanCommits() throws Exception { - boolean b = true; - response.setContentLength(1); + @Test + public void contentLengthOutputStreamPrintlnBooleanCommits() throws Exception { + boolean b = true; + response.setContentLength(1); - response.getOutputStream().println(b); + response.getOutputStream().println(b); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnCharCommits() throws Exception { - char c = 1; - response.setContentLength(1); + @Test + public void contentLengthOutputStreamPrintlnCharCommits() throws Exception { + char c = 1; + response.setContentLength(1); - response.getOutputStream().println(c); + response.getOutputStream().println(c); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnIntCommits() throws Exception { - int i = 12345; - response.setContentLength(String.valueOf(i).length()); + @Test + public void contentLengthOutputStreamPrintlnIntCommits() throws Exception { + int i = 12345; + response.setContentLength(String.valueOf(i).length()); - response.getOutputStream().println(i); + response.getOutputStream().println(i); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnLongCommits() throws Exception { - long l = 12345678; - response.setContentLength(String.valueOf(l).length()); + @Test + public void contentLengthOutputStreamPrintlnLongCommits() throws Exception { + long l = 12345678; + response.setContentLength(String.valueOf(l).length()); - response.getOutputStream().println(l); + response.getOutputStream().println(l); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnFloatCommits() throws Exception { - float f = 1234; - response.setContentLength(String.valueOf(f).length()); + @Test + public void contentLengthOutputStreamPrintlnFloatCommits() throws Exception { + float f = 1234; + response.setContentLength(String.valueOf(f).length()); - response.getOutputStream().println(f); + response.getOutputStream().println(f); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnDoubleCommits() throws Exception { - double x = 1; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthOutputStreamPrintlnDoubleCommits() throws Exception { + double x = 1; + response.setContentLength(String.valueOf(x).length()); - response.getOutputStream().println(x); + response.getOutputStream().println(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthOutputStreamPrintlnStringCommits() throws Exception { - String x = "1"; - response.setContentLength(String.valueOf(x).length()); + @Test + public void contentLengthOutputStreamPrintlnStringCommits() throws Exception { + String x = "1"; + response.setContentLength(String.valueOf(x).length()); - response.getOutputStream().println(x); + response.getOutputStream().println(x); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void contentLengthDoesNotCommit() throws IOException { - String body = "something"; + @Test + public void contentLengthDoesNotCommit() throws IOException { + String body = "something"; - response.setContentLength(body.length()); + response.setContentLength(body.length()); - assertThat(committed).isFalse(); - } + assertThat(committed).isFalse(); + } - @Test - public void contentLengthOutputStreamWriteStringCommits() throws IOException { - String body = "something"; - response.setContentLength(body.length()); + @Test + public void contentLengthOutputStreamWriteStringCommits() throws IOException { + String body = "something"; + response.setContentLength(body.length()); - response.getOutputStream().print(body); + response.getOutputStream().print(body); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void addHeaderContentLengthPrintWriterWriteStringCommits() throws Exception { - int expected = 1234; - response.addHeader("Content-Length",String.valueOf(String.valueOf(expected).length())); + @Test + public void addHeaderContentLengthPrintWriterWriteStringCommits() throws Exception { + int expected = 1234; + response.addHeader("Content-Length",String.valueOf(String.valueOf(expected).length())); - response.getWriter().write(expected); + response.getWriter().write(expected); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void bufferSizePrintWriterWriteCommits() throws Exception { - String expected = "1234567890"; - when(response.getBufferSize()).thenReturn(expected.length()); + @Test + public void bufferSizePrintWriterWriteCommits() throws Exception { + String expected = "1234567890"; + when(response.getBufferSize()).thenReturn(expected.length()); - response.getWriter().write(expected); + response.getWriter().write(expected); - assertThat(committed).isTrue(); - } + assertThat(committed).isTrue(); + } - @Test - public void bufferSizeCommitsOnce() throws Exception { - String expected = "1234567890"; - when(response.getBufferSize()).thenReturn(expected.length()); + @Test + public void bufferSizeCommitsOnce() throws Exception { + String expected = "1234567890"; + when(response.getBufferSize()).thenReturn(expected.length()); - response.getWriter().write(expected); + response.getWriter().write(expected); - assertThat(committed).isTrue(); + assertThat(committed).isTrue(); - committed = false; + committed = false; - response.getWriter().write(expected); + response.getWriter().write(expected); - assertThat(committed).isFalse(); - } + assertThat(committed).isFalse(); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/web/http/OncePerRequestFilterTests.java b/spring-session/src/test/java/org/springframework/session/web/http/OncePerRequestFilterTests.java index b8e5ac7d..bb90e5cd 100644 --- a/spring-session/src/test/java/org/springframework/session/web/http/OncePerRequestFilterTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/http/OncePerRequestFilterTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.web.http; import org.junit.Before; @@ -20,57 +35,57 @@ import java.util.List; import static org.fest.assertions.Assertions.*; public class OncePerRequestFilterTests { - private MockHttpServletRequest request; - private MockHttpServletResponse response; - private MockFilterChain chain; - private OncePerRequestFilter filter; - private HttpServlet servlet; + private MockHttpServletRequest request; + private MockHttpServletResponse response; + private MockFilterChain chain; + private OncePerRequestFilter filter; + private HttpServlet servlet; - private List invocations; + private List invocations; - @Before - @SuppressWarnings("serial") - public void setup() { - servlet = new HttpServlet() {}; - request = new MockHttpServletRequest(); - response = new MockHttpServletResponse(); - chain = new MockFilterChain(); - invocations = new ArrayList(); - filter = new OncePerRequestFilter() { - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - invocations.add(this); - filterChain.doFilter(request, response); - } - }; - } + @Before + @SuppressWarnings("serial") + public void setup() { + servlet = new HttpServlet() {}; + request = new MockHttpServletRequest(); + response = new MockHttpServletResponse(); + chain = new MockFilterChain(); + invocations = new ArrayList(); + filter = new OncePerRequestFilter() { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + invocations.add(this); + filterChain.doFilter(request, response); + } + }; + } - @Test - public void doFilterOnce() throws ServletException, IOException { - filter.doFilter(request, response, chain); + @Test + public void doFilterOnce() throws ServletException, IOException { + filter.doFilter(request, response, chain); - assertThat(invocations).containsOnly(filter); - } + assertThat(invocations).containsOnly(filter); + } - @Test - public void doFilterMultiOnlyIvokesOnce() throws ServletException, IOException { - filter.doFilter(request, response, new MockFilterChain(servlet, filter)); + @Test + public void doFilterMultiOnlyIvokesOnce() throws ServletException, IOException { + filter.doFilter(request, response, new MockFilterChain(servlet, filter)); - assertThat(invocations).containsOnly(filter); - } + assertThat(invocations).containsOnly(filter); + } - @Test - public void doFilterOtherSubclassInvoked() throws ServletException, IOException { - OncePerRequestFilter filter2 = new OncePerRequestFilter() { - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - invocations.add(this); - filterChain.doFilter(request, response); - } - }; - filter.doFilter(request, response, new MockFilterChain(servlet, filter2)); + @Test + public void doFilterOtherSubclassInvoked() throws ServletException, IOException { + OncePerRequestFilter filter2 = new OncePerRequestFilter() { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + invocations.add(this); + filterChain.doFilter(request, response); + } + }; + filter.doFilter(request, response, new MockFilterChain(servlet, filter2)); - assertThat(invocations).containsOnly(filter, filter2); - } + assertThat(invocations).containsOnly(filter, filter2); + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/web/http/SessionRepositoryFilterTests.java b/spring-session/src/test/java/org/springframework/session/web/http/SessionRepositoryFilterTests.java index c53ac0a0..d8ce8f62 100644 --- a/spring-session/src/test/java/org/springframework/session/web/http/SessionRepositoryFilterTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/http/SessionRepositoryFilterTests.java @@ -1,3 +1,18 @@ +/* + * Copyright 2002-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 + * + * 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 org.springframework.session.web.http; import static org.fest.assertions.Assertions.assertThat; @@ -40,1014 +55,1014 @@ import org.springframework.session.SessionRepository; @RunWith(MockitoJUnitRunner.class) @SuppressWarnings("deprecation") public class SessionRepositoryFilterTests { - @Mock - private HttpSessionStrategy strategy; - - private SessionRepository sessionRepository; - - private SessionRepositoryFilter filter; - - private MockHttpServletRequest request; - - private MockHttpServletResponse response; - - private MockFilterChain chain; - - @Before - public void setup() throws Exception { - sessionRepository = new MapSessionRepository(); - filter = new SessionRepositoryFilter(sessionRepository); - request = new MockHttpServletRequest(); - response = new MockHttpServletResponse(); - chain = new MockFilterChain(); - } - - @Test - public void doFilterCreateDate() throws Exception { - final String CREATE_ATTR = "create"; - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - long creationTime = wrappedRequest.getSession().getCreationTime(); - long now = System.currentTimeMillis(); - assertThat(now - creationTime).isGreaterThanOrEqualTo(0).isLessThan(5000); - request.setAttribute(CREATE_ATTR, creationTime); - } - }); - - final long expectedCreationTime = (Long) request.getAttribute(CREATE_ATTR); - Thread.sleep(50L); - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - long creationTime = wrappedRequest.getSession().getCreationTime(); - - assertThat(creationTime).isEqualTo(expectedCreationTime); - } - }); - } - - @Test - public void doFilterLastAccessedTime() throws Exception { - final String ACCESS_ATTR = "create"; - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - long lastAccessed = wrappedRequest.getSession().getLastAccessedTime(); - assertThat(lastAccessed).isEqualTo(wrappedRequest.getSession().getCreationTime()); - request.setAttribute(ACCESS_ATTR, lastAccessed); - } - }); - - Thread.sleep(10L); - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - long lastAccessed = wrappedRequest.getSession().getLastAccessedTime(); - - assertThat(lastAccessed).isGreaterThan(wrappedRequest.getSession().getCreationTime()); - } - }); - } - - @Test - public void doFilterId() throws Exception { - final String ID_ATTR = "create"; - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - String id = wrappedRequest.getSession().getId(); - assertThat(id).isNotNull(); - assertThat(wrappedRequest.getSession().getId()).isEqualTo(id); - request.setAttribute(ID_ATTR, id); - } - }); - - final String id = (String) request.getAttribute(ID_ATTR); - assertThat(getSessionCookie().getValue()).isEqualTo(id); - setSessionCookie(id); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getId()).isEqualTo(id); - } - }); - } - - @Test - public void doFilterIdChanges() throws Exception { - final String ID_ATTR = "create"; - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - String id = wrappedRequest.getSession().getId(); - request.setAttribute(ID_ATTR, id); - } - }); - - final String id = (String) request.getAttribute(ID_ATTR); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getId()).isNotEqualTo(id); - } - }); - } - - @Test - public void doFilterServletContext() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - ServletContext context = wrappedRequest.getSession().getServletContext(); - assertThat(context).isSameAs(wrappedRequest.getServletContext()); - } - }); - } - - @Test - public void doFilterMaxInactiveIntervalDefault() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - int interval = wrappedRequest.getSession().getMaxInactiveInterval(); - assertThat(interval).isEqualTo(1800); // 30 minute default (same as Tomcat) - } - }); - } - - @Test - public void doFilterMaxInactiveIntervalOverride() throws Exception { - final int interval = 600; - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession().setMaxInactiveInterval(interval); - assertThat(wrappedRequest.getSession().getMaxInactiveInterval()).isEqualTo(interval); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getMaxInactiveInterval()).isEqualTo(interval); - } - }); - } - - @Test - public void doFilterAttribute() throws Exception { - final String ATTR = "ATTR"; - final String VALUE = "VALUE"; - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession().setAttribute(ATTR, VALUE); - assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isEqualTo(VALUE); - assertThat(Collections.list(wrappedRequest.getSession().getAttributeNames())).containsOnly(ATTR); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isEqualTo(VALUE); - assertThat(Collections.list(wrappedRequest.getSession().getAttributeNames())).containsOnly(ATTR); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isEqualTo(VALUE); - - wrappedRequest.getSession().removeAttribute(ATTR); - - assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isNull(); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isNull(); - } - }); - } - - @Test - public void doFilterValue() throws Exception { - final String ATTR = "ATTR"; - final String VALUE = "VALUE"; - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession().putValue(ATTR, VALUE); - assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE); - assertThat(Arrays.asList(wrappedRequest.getSession().getValueNames())).containsOnly(ATTR); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE); - assertThat(Arrays.asList(wrappedRequest.getSession().getValueNames())).containsOnly(ATTR); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE); - - wrappedRequest.getSession().removeValue(ATTR); - - assertThat(wrappedRequest.getSession().getValue(ATTR)).isNull(); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getValue(ATTR)).isNull(); - } - }); - } - - @Test - public void doFilterIsNewTrue() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().isNew()).isTrue(); - assertThat(wrappedRequest.getSession().isNew()).isTrue(); - } - }); - } - - @Test - public void doFilterIsNewFalse() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(); - } - }); - - setupSession(); - response.reset(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().isNew()).isFalse(); - } - }); - - assertThat(response.getCookie("SESSION")).isNull(); - } - - @Test - public void doFilterSetsCookieIfChanged() throws Exception { - sessionRepository = new MapSessionRepository() { - @Override - public ExpiringSession getSession(String id) { - return createSession(); - } - }; - filter = new SessionRepositoryFilter(sessionRepository); - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(); - } - }); - assertThat(response.getCookie("SESSION")).isNotNull(); - - setupSession(); - - response.reset(); - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().isNew()).isFalse(); - } - }); - - assertThat(response.getCookie("SESSION")).isNotNull(); - } - - @Test - public void doFilterGetSessionNew() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(); - } - }); - - assertNewSession(); - } - - @Test - public void doFilterGetSessionTrueNew() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(true); - } - }); - - assertNewSession(); - } - - @Test - public void doFilterGetSessionFalseNew() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(false); - } - }); - - assertNoSession(); - } - - @Test - public void doFilterIsRequestedValidSessionTrue() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(); - } - }); - - setupSession(); - request.setRequestedSessionIdValid(false); // ensure we are using wrapped request - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.isRequestedSessionIdValid()).isTrue(); - } - }); - } - - // gh-142, gh-153 - @Test - public void doFilterIsRequestedValidSessionFalseInvalidId() throws Exception { - setSessionCookie("invalid"); - request.setRequestedSessionIdValid(true); // ensure we are using wrapped request - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.isRequestedSessionIdValid()).isFalse(); - } - }); - } - - @Test - public void doFilterIsRequestedValidSessionFalse() throws Exception { - request.setRequestedSessionIdValid(true); // ensure we are using wrapped request - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.isRequestedSessionIdValid()).isFalse(); - } - }); - } - - @Test - public void doFilterGetSessionGetSessionFalse() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(); - } - }); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession(false)).isNotNull(); - } - }); - } - - @Test - public void doFilterCookieSecuritySettings() throws Exception { - request.setSecure(true); - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(); - } - }); - - Cookie session = getSessionCookie(); - assertThat(session.isHttpOnly()).describedAs("Session Cookie should be HttpOnly").isTrue(); - assertThat(session.getSecure()).describedAs("Session Cookie should be marked as Secure").isTrue(); - } - - @Test - public void doFilterSessionContext() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSessionContext sessionContext = wrappedRequest.getSession().getSessionContext(); - assertThat(sessionContext).isNotNull(); - assertThat(sessionContext.getSession("a")).isNull(); - assertThat(sessionContext.getIds()).isNotNull(); - assertThat(sessionContext.getIds().hasMoreElements()).isFalse(); - - try { - sessionContext.getIds().nextElement(); - fail("Expected Exception"); - } catch(NoSuchElementException success) {} - } - }); - } - - - - // --- saving - - @Test - public void doFilterGetAttr() throws Exception { - final String ATTR_NAME = "attr"; - final String ATTR_VALUE = "value"; - final String ATTR_NAME2 = "attr2"; - final String ATTR_VALUE2 = "value2"; - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession().setAttribute(ATTR_NAME, ATTR_VALUE); - wrappedRequest.getSession().setAttribute(ATTR_NAME2, ATTR_VALUE2); - } - }); - - assertNewSession(); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME)).isEqualTo(ATTR_VALUE); - assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME2)).isEqualTo(ATTR_VALUE2); - } - }); - } - - // --- invalidate - - @Test - public void doFilterInvalidateInvalidateIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.invalidate(); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateCreationTimeIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.getCreationTime(); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateAttributeIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.getAttribute("attr"); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateValueIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.getValue("attr"); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateAttributeNamesIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.getAttributeNames(); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateValueNamesIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.getValueNames(); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateSetAttributeIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.setAttribute("a", "b"); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidatePutValueIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.putValue("a", "b"); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateRemoveAttributeIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.removeAttribute("name"); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateRemoveValueIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.removeValue("name"); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateNewIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.isNew(); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateLastAccessedTimeIllegalState() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - try { - session.getLastAccessedTime(); - fail("Expected Exception"); - } catch(IllegalStateException success) {} - } - }); - } - - @Test - public void doFilterInvalidateId() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - // no exception - session.getId(); - } - }); - } - - @Test - public void doFilterInvalidateServletContext() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - - // no exception - session.getServletContext(); - } - }); - } - - @Test - public void doFilterInvalidateSessionContext() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - - // no exception - session.getSessionContext(); - } - }); - } - - @Test - public void doFilterInvalidateMaxInteractiveInterval() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - HttpSession session = wrappedRequest.getSession(); - session.invalidate(); - - // no exception - session.getMaxInactiveInterval(); - session.setMaxInactiveInterval(3600); - } - }); - } - - @Test - public void doFilterInvalidateAndGetSession() throws Exception { - final String ATTR_NAME = "attr"; - final String ATTR_VALUE = "value"; - final String ATTR_NAME2 = "attr2"; - final String ATTR_VALUE2 = "value2"; - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession().setAttribute(ATTR_NAME, ATTR_VALUE); - wrappedRequest.getSession().invalidate(); - wrappedRequest.getSession().setAttribute(ATTR_NAME2, ATTR_VALUE2); - } - }); - - assertNewSession(); - - setupSession(); - - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME)).isNull(); - assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME2)).isEqualTo(ATTR_VALUE2); - } - }); - } - - // --- invalid session ids - - @Test - public void doFilterGetSessionInvalidSessionId() throws Exception { - setSessionCookie("INVALID"); - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(); - } - }); - - assertNewSession(); - } - - @Test - public void doFilterGetSessionTrueInvalidSessionId() throws Exception { - setSessionCookie("INVALID"); - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(true); - } - }); - - assertNewSession(); - } - - @Test - public void doFilterGetSessionFalseInvalidSessionId() throws Exception { - setSessionCookie("INVALID"); - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest) { - wrappedRequest.getSession(false); - } - }); - - assertNoSession(); - } - - // --- commit response saves immediately - - @Test - public void doFilterSendError() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - @Test - public void doFilterSendErrorAndMessage() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error"); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - @Test - public void doFilterSendRedirect() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.sendRedirect("/"); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - @Test - public void doFilterFlushBuffer() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.flushBuffer(); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - @Test - public void doFilterOutputFlush() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.getOutputStream().flush(); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - @Test - public void doFilterOutputClose() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.getOutputStream().close(); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - @Test - public void doFilterWriterFlush() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.getWriter().flush(); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - @Test - public void doFilterWriterClose() throws Exception { - doFilter(new DoInFilter() { - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String id = wrappedRequest.getSession().getId(); - wrappedResponse.getWriter().close(); - assertThat(sessionRepository.getSession(id)).isNotNull(); - } - }); - } - - // --- MultiHttpSessionStrategyAdapter - - @Test - public void doFilterAdapterGetRequestedSessionId() throws Exception { - filter.setHttpSessionStrategy(strategy); - final String expectedId = "MultiHttpSessionStrategyAdapter-requested-id"; - when(strategy.getRequestedSessionId(any(HttpServletRequest.class))).thenReturn(expectedId); - - doFilter(new DoInFilter(){ - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - String actualId = wrappedRequest.getRequestedSessionId(); - assertThat(actualId).isEqualTo(expectedId); - } - }); - } - - @Test - public void doFilterAdapterOnNewSession() throws Exception { - filter.setHttpSessionStrategy(strategy); - - doFilter(new DoInFilter(){ - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - wrappedRequest.getSession(); - } - }); - - HttpServletRequest request = (HttpServletRequest) chain.getRequest(); - Session session = sessionRepository.getSession(request.getSession().getId()); - verify(strategy).onNewSession(eq(session), any(HttpServletRequest.class),any(HttpServletResponse.class)); - } - - @Test - public void doFilterAdapterOnInvalidate() throws Exception { - filter.setHttpSessionStrategy(strategy); - - doFilter(new DoInFilter(){ - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - wrappedRequest.getSession().getId(); - } - }); - - HttpServletRequest request = (HttpServletRequest) chain.getRequest(); - String id = request.getSession().getId(); - when(strategy.getRequestedSessionId(any(HttpServletRequest.class))).thenReturn(id); - - doFilter(new DoInFilter(){ - @Override - public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { - wrappedRequest.getSession().invalidate(); - } - }); - - verify(strategy).onInvalidateSession(any(HttpServletRequest.class),any(HttpServletResponse.class)); - } - - // --- order - - @Test - public void order() { - assertThat(OrderUtils.getOrder(filter.getClass())).isEqualTo(SessionRepositoryFilter.DEFAULT_ORDER); - } - - // We want the filter to work without any dependencies on Spring - @Test(expected = ClassCastException.class) - @SuppressWarnings("unused") - public void doesNotImplementOrdered() { - Ordered o = (Ordered) filter; - } - - // --- helper methods - - private void assertNewSession() { - Cookie cookie = getSessionCookie(); - assertThat(cookie).isNotNull(); - assertThat(cookie.getMaxAge()).isEqualTo(-1); - assertThat(cookie.getValue()).isNotEqualTo("INVALID"); - assertThat(cookie.isHttpOnly()).describedAs("Cookie is expected to be HTTP Only").isTrue(); - assertThat(cookie.getSecure()).describedAs("Cookie secured is expected to be " + request.isSecure()).isEqualTo(request.isSecure()); - assertThat(request.getSession(false)).describedAs("The original HttpServletRequest HttpSession should be null").isNull(); - } - - private void assertNoSession() { - Cookie cookie = getSessionCookie(); - assertThat(cookie).isNull(); - assertThat(request.getSession(false)).describedAs("The original HttpServletRequest HttpSession should be null").isNull(); - } - - private Cookie getSessionCookie() { - return response.getCookie("SESSION"); - } - - private void setSessionCookie(String sessionId) { - request.setCookies(new Cookie[]{new Cookie("SESSION", sessionId)}); - } - - private void setupSession() { - setSessionCookie(getSessionCookie().getValue()); - } - - @SuppressWarnings("serial") - private void doFilter(final DoInFilter doInFilter) throws ServletException, IOException { - chain = new MockFilterChain(new HttpServlet() {}, new OncePerRequestFilter() { - @Override - protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { - doInFilter.doFilter(request, response); - } - }); - filter.doFilter(request, response, chain); - } - - abstract class DoInFilter { - void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws ServletException, IOException { - doFilter(wrappedRequest); - } - void doFilter(HttpServletRequest wrappedRequest) {} - } + @Mock + private HttpSessionStrategy strategy; + + private SessionRepository sessionRepository; + + private SessionRepositoryFilter filter; + + private MockHttpServletRequest request; + + private MockHttpServletResponse response; + + private MockFilterChain chain; + + @Before + public void setup() throws Exception { + sessionRepository = new MapSessionRepository(); + filter = new SessionRepositoryFilter(sessionRepository); + request = new MockHttpServletRequest(); + response = new MockHttpServletResponse(); + chain = new MockFilterChain(); + } + + @Test + public void doFilterCreateDate() throws Exception { + final String CREATE_ATTR = "create"; + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + long creationTime = wrappedRequest.getSession().getCreationTime(); + long now = System.currentTimeMillis(); + assertThat(now - creationTime).isGreaterThanOrEqualTo(0).isLessThan(5000); + request.setAttribute(CREATE_ATTR, creationTime); + } + }); + + final long expectedCreationTime = (Long) request.getAttribute(CREATE_ATTR); + Thread.sleep(50L); + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + long creationTime = wrappedRequest.getSession().getCreationTime(); + + assertThat(creationTime).isEqualTo(expectedCreationTime); + } + }); + } + + @Test + public void doFilterLastAccessedTime() throws Exception { + final String ACCESS_ATTR = "create"; + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + long lastAccessed = wrappedRequest.getSession().getLastAccessedTime(); + assertThat(lastAccessed).isEqualTo(wrappedRequest.getSession().getCreationTime()); + request.setAttribute(ACCESS_ATTR, lastAccessed); + } + }); + + Thread.sleep(10L); + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + long lastAccessed = wrappedRequest.getSession().getLastAccessedTime(); + + assertThat(lastAccessed).isGreaterThan(wrappedRequest.getSession().getCreationTime()); + } + }); + } + + @Test + public void doFilterId() throws Exception { + final String ID_ATTR = "create"; + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + String id = wrappedRequest.getSession().getId(); + assertThat(id).isNotNull(); + assertThat(wrappedRequest.getSession().getId()).isEqualTo(id); + request.setAttribute(ID_ATTR, id); + } + }); + + final String id = (String) request.getAttribute(ID_ATTR); + assertThat(getSessionCookie().getValue()).isEqualTo(id); + setSessionCookie(id); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getId()).isEqualTo(id); + } + }); + } + + @Test + public void doFilterIdChanges() throws Exception { + final String ID_ATTR = "create"; + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + String id = wrappedRequest.getSession().getId(); + request.setAttribute(ID_ATTR, id); + } + }); + + final String id = (String) request.getAttribute(ID_ATTR); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getId()).isNotEqualTo(id); + } + }); + } + + @Test + public void doFilterServletContext() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + ServletContext context = wrappedRequest.getSession().getServletContext(); + assertThat(context).isSameAs(wrappedRequest.getServletContext()); + } + }); + } + + @Test + public void doFilterMaxInactiveIntervalDefault() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + int interval = wrappedRequest.getSession().getMaxInactiveInterval(); + assertThat(interval).isEqualTo(1800); // 30 minute default (same as Tomcat) + } + }); + } + + @Test + public void doFilterMaxInactiveIntervalOverride() throws Exception { + final int interval = 600; + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession().setMaxInactiveInterval(interval); + assertThat(wrappedRequest.getSession().getMaxInactiveInterval()).isEqualTo(interval); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getMaxInactiveInterval()).isEqualTo(interval); + } + }); + } + + @Test + public void doFilterAttribute() throws Exception { + final String ATTR = "ATTR"; + final String VALUE = "VALUE"; + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession().setAttribute(ATTR, VALUE); + assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isEqualTo(VALUE); + assertThat(Collections.list(wrappedRequest.getSession().getAttributeNames())).containsOnly(ATTR); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isEqualTo(VALUE); + assertThat(Collections.list(wrappedRequest.getSession().getAttributeNames())).containsOnly(ATTR); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isEqualTo(VALUE); + + wrappedRequest.getSession().removeAttribute(ATTR); + + assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isNull(); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getAttribute(ATTR)).isNull(); + } + }); + } + + @Test + public void doFilterValue() throws Exception { + final String ATTR = "ATTR"; + final String VALUE = "VALUE"; + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession().putValue(ATTR, VALUE); + assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE); + assertThat(Arrays.asList(wrappedRequest.getSession().getValueNames())).containsOnly(ATTR); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE); + assertThat(Arrays.asList(wrappedRequest.getSession().getValueNames())).containsOnly(ATTR); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getValue(ATTR)).isEqualTo(VALUE); + + wrappedRequest.getSession().removeValue(ATTR); + + assertThat(wrappedRequest.getSession().getValue(ATTR)).isNull(); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getValue(ATTR)).isNull(); + } + }); + } + + @Test + public void doFilterIsNewTrue() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().isNew()).isTrue(); + assertThat(wrappedRequest.getSession().isNew()).isTrue(); + } + }); + } + + @Test + public void doFilterIsNewFalse() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(); + } + }); + + setupSession(); + response.reset(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().isNew()).isFalse(); + } + }); + + assertThat(response.getCookie("SESSION")).isNull(); + } + + @Test + public void doFilterSetsCookieIfChanged() throws Exception { + sessionRepository = new MapSessionRepository() { + @Override + public ExpiringSession getSession(String id) { + return createSession(); + } + }; + filter = new SessionRepositoryFilter(sessionRepository); + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(); + } + }); + assertThat(response.getCookie("SESSION")).isNotNull(); + + setupSession(); + + response.reset(); + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().isNew()).isFalse(); + } + }); + + assertThat(response.getCookie("SESSION")).isNotNull(); + } + + @Test + public void doFilterGetSessionNew() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(); + } + }); + + assertNewSession(); + } + + @Test + public void doFilterGetSessionTrueNew() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(true); + } + }); + + assertNewSession(); + } + + @Test + public void doFilterGetSessionFalseNew() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(false); + } + }); + + assertNoSession(); + } + + @Test + public void doFilterIsRequestedValidSessionTrue() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(); + } + }); + + setupSession(); + request.setRequestedSessionIdValid(false); // ensure we are using wrapped request + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.isRequestedSessionIdValid()).isTrue(); + } + }); + } + + // gh-142, gh-153 + @Test + public void doFilterIsRequestedValidSessionFalseInvalidId() throws Exception { + setSessionCookie("invalid"); + request.setRequestedSessionIdValid(true); // ensure we are using wrapped request + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.isRequestedSessionIdValid()).isFalse(); + } + }); + } + + @Test + public void doFilterIsRequestedValidSessionFalse() throws Exception { + request.setRequestedSessionIdValid(true); // ensure we are using wrapped request + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.isRequestedSessionIdValid()).isFalse(); + } + }); + } + + @Test + public void doFilterGetSessionGetSessionFalse() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(); + } + }); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession(false)).isNotNull(); + } + }); + } + + @Test + public void doFilterCookieSecuritySettings() throws Exception { + request.setSecure(true); + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(); + } + }); + + Cookie session = getSessionCookie(); + assertThat(session.isHttpOnly()).describedAs("Session Cookie should be HttpOnly").isTrue(); + assertThat(session.getSecure()).describedAs("Session Cookie should be marked as Secure").isTrue(); + } + + @Test + public void doFilterSessionContext() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSessionContext sessionContext = wrappedRequest.getSession().getSessionContext(); + assertThat(sessionContext).isNotNull(); + assertThat(sessionContext.getSession("a")).isNull(); + assertThat(sessionContext.getIds()).isNotNull(); + assertThat(sessionContext.getIds().hasMoreElements()).isFalse(); + + try { + sessionContext.getIds().nextElement(); + fail("Expected Exception"); + } catch(NoSuchElementException success) {} + } + }); + } + + + + // --- saving + + @Test + public void doFilterGetAttr() throws Exception { + final String ATTR_NAME = "attr"; + final String ATTR_VALUE = "value"; + final String ATTR_NAME2 = "attr2"; + final String ATTR_VALUE2 = "value2"; + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession().setAttribute(ATTR_NAME, ATTR_VALUE); + wrappedRequest.getSession().setAttribute(ATTR_NAME2, ATTR_VALUE2); + } + }); + + assertNewSession(); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME)).isEqualTo(ATTR_VALUE); + assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME2)).isEqualTo(ATTR_VALUE2); + } + }); + } + + // --- invalidate + + @Test + public void doFilterInvalidateInvalidateIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.invalidate(); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateCreationTimeIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.getCreationTime(); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateAttributeIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.getAttribute("attr"); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateValueIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.getValue("attr"); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateAttributeNamesIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.getAttributeNames(); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateValueNamesIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.getValueNames(); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateSetAttributeIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.setAttribute("a", "b"); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidatePutValueIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.putValue("a", "b"); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateRemoveAttributeIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.removeAttribute("name"); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateRemoveValueIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.removeValue("name"); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateNewIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.isNew(); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateLastAccessedTimeIllegalState() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + try { + session.getLastAccessedTime(); + fail("Expected Exception"); + } catch(IllegalStateException success) {} + } + }); + } + + @Test + public void doFilterInvalidateId() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + // no exception + session.getId(); + } + }); + } + + @Test + public void doFilterInvalidateServletContext() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + + // no exception + session.getServletContext(); + } + }); + } + + @Test + public void doFilterInvalidateSessionContext() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + + // no exception + session.getSessionContext(); + } + }); + } + + @Test + public void doFilterInvalidateMaxInteractiveInterval() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + HttpSession session = wrappedRequest.getSession(); + session.invalidate(); + + // no exception + session.getMaxInactiveInterval(); + session.setMaxInactiveInterval(3600); + } + }); + } + + @Test + public void doFilterInvalidateAndGetSession() throws Exception { + final String ATTR_NAME = "attr"; + final String ATTR_VALUE = "value"; + final String ATTR_NAME2 = "attr2"; + final String ATTR_VALUE2 = "value2"; + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession().setAttribute(ATTR_NAME, ATTR_VALUE); + wrappedRequest.getSession().invalidate(); + wrappedRequest.getSession().setAttribute(ATTR_NAME2, ATTR_VALUE2); + } + }); + + assertNewSession(); + + setupSession(); + + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME)).isNull(); + assertThat(wrappedRequest.getSession().getAttribute(ATTR_NAME2)).isEqualTo(ATTR_VALUE2); + } + }); + } + + // --- invalid session ids + + @Test + public void doFilterGetSessionInvalidSessionId() throws Exception { + setSessionCookie("INVALID"); + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(); + } + }); + + assertNewSession(); + } + + @Test + public void doFilterGetSessionTrueInvalidSessionId() throws Exception { + setSessionCookie("INVALID"); + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(true); + } + }); + + assertNewSession(); + } + + @Test + public void doFilterGetSessionFalseInvalidSessionId() throws Exception { + setSessionCookie("INVALID"); + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest) { + wrappedRequest.getSession(false); + } + }); + + assertNoSession(); + } + + // --- commit response saves immediately + + @Test + public void doFilterSendError() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + @Test + public void doFilterSendErrorAndMessage() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Error"); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + @Test + public void doFilterSendRedirect() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.sendRedirect("/"); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + @Test + public void doFilterFlushBuffer() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.flushBuffer(); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + @Test + public void doFilterOutputFlush() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.getOutputStream().flush(); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + @Test + public void doFilterOutputClose() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.getOutputStream().close(); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + @Test + public void doFilterWriterFlush() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.getWriter().flush(); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + @Test + public void doFilterWriterClose() throws Exception { + doFilter(new DoInFilter() { + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String id = wrappedRequest.getSession().getId(); + wrappedResponse.getWriter().close(); + assertThat(sessionRepository.getSession(id)).isNotNull(); + } + }); + } + + // --- MultiHttpSessionStrategyAdapter + + @Test + public void doFilterAdapterGetRequestedSessionId() throws Exception { + filter.setHttpSessionStrategy(strategy); + final String expectedId = "MultiHttpSessionStrategyAdapter-requested-id"; + when(strategy.getRequestedSessionId(any(HttpServletRequest.class))).thenReturn(expectedId); + + doFilter(new DoInFilter(){ + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + String actualId = wrappedRequest.getRequestedSessionId(); + assertThat(actualId).isEqualTo(expectedId); + } + }); + } + + @Test + public void doFilterAdapterOnNewSession() throws Exception { + filter.setHttpSessionStrategy(strategy); + + doFilter(new DoInFilter(){ + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + wrappedRequest.getSession(); + } + }); + + HttpServletRequest request = (HttpServletRequest) chain.getRequest(); + Session session = sessionRepository.getSession(request.getSession().getId()); + verify(strategy).onNewSession(eq(session), any(HttpServletRequest.class),any(HttpServletResponse.class)); + } + + @Test + public void doFilterAdapterOnInvalidate() throws Exception { + filter.setHttpSessionStrategy(strategy); + + doFilter(new DoInFilter(){ + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + wrappedRequest.getSession().getId(); + } + }); + + HttpServletRequest request = (HttpServletRequest) chain.getRequest(); + String id = request.getSession().getId(); + when(strategy.getRequestedSessionId(any(HttpServletRequest.class))).thenReturn(id); + + doFilter(new DoInFilter(){ + @Override + public void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws IOException { + wrappedRequest.getSession().invalidate(); + } + }); + + verify(strategy).onInvalidateSession(any(HttpServletRequest.class),any(HttpServletResponse.class)); + } + + // --- order + + @Test + public void order() { + assertThat(OrderUtils.getOrder(filter.getClass())).isEqualTo(SessionRepositoryFilter.DEFAULT_ORDER); + } + + // We want the filter to work without any dependencies on Spring + @Test(expected = ClassCastException.class) + @SuppressWarnings("unused") + public void doesNotImplementOrdered() { + Ordered o = (Ordered) filter; + } + + // --- helper methods + + private void assertNewSession() { + Cookie cookie = getSessionCookie(); + assertThat(cookie).isNotNull(); + assertThat(cookie.getMaxAge()).isEqualTo(-1); + assertThat(cookie.getValue()).isNotEqualTo("INVALID"); + assertThat(cookie.isHttpOnly()).describedAs("Cookie is expected to be HTTP Only").isTrue(); + assertThat(cookie.getSecure()).describedAs("Cookie secured is expected to be " + request.isSecure()).isEqualTo(request.isSecure()); + assertThat(request.getSession(false)).describedAs("The original HttpServletRequest HttpSession should be null").isNull(); + } + + private void assertNoSession() { + Cookie cookie = getSessionCookie(); + assertThat(cookie).isNull(); + assertThat(request.getSession(false)).describedAs("The original HttpServletRequest HttpSession should be null").isNull(); + } + + private Cookie getSessionCookie() { + return response.getCookie("SESSION"); + } + + private void setSessionCookie(String sessionId) { + request.setCookies(new Cookie[]{new Cookie("SESSION", sessionId)}); + } + + private void setupSession() { + setSessionCookie(getSessionCookie().getValue()); + } + + @SuppressWarnings("serial") + private void doFilter(final DoInFilter doInFilter) throws ServletException, IOException { + chain = new MockFilterChain(new HttpServlet() {}, new OncePerRequestFilter() { + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + doInFilter.doFilter(request, response); + } + }); + filter.doFilter(request, response, chain); + } + + abstract class DoInFilter { + void doFilter(HttpServletRequest wrappedRequest, HttpServletResponse wrappedResponse) throws ServletException, IOException { + doFilter(wrappedRequest); + } + void doFilter(HttpServletRequest wrappedRequest) {} + } } \ No newline at end of file diff --git a/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactoryTests.java b/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactoryTests.java index b54fe093..cb63d0bd 100644 --- a/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactoryTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketConnectHandlerDecoratorFactoryTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -33,44 +33,44 @@ import org.springframework.web.socket.WebSocketSession; @RunWith(MockitoJUnitRunner.class) public class WebSocketConnectHandlerDecoratorFactoryTests { - @Mock - ApplicationEventPublisher eventPublisher; - @Mock - WebSocketHandler delegate; - @Mock - WebSocketSession session; - @Captor - ArgumentCaptor event; + @Mock + ApplicationEventPublisher eventPublisher; + @Mock + WebSocketHandler delegate; + @Mock + WebSocketSession session; + @Captor + ArgumentCaptor event; - WebSocketConnectHandlerDecoratorFactory factory; + WebSocketConnectHandlerDecoratorFactory factory; - @Before - public void setup() { - factory = new WebSocketConnectHandlerDecoratorFactory(eventPublisher); - } + @Before + public void setup() { + factory = new WebSocketConnectHandlerDecoratorFactory(eventPublisher); + } - @Test(expected = IllegalArgumentException.class) - public void constructorNullEventPublisher() { - new WebSocketConnectHandlerDecoratorFactory(null); - } + @Test(expected = IllegalArgumentException.class) + public void constructorNullEventPublisher() { + new WebSocketConnectHandlerDecoratorFactory(null); + } - @Test - public void decorateAfterConnectionEstablished() throws Exception { - WebSocketHandler decorated = factory.decorate(delegate); + @Test + public void decorateAfterConnectionEstablished() throws Exception { + WebSocketHandler decorated = factory.decorate(delegate); - decorated.afterConnectionEstablished(session); + decorated.afterConnectionEstablished(session); - verify(eventPublisher).publishEvent(event.capture()); - assertThat(event.getValue().getWebSocketSession()).isSameAs(session); - } + verify(eventPublisher).publishEvent(event.capture()); + assertThat(event.getValue().getWebSocketSession()).isSameAs(session); + } - @Test - public void decorateAfterConnectionEstablishedEventError() throws Exception { - WebSocketHandler decorated = factory.decorate(delegate); - doThrow(new IllegalStateException("Test throw on publishEvent")).when(eventPublisher).publishEvent(any(ApplicationEvent.class)); + @Test + public void decorateAfterConnectionEstablishedEventError() throws Exception { + WebSocketHandler decorated = factory.decorate(delegate); + doThrow(new IllegalStateException("Test throw on publishEvent")).when(eventPublisher).publishEvent(any(ApplicationEvent.class)); - decorated.afterConnectionEstablished(session); + decorated.afterConnectionEstablished(session); - verify(eventPublisher).publishEvent(any(SessionConnectEvent.class)); - } + verify(eventPublisher).publishEvent(any(SessionConnectEvent.class)); + } } diff --git a/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketRegistryListenerTests.java b/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketRegistryListenerTests.java index 5fdf0796..36e0bc18 100644 --- a/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketRegistryListenerTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/socket/handler/WebSocketRegistryListenerTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -16,7 +16,10 @@ package org.springframework.session.web.socket.handler; import static org.fest.assertions.Assertions.assertThat; -import static org.mockito.Mockito.*; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; import java.security.Principal; import java.util.HashMap; @@ -26,7 +29,6 @@ import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.internal.util.reflection.Whitebox; import org.mockito.runners.MockitoJUnitRunner; import org.springframework.messaging.Message; import org.springframework.messaging.MessageHeaders; @@ -41,115 +43,116 @@ import org.springframework.web.socket.messaging.SessionDisconnectEvent; @RunWith(MockitoJUnitRunner.class) public class WebSocketRegistryListenerTests { - @Mock - WebSocketSession wsSession; - @Mock - WebSocketSession wsSession2; - @Mock - Message message; - @Mock - Principal principal; + @Mock + WebSocketSession wsSession; + @Mock + WebSocketSession wsSession2; + @Mock + Message message; + @Mock + Principal principal; - SessionConnectEvent connect; + SessionConnectEvent connect; - SessionConnectEvent connect2; + SessionConnectEvent connect2; - SessionDisconnectEvent disconnect; + SessionDisconnectEvent disconnect; - SessionDestroyedEvent destroyed; + SessionDestroyedEvent destroyed; - Map attributes; + Map attributes; - String sessionId; + String sessionId; - WebSocketRegistryListener listener; + WebSocketRegistryListener listener; - @Before - public void setup() { - sessionId = "session-id"; - attributes = new HashMap(); - SessionRepositoryMessageInterceptor.setSessionId(attributes, sessionId); + @Before + public void setup() { + sessionId = "session-id"; + attributes = new HashMap(); + SessionRepositoryMessageInterceptor.setSessionId(attributes, sessionId); - when(wsSession.getAttributes()).thenReturn(attributes); - when(wsSession.getPrincipal()).thenReturn(principal); - when(wsSession.getId()).thenReturn("wsSession-id"); + when(wsSession.getAttributes()).thenReturn(attributes); + when(wsSession.getPrincipal()).thenReturn(principal); + when(wsSession.getId()).thenReturn("wsSession-id"); - when(wsSession2.getAttributes()).thenReturn(attributes); - when(wsSession2.getPrincipal()).thenReturn(principal); - when(wsSession2.getId()).thenReturn("wsSession-id2"); + when(wsSession2.getAttributes()).thenReturn(attributes); + when(wsSession2.getPrincipal()).thenReturn(principal); + when(wsSession2.getId()).thenReturn("wsSession-id2"); - Map headers = new HashMap(); - headers.put(SimpMessageHeaderAccessor.SESSION_ATTRIBUTES, attributes); - when(message.getHeaders()).thenReturn(new MessageHeaders(headers)); + Map headers = new HashMap(); + headers.put(SimpMessageHeaderAccessor.SESSION_ATTRIBUTES, attributes); + when(message.getHeaders()).thenReturn(new MessageHeaders(headers)); - listener = new WebSocketRegistryListener(); - connect = new SessionConnectEvent(listener,wsSession); - connect2 = new SessionConnectEvent(listener,wsSession2); - disconnect = new SessionDisconnectEvent(listener, message, wsSession.getId(), CloseStatus.NORMAL); - destroyed = new SessionDestroyedEvent(listener, sessionId); - } + listener = new WebSocketRegistryListener(); + connect = new SessionConnectEvent(listener,wsSession); + connect2 = new SessionConnectEvent(listener,wsSession2); + disconnect = new SessionDisconnectEvent(listener, message, wsSession.getId(), CloseStatus.NORMAL); + destroyed = new SessionDestroyedEvent(listener, sessionId); + } - @Test - public void onApplicationEventConnectSessionDestroyed() throws Exception { - listener.onApplicationEvent(connect); + @Test + public void onApplicationEventConnectSessionDestroyed() throws Exception { + listener.onApplicationEvent(connect); - listener.onApplicationEvent(destroyed); + listener.onApplicationEvent(destroyed); - verify(wsSession).close(WebSocketRegistryListener.SESSION_EXPIRED_STATUS); - } + verify(wsSession).close(WebSocketRegistryListener.SESSION_EXPIRED_STATUS); + } - @Test - public void onApplicationEventConnectSessionDestroyedNullPrincipal() throws Exception { - when(wsSession.getPrincipal()).thenReturn(null); - listener.onApplicationEvent(connect); + @Test + public void onApplicationEventConnectSessionDestroyedNullPrincipal() throws Exception { + when(wsSession.getPrincipal()).thenReturn(null); + listener.onApplicationEvent(connect); - listener.onApplicationEvent(destroyed); + listener.onApplicationEvent(destroyed); - verify(wsSession,times(0)).close(any(CloseStatus.class)); - } + verify(wsSession,times(0)).close(any(CloseStatus.class)); + } - @Test - public void onApplicationEventConnectDisconnect() throws Exception { - listener.onApplicationEvent(connect); - listener.onApplicationEvent(disconnect); + @Test + public void onApplicationEventConnectDisconnect() throws Exception { + listener.onApplicationEvent(connect); + listener.onApplicationEvent(disconnect); - listener.onApplicationEvent(destroyed); + listener.onApplicationEvent(destroyed); - verify(wsSession,times(0)).close(any(CloseStatus.class)); - } + verify(wsSession,times(0)).close(any(CloseStatus.class)); + } - // gh-76 - @Test - public void onApplicationEventConnectDisconnectCleanup() { - listener.onApplicationEvent(connect); + // gh-76 + @Test + @SuppressWarnings("unchecked") + public void onApplicationEventConnectDisconnectCleanup() { + listener.onApplicationEvent(connect); - listener.onApplicationEvent(disconnect); + listener.onApplicationEvent(disconnect); - Map> httpSessionIdToWsSessions = - (Map>) ReflectionTestUtils.getField(listener, "httpSessionIdToWsSessions"); - assertThat(httpSessionIdToWsSessions).isEmpty(); - } + Map> httpSessionIdToWsSessions = + (Map>) ReflectionTestUtils.getField(listener, "httpSessionIdToWsSessions"); + assertThat(httpSessionIdToWsSessions).isEmpty(); + } - @Test - public void onApplicationEventConnectDisconnectNullSession() throws Exception { - listener.onApplicationEvent(connect); - attributes.clear(); + @Test + public void onApplicationEventConnectDisconnectNullSession() throws Exception { + listener.onApplicationEvent(connect); + attributes.clear(); - listener.onApplicationEvent(disconnect); + listener.onApplicationEvent(disconnect); - // no exception - } + // no exception + } - @Test - public void onApplicationEventConnectConnectDisonnect() throws Exception { - listener.onApplicationEvent(connect); - listener.onApplicationEvent(connect2); - listener.onApplicationEvent(disconnect); + @Test + public void onApplicationEventConnectConnectDisonnect() throws Exception { + listener.onApplicationEvent(connect); + listener.onApplicationEvent(connect2); + listener.onApplicationEvent(disconnect); - listener.onApplicationEvent(destroyed); + listener.onApplicationEvent(destroyed); - verify(wsSession2).close(WebSocketRegistryListener.SESSION_EXPIRED_STATUS); - verify(wsSession,times(0)).close(any(CloseStatus.class)); - } + verify(wsSession2).close(WebSocketRegistryListener.SESSION_EXPIRED_STATUS); + verify(wsSession,times(0)).close(any(CloseStatus.class)); + } } diff --git a/spring-session/src/test/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptorTests.java b/spring-session/src/test/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptorTests.java index e37a8e51..3ee4e51b 100644 --- a/spring-session/src/test/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptorTests.java +++ b/spring-session/src/test/java/org/springframework/session/web/socket/server/SessionRepositoryMessageInterceptorTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2013 the original author or authors. + * Copyright 2002-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. @@ -43,214 +43,214 @@ import org.springframework.session.SessionRepository; @RunWith(MockitoJUnitRunner.class) public class SessionRepositoryMessageInterceptorTests { - @Mock - SessionRepository sessionRepository; - @Mock - MessageChannel channel; - @Mock - ExpiringSession session; + @Mock + SessionRepository sessionRepository; + @Mock + MessageChannel channel; + @Mock + ExpiringSession session; - Message createMessage; + Message createMessage; - SimpMessageHeaderAccessor headers; + SimpMessageHeaderAccessor headers; - SessionRepositoryMessageInterceptor interceptor; + SessionRepositoryMessageInterceptor interceptor; - @Before - public void setup() { - interceptor = new SessionRepositoryMessageInterceptor(sessionRepository); - headers = SimpMessageHeaderAccessor.create(); - headers.setSessionId("session"); - headers.setSessionAttributes(new HashMap()); - setMessageType(SimpMessageType.MESSAGE); - String sessionId = "http-session"; - setSessionId(sessionId); - when(sessionRepository.getSession(sessionId)).thenReturn(session); - } + @Before + public void setup() { + interceptor = new SessionRepositoryMessageInterceptor(sessionRepository); + headers = SimpMessageHeaderAccessor.create(); + headers.setSessionId("session"); + headers.setSessionAttributes(new HashMap()); + setMessageType(SimpMessageType.MESSAGE); + String sessionId = "http-session"; + setSessionId(sessionId); + when(sessionRepository.getSession(sessionId)).thenReturn(session); + } - @Test(expected = IllegalArgumentException.class) - public void preSendconstructorNullRepository() { - new SessionRepositoryMessageInterceptor(null); - } + @Test(expected = IllegalArgumentException.class) + public void preSendconstructorNullRepository() { + new SessionRepositoryMessageInterceptor(null); + } - @Test - public void preSendNullMessage() { - assertThat(interceptor.preSend(null, channel)).isNull(); - } + @Test + public void preSendNullMessage() { + assertThat(interceptor.preSend(null, channel)).isNull(); + } - @Test - public void preSendConnectAckDoesNotInvokeSessionRepository() { - setMessageType(SimpMessageType.CONNECT_ACK); + @Test + public void preSendConnectAckDoesNotInvokeSessionRepository() { + setMessageType(SimpMessageType.CONNECT_ACK); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test - public void preSendHeartbeatDoesNotInvokeSessionRepository() { - setMessageType(SimpMessageType.HEARTBEAT); + @Test + public void preSendHeartbeatDoesNotInvokeSessionRepository() { + setMessageType(SimpMessageType.HEARTBEAT); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test - public void preSendDisconnectDoesNotInvokeSessionRepository() { - setMessageType(SimpMessageType.DISCONNECT); + @Test + public void preSendDisconnectDoesNotInvokeSessionRepository() { + setMessageType(SimpMessageType.DISCONNECT); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test - public void preSendOtherDoesNotInvokeSessionRepository() { - setMessageType(SimpMessageType.OTHER); + @Test + public void preSendOtherDoesNotInvokeSessionRepository() { + setMessageType(SimpMessageType.OTHER); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test(expected = IllegalArgumentException.class) - public void setMatchingMessageTypesNull() { - interceptor.setMatchingMessageTypes(null); - } + @Test(expected = IllegalArgumentException.class) + public void setMatchingMessageTypesNull() { + interceptor.setMatchingMessageTypes(null); + } - @Test(expected = IllegalArgumentException.class) - public void setMatchingMessageTypesEmpty() { - interceptor.setMatchingMessageTypes(Collections.emptySet()); - } + @Test(expected = IllegalArgumentException.class) + public void setMatchingMessageTypesEmpty() { + interceptor.setMatchingMessageTypes(Collections.emptySet()); + } - @Test - public void preSendSetMatchingMessageTypes() { - interceptor.setMatchingMessageTypes(EnumSet.of(SimpMessageType.DISCONNECT)); - setMessageType(SimpMessageType.DISCONNECT); + @Test + public void preSendSetMatchingMessageTypes() { + interceptor.setMatchingMessageTypes(EnumSet.of(SimpMessageType.DISCONNECT)); + setMessageType(SimpMessageType.DISCONNECT); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verify(sessionRepository).getSession(anyString()); - verify(sessionRepository).save(session); - } + verify(sessionRepository).getSession(anyString()); + verify(sessionRepository).save(session); + } - @Test - public void preSendConnectUpdatesLastUpdateTime() { - setMessageType(SimpMessageType.CONNECT); + @Test + public void preSendConnectUpdatesLastUpdateTime() { + setMessageType(SimpMessageType.CONNECT); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verify(sessionRepository).getSession(anyString()); - verify(sessionRepository).save(session); - } + verify(sessionRepository).getSession(anyString()); + verify(sessionRepository).save(session); + } - @Test - public void preSendMessageUpdatesLastUpdateTime() { - setMessageType(SimpMessageType.MESSAGE); + @Test + public void preSendMessageUpdatesLastUpdateTime() { + setMessageType(SimpMessageType.MESSAGE); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verify(sessionRepository).getSession(anyString()); - verify(sessionRepository).save(session); - } + verify(sessionRepository).getSession(anyString()); + verify(sessionRepository).save(session); + } - @Test - public void preSendSubscribeUpdatesLastUpdateTime() { - setMessageType(SimpMessageType.SUBSCRIBE); + @Test + public void preSendSubscribeUpdatesLastUpdateTime() { + setMessageType(SimpMessageType.SUBSCRIBE); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verify(sessionRepository).getSession(anyString()); - verify(sessionRepository).save(session); - } + verify(sessionRepository).getSession(anyString()); + verify(sessionRepository).save(session); + } - @Test - public void preSendUnsubscribeUpdatesLastUpdateTime() { - setMessageType(SimpMessageType.UNSUBSCRIBE); + @Test + public void preSendUnsubscribeUpdatesLastUpdateTime() { + setMessageType(SimpMessageType.UNSUBSCRIBE); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verify(sessionRepository).getSession(anyString()); - verify(sessionRepository).save(session); - } + verify(sessionRepository).getSession(anyString()); + verify(sessionRepository).save(session); + } - // This will updated when SPR-12288 is resolved - @Test - public void preSendExpiredSession() { - setSessionId("expired"); + // This will updated when SPR-12288 is resolved + @Test + public void preSendExpiredSession() { + setSessionId("expired"); - interceptor.preSend(createMessage(), channel); + interceptor.preSend(createMessage(), channel); - verify(sessionRepository,times(0)).save(any(ExpiringSession.class)); - } + verify(sessionRepository,times(0)).save(any(ExpiringSession.class)); + } - @Test - public void preSendNullSessionId() { - setSessionId(null); + @Test + public void preSendNullSessionId() { + setSessionId(null); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test - public void preSendNullSessionAttributes() { - headers.setSessionAttributes(null); + @Test + public void preSendNullSessionAttributes() { + headers.setSessionAttributes(null); - assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); + assertThat(interceptor.preSend(createMessage(), channel)).isSameAs(createMessage); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test - public void beforeHandshakeNotServletServerHttpRequest() throws Exception { - assertThat(interceptor.beforeHandshake(null,null,null,null)).isTrue(); + @Test + public void beforeHandshakeNotServletServerHttpRequest() throws Exception { + assertThat(interceptor.beforeHandshake(null,null,null,null)).isTrue(); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test - public void beforeHandshakeNullSession() throws Exception { - ServletServerHttpRequest request = new ServletServerHttpRequest(new MockHttpServletRequest()); - assertThat(interceptor.beforeHandshake(request,null,null,null)).isTrue(); + @Test + public void beforeHandshakeNullSession() throws Exception { + ServletServerHttpRequest request = new ServletServerHttpRequest(new MockHttpServletRequest()); + assertThat(interceptor.beforeHandshake(request,null,null,null)).isTrue(); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - @Test - public void beforeHandshakeSession() throws Exception { - MockHttpServletRequest httpRequest = new MockHttpServletRequest(); - HttpSession httpSession = httpRequest.getSession(); - ServletServerHttpRequest request = new ServletServerHttpRequest(httpRequest); - Map attributes = new HashMap(); + @Test + public void beforeHandshakeSession() throws Exception { + MockHttpServletRequest httpRequest = new MockHttpServletRequest(); + HttpSession httpSession = httpRequest.getSession(); + ServletServerHttpRequest request = new ServletServerHttpRequest(httpRequest); + Map attributes = new HashMap(); - assertThat(interceptor.beforeHandshake(request,null,null,attributes)).isTrue(); + assertThat(interceptor.beforeHandshake(request,null,null,attributes)).isTrue(); - assertThat(attributes.size()).isEqualTo(1); - assertThat(SessionRepositoryMessageInterceptor.getSessionId(attributes)).isEqualTo(httpSession.getId()); - } + assertThat(attributes.size()).isEqualTo(1); + assertThat(SessionRepositoryMessageInterceptor.getSessionId(attributes)).isEqualTo(httpSession.getId()); + } - /** - * At the moment there is no need for afterHandshake to do anything. - */ - @Test - public void afterHandshakeDoesNothing() { - interceptor.afterHandshake(null,null,null,null); + /** + * At the moment there is no need for afterHandshake to do anything. + */ + @Test + public void afterHandshakeDoesNothing() { + interceptor.afterHandshake(null,null,null,null); - verifyZeroInteractions(sessionRepository); - } + verifyZeroInteractions(sessionRepository); + } - private void setSessionId(String id) { - SessionRepositoryMessageInterceptor.setSessionId(headers.getSessionAttributes(), id); - } + private void setSessionId(String id) { + SessionRepositoryMessageInterceptor.setSessionId(headers.getSessionAttributes(), id); + } - private Message createMessage() { - createMessage = MessageBuilder.createMessage("", headers.getMessageHeaders()); - return createMessage; - } + private Message createMessage() { + createMessage = MessageBuilder.createMessage("", headers.getMessageHeaders()); + return createMessage; + } - private void setMessageType(SimpMessageType type) { - headers.setHeader(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER, type); - } + private void setMessageType(SimpMessageType type) { + headers.setHeader(SimpMessageHeaderAccessor.MESSAGE_TYPE_HEADER, type); + } }