From 02da23a2a07c6168ea6a73fcd00aa7e4c48b2d10 Mon Sep 17 00:00:00 2001 From: Rob Winch Date: Wed, 26 Apr 2017 19:26:14 -0500 Subject: [PATCH] Remove GemFire Fixes gh-768 --- .../groovy/build/GemFireServerPlugin.groovy | 70 - .../gradle-plugins/gemfire-server.properties | 1 - docs/spring-session-docs.gradle | 1 - .../docs/asciidoc/guides/boot-gemfire.adoc | 270 --- .../guides/java-gemfire-clientserver.adoc | 272 --- .../asciidoc/guides/java-gemfire-p2p.adoc | 209 -- .../guides/xml-gemfire-clientserver.adoc | 273 --- .../docs/asciidoc/guides/xml-gemfire-p2p.adoc | 210 -- docs/src/docs/asciidoc/index.adoc | 207 -- .../HttpSessionGemFireIndexingITests.java | 102 - ...ttpSessionGemFireIndexingCustomITests.java | 72 - gradle/spring3.gradle | 3 - .../spring-session-sample-boot-gemfire.gradle | 87 - .../java/sample/AttributeTests.java | 76 - .../java/sample/pages/HomePage.java | 151 -- .../main/java/sample/client/Application.java | 336 --- .../java/sample/server/GemFireServer.java | 110 - .../sample/server/NativeGemFireServer.java | 186 -- .../src/main/resources/templates/index.html | 49 - ...ple-javaconfig-gemfire-clientserver.gradle | 22 - .../java/sample/AttributeTests.java | 62 - .../java/sample/pages/HomePage.java | 151 -- .../src/main/java/sample/ClientConfig.java | 216 -- .../src/main/java/sample/Initializer.java | 28 - .../src/main/java/sample/ServerConfig.java | 99 - .../src/main/java/sample/SessionServlet.java | 42 - .../src/main/webapp/META-INF/MANIFEST.MF | 0 .../src/main/webapp/index.jsp | 50 - ...ssion-sample-javaconfig-gemfire-p2p.gradle | 19 - .../java/sample/AttributeTests.java | 62 - .../java/sample/pages/HomePage.java | 151 -- .../src/main/java/sample/Config.java | 53 - .../src/main/java/sample/Initializer.java | 28 - .../src/main/java/sample/SessionServlet.java | 42 - .../src/main/webapp/META-INF/MANIFEST.MF | 0 .../gemfire-p2p/src/main/webapp/index.jsp | 50 - ...ion-sample-xml-gemfire-clientserver.gradle | 22 - .../java/sample/AttributeTests.java | 62 - .../java/sample/pages/HomePage.java | 151 -- .../src/main/java/sample/Application.java | 33 - ...ireClientServerReadyBeanPostProcessor.java | 148 -- .../src/main/java/sample/SessionServlet.java | 40 - .../META-INF/spring/application.properties | 2 - .../META-INF/spring/session-server.xml | 48 - .../src/main/webapp/META-INF/MANIFEST.MF | 0 .../webapp/WEB-INF/spring/session-client.xml | 50 - .../src/main/webapp/WEB-INF/web.xml | 53 - .../src/main/webapp/index.jsp | 50 - ...ring-session-sample-xml-gemfire-p2p.gradle | 19 - .../java/sample/AttributeTests.java | 62 - .../java/sample/pages/HomePage.java | 151 -- .../src/main/java/sample/SessionServlet.java | 40 - .../src/main/webapp/META-INF/MANIFEST.MF | 0 .../main/webapp/WEB-INF/spring/session.xml | 34 - .../src/main/webapp/WEB-INF/web.xml | 57 - .../xml/gemfire-p2p/src/main/webapp/index.jsp | 50 - .../spring-session-data-gemfire.gradle | 11 - spring-session/spring-session.gradle | 2 - .../AbstractGemFireIntegrationTests.java | 460 ---- ...ionsSessionRepositoryIntegrationTests.java | 374 ---- ...essionAttributesDeltaIntegrationTests.java | 285 --- ...gionSessionOperationsIntegrationTests.java | 309 --- ...ionsSessionRepositoryIntegrationTests.java | 459 ---- ...ionsSessionRepositoryIntegrationTests.java | 344 --- ...FireHttpSessionEventsIntegrationTests.java | 254 --- ...FireHttpSessionJavaConfigurationTests.java | 148 -- ...mFireHttpSessionXmlConfigurationTests.java | 113 - ...actGemFireOperationsSessionRepository.java | 956 --------- .../GemFireOperationsSessionRepository.java | 155 -- .../web/http/EnableGemFireHttpSession.java | 170 -- .../http/GemFireHttpSessionConfiguration.java | 487 ----- ...emFireCacheTypeAwareRegionFactoryBean.java | 384 ---- .../SessionAttributesIndexFactoryBean.java | 175 -- .../data/gemfire/support/GemFireUtils.java | 170 -- ...emFireOperationsSessionRepositoryTest.java | 1909 ----------------- ...emFireOperationsSessionRepositoryTest.java | 436 ---- .../GemFireHttpSessionConfigurationTest.java | 407 ---- ...reCacheTypeAwareRegionFactoryBeanTest.java | 295 --- ...essionAttributesIndexFactoryBeanTests.java | 132 -- .../gemfire/support/GemFireUtilsTest.java | 203 -- ...tpSessionXmlConfigurationTests-context.xml | 26 - 81 files changed, 13496 deletions(-) delete mode 100644 buildSrc/src/main/groovy/build/GemFireServerPlugin.groovy delete mode 100644 buildSrc/src/main/resources/META-INF/gradle-plugins/gemfire-server.properties delete mode 100644 docs/src/docs/asciidoc/guides/boot-gemfire.adoc delete mode 100644 docs/src/docs/asciidoc/guides/java-gemfire-clientserver.adoc delete mode 100644 docs/src/docs/asciidoc/guides/java-gemfire-p2p.adoc delete mode 100644 docs/src/docs/asciidoc/guides/xml-gemfire-clientserver.adoc delete mode 100644 docs/src/docs/asciidoc/guides/xml-gemfire-p2p.adoc delete mode 100644 docs/src/integration-test/java/docs/http/HttpSessionGemFireIndexingITests.java delete mode 100644 docs/src/integration-test/java/docs/http/gemfire/indexablesessionattributes/HttpSessionGemFireIndexingCustomITests.java delete mode 100644 samples/boot/gemfire/spring-session-sample-boot-gemfire.gradle delete mode 100644 samples/boot/gemfire/src/integration-test/java/sample/AttributeTests.java delete mode 100644 samples/boot/gemfire/src/integration-test/java/sample/pages/HomePage.java delete mode 100644 samples/boot/gemfire/src/main/java/sample/client/Application.java delete mode 100644 samples/boot/gemfire/src/main/java/sample/server/GemFireServer.java delete mode 100644 samples/boot/gemfire/src/main/java/sample/server/NativeGemFireServer.java delete mode 100644 samples/boot/gemfire/src/main/resources/templates/index.html delete mode 100644 samples/javaconfig/gemfire-clientserver/spring-session-sample-javaconfig-gemfire-clientserver.gradle delete mode 100644 samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java delete mode 100644 samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java delete mode 100644 samples/javaconfig/gemfire-clientserver/src/main/java/sample/ClientConfig.java delete mode 100644 samples/javaconfig/gemfire-clientserver/src/main/java/sample/Initializer.java delete mode 100644 samples/javaconfig/gemfire-clientserver/src/main/java/sample/ServerConfig.java delete mode 100644 samples/javaconfig/gemfire-clientserver/src/main/java/sample/SessionServlet.java delete mode 100644 samples/javaconfig/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF delete mode 100644 samples/javaconfig/gemfire-clientserver/src/main/webapp/index.jsp delete mode 100644 samples/javaconfig/gemfire-p2p/spring-session-sample-javaconfig-gemfire-p2p.gradle delete mode 100644 samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java delete mode 100644 samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java delete mode 100644 samples/javaconfig/gemfire-p2p/src/main/java/sample/Config.java delete mode 100644 samples/javaconfig/gemfire-p2p/src/main/java/sample/Initializer.java delete mode 100644 samples/javaconfig/gemfire-p2p/src/main/java/sample/SessionServlet.java delete mode 100644 samples/javaconfig/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF delete mode 100644 samples/javaconfig/gemfire-p2p/src/main/webapp/index.jsp delete mode 100644 samples/xml/gemfire-clientserver/spring-session-sample-xml-gemfire-clientserver.gradle delete mode 100644 samples/xml/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java delete mode 100644 samples/xml/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java delete mode 100644 samples/xml/gemfire-clientserver/src/main/java/sample/Application.java delete mode 100644 samples/xml/gemfire-clientserver/src/main/java/sample/GemFireClientServerReadyBeanPostProcessor.java delete mode 100644 samples/xml/gemfire-clientserver/src/main/java/sample/SessionServlet.java delete mode 100644 samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/application.properties delete mode 100644 samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/session-server.xml delete mode 100644 samples/xml/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF delete mode 100644 samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/spring/session-client.xml delete mode 100644 samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml delete mode 100644 samples/xml/gemfire-clientserver/src/main/webapp/index.jsp delete mode 100644 samples/xml/gemfire-p2p/spring-session-sample-xml-gemfire-p2p.gradle delete mode 100644 samples/xml/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java delete mode 100644 samples/xml/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java delete mode 100644 samples/xml/gemfire-p2p/src/main/java/sample/SessionServlet.java delete mode 100644 samples/xml/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF delete mode 100644 samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/spring/session.xml delete mode 100644 samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml delete mode 100644 samples/xml/gemfire-p2p/src/main/webapp/index.jsp delete mode 100644 spring-session-data-gemfire/spring-session-data-gemfire.gradle delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerHttpSessionAttributesDeltaIntegrationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerProxyRegionSessionOperationsIntegrationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryIntegrationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSessionEventsIntegrationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionJavaConfigurationTests.java delete mode 100644 spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests.java delete mode 100644 spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java delete mode 100644 spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java delete mode 100644 spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java delete mode 100644 spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java delete mode 100644 spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java delete mode 100644 spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBean.java delete mode 100644 spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java delete mode 100644 spring-session/src/test/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepositoryTest.java delete mode 100644 spring-session/src/test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryTest.java delete mode 100644 spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java delete mode 100644 spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java delete mode 100644 spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBeanTests.java delete mode 100644 spring-session/src/test/java/org/springframework/session/data/gemfire/support/GemFireUtilsTest.java delete mode 100644 spring-session/src/test/resources/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests-context.xml diff --git a/buildSrc/src/main/groovy/build/GemFireServerPlugin.groovy b/buildSrc/src/main/groovy/build/GemFireServerPlugin.groovy deleted file mode 100644 index a056f371..00000000 --- a/buildSrc/src/main/groovy/build/GemFireServerPlugin.groovy +++ /dev/null @@ -1,70 +0,0 @@ -package build; - -import org.gradle.api.plugins.JavaPlugin -import org.gradle.api.tasks.bundling.Zip -import org.gradle.api.DefaultTask -import org.gradle.api.Plugin -import org.gradle.api.Project -import org.gradle.api.tasks.TaskAction - -public class GemFireServerPlugin implements Plugin { - - @Override - public void apply(Project project) { - project.tasks.create('gemFireServer', GemFireServerTask) - - project.tasks.integrationTest.doLast { - println 'Stopping GemFire Server...' - project.tasks.gemFireServer.process?.destroyForcibly() - } - - project.tasks.prepareAppServerForIntegrationTests { - dependsOn project.tasks.gemFireServer - doFirst { - project.gretty { - jvmArgs = ["-Dspring.session.data.gemfire.port=${project.tasks.gemFireServer.port}"] - } - } - } - } - - static int availablePort() { - new ServerSocket(0).withCloseable { socket -> - socket.localPort - } - } - - static class GemFireServerTask extends DefaultTask { - def mainClassName = "sample.ServerConfig" - def process - def port - boolean debug - - @TaskAction - def greet() { - port = availablePort() - println "Starting GemFire Server on port [$port]..." - - def out = debug ? System.out : new StringBuilder() - def err = debug ? System.out : new StringBuilder() - - String classpath = project.sourceSets.main.runtimeClasspath.collect { it }.join(File.pathSeparator) - String gemfireLogLevel = System.getProperty('spring.session.data.gemfire.log-level', 'warning') - - String[] commandLine = [ - 'java', '-server', '-ea', '-classpath', classpath, - //"-Dgemfire.log-file=gemfire-server.log", - //"-Dgemfire.log-level=config", - "-Dspring.session.data.gemfire.log-level=" + gemfireLogLevel, - "-Dspring.session.data.gemfire.port=${port}", - 'sample.ServerConfig' - ] - - //println commandLine - - project.tasks.appRun.ext.process = process = commandLine.execute() - - process.consumeProcessOutput(out, err) - } - } -} diff --git a/buildSrc/src/main/resources/META-INF/gradle-plugins/gemfire-server.properties b/buildSrc/src/main/resources/META-INF/gradle-plugins/gemfire-server.properties deleted file mode 100644 index bb6a3057..00000000 --- a/buildSrc/src/main/resources/META-INF/gradle-plugins/gemfire-server.properties +++ /dev/null @@ -1 +0,0 @@ -implementation-class=build.GemFireServerPlugin \ No newline at end of file diff --git a/docs/spring-session-docs.gradle b/docs/spring-session-docs.gradle index cd67a951..086f7586 100644 --- a/docs/spring-session-docs.gradle +++ b/docs/spring-session-docs.gradle @@ -3,7 +3,6 @@ apply plugin: 'io.spring.convention.spring-test' dependencies { testCompile project(':spring-session') - testCompile project(':spring-session-data-gemfire') testCompile project(':spring-session-data-mongo') testCompile project(':spring-session-data-redis') testCompile "org.springframework:spring-jdbc" diff --git a/docs/src/docs/asciidoc/guides/boot-gemfire.adoc b/docs/src/docs/asciidoc/guides/boot-gemfire.adoc deleted file mode 100644 index 06829fca..00000000 --- a/docs/src/docs/asciidoc/guides/boot-gemfire.adoc +++ /dev/null @@ -1,270 +0,0 @@ -= Spring Session - HttpSession with GemFire Client/Server using Spring Boot -John Blum -:toc: - -This guide describes how to build a _Spring Boot_ application configured with _Spring Session_ to transparently leverage -Pivotal GemFire to back a web application's `HttpSession`. - -In this sample, GemFire's client/server topology is employed using a pair of _Spring Boot_ applications, one to -configure and run a GemFire Server and another to configure and run the client, Spring MVC-based web application -making use of the `HttpSession`. - -NOTE: The completed guide can be found in the <>. - -== Updating Dependencies -Before using _Spring Session_, you must ensure that the required dependencies are included. -If you are using Maven, include the following `dependencies` in your _pom.xml_: - -.pom.xml -[source,xml] -[subs="verbatim,attributes"] ----- - - - - - org.springframework.session - spring-session-data-gemfire - {spring-session-version} - pom - - - org.springframework.boot - spring-boot-starter-web - - ----- - -ifeval::["{version-snapshot}" == "true"] -Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-snapshot - https://repo.spring.io/libs-snapshot - - ----- -endif::[] - -ifeval::["{version-milestone}" == "true"] -Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-milestone - https://repo.spring.io/libs-milestone - - ----- -endif::[] - -// tag::config[] -[[httpsession-spring-java-configuration]] -== Spring Boot Configuration - -After adding the required dependencies and repository declarations, we can create our Spring configuration -for both the GemFire client and server using _Spring Boot_. The Spring configuration is responsible for -creating a Servlet Filter that replaces the `HttpSession` with an implementation backed by _Spring Session_ -and GemFire. - -=== Spring Boot-based GemFire Server - -We start with the _Spring Boot_ application for configuring and bootstrapping a GemFire Server process... - -[source,java] ----- -include::{samples-dir}boot/gemfire/src/main/java/sample/server/GemFireServer.java[tags=class] ----- - -<1> The `@EnableGemFireHttpSession` annotation is used on the GemFire Server to mainly define the corresponding -Region (e.g. `ClusteredSpringSessions`, the default) in which Session state information will be stored -and managed by GemFire. As well, we have specified an arbitrary expiration attribute (i.e. `maxInactiveIntervalInSeconds`) -for when the Session will timeout, which is triggered by a GemFire Region entry expiration event that also invalidates -the Session object in the Region. -<2> Next, we define a few `Properties` that allow us to configure certain aspects of the GemFire Server using -http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html[GemFire's System properties]. -<3> Then, we create an instance of the GemFire `Cache` using our defined `Properties`. -<4> Finally, we configure and start a `CacheServer` running in the GemFire Server to listen for connections -from cache clients. The `CacheServer's` `Socket` will be used to connect our GemFire cache client, -_Spring Boot_ web application to the server. - -The sample also makes use of a `PropertySourcesPlaceholderConfigurer` bean in order to externalize the sample application -configuration to affect GemFire and application configuration/behavior from the command-line (e.g. such as GemFire's -`log-level` using the `gemfire.log.level` System property; more details below). - -=== Spring Boot-based GemFire cache client Web application - -Now, we create our _Spring Boot_ Web application exposing our Web service with Spring MVC, running as a -GemFire cache client connected to our _Spring Boot_-based GemFire Server, using Spring Session backed by GemFire -to manage Session state in a clustered, replicated fashion. - -[source,java] ----- -include::{samples-dir}boot/gemfire/src/main/java/sample/client/Application.java[tags=class] ----- - -<1> Here, again, we use the `@EnableGemFireHttpSession` annotation to not only configure the GemFire cache client, -but to also override the (HTTP) Web application container's `HttpSession` and replace it with a Session implementation -backed by _Spring Session_ and GemFire. Also notice, we did not define any Session expiration timeout with the -`maxInactiveIntervalInSeconds` attribute this time. That is because the Session expiration is managed by GemFire, -on the server, which will appropriately notify the cache client when the Session times out. Again, we have just -resorted to using the default named Region, `ClusteredSpringSessions`. Of course, we can change the Region name, -but we must do so on both the client and the server. That is a GemFire requirement, not a -_Spring Session Data GemFire_ requirement. -<2> Similarly to the server configuration, we set a few basic GemFire System `Properties` on the client. -<3> Although, this time, an instance of `ClientCache` is created with the `ClientCacheFactoryBean` -from _Spring Data GemFire_. -<4> However, in order to connect to the GemFire Server we must define a GemFire `Pool` bean containing a -pool of connections to the server. Whenever a client Region entry operation corresponding to a Session update occurs, -the client-side Region will use an existing, pooled connection to route the operation to the server. -<5> The following _Spring_ `BeanPostProcessor` (along with some utility methods) are only needed for testing purposes -and are not required by any production code. Specifically, the `BeanPostProcessor` along with the code referenced in *6* -is useful in integration test cases where the client and server processes are forked by the test framework. It is pretty -easy to figure out that a race condition is imminent without proper coordination between the client and the server, -therefore, the BPP and `ClientMembershipListener` help sync the interaction between the client and the server -on startup during automated testing. -<6> Navigates the Web application to the home page (`index.html`), which uses **Thymeleaf** templates for server-side -pages. -<7> Heartbeat Web service endpoint (useful for manual testing purposes). -<8> Web service endpoint allowing the user to add a Session attribute using the Web application UI. In addition, -the webapp stores an additional Session attribute (`requestCount`) to keep track of how many HTTP requests the user -has sent during the current "session". - -There are many other utility methods, so please refer to the actual source code for full details. - -TIP: In typical GemFire deployments, where the cluster includes potentially hundreds or thousands of GemFire data nodes -(servers), it is more common for clients to connect to one or more GemFire Locators running in the cluster. A Locator -passes meta-data to clients about the servers available, their load and which servers have the client's data of interest, -which is particularly important in direct, single-hop data access and latency-sensitive operations. See more details -about the http://gemfire.docs.pivotal.io/docs-gemfire/latest/topologies_and_comm/cs_configuration/chapter_overview.html[Client/Server Topology in GemFire's User Guide]. - -NOTE: For more information on configuring _Spring Data GemFire_, refer to the http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[reference guide]. - -The `@EnableGemFireHttpSession` annotation enables a developer to configure certain aspects of both _Spring Session_ -and GemFire out-of-the-box using the following attributes: - -* `maxInactiveIntervalInSeconds` - controls _HttpSession_ idle-timeout expiration (defaults to **30 minutes**). -* `regionName` - specifies the name of the GemFire Region used to store `HttpSession` state (defaults is "*ClusteredSpringSessions*"). -* `clientRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy] -with a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/client/ClientRegionShortcut.html[ClientRegionShortcut] -(default is `PROXY`). This attribute is only used when configuring client Region. -* `poolName` - name of the dedicated GemFire Pool used to connect a client to the cluster of servers. The attribute -is only used when the application is a GemFire cache client. Defaults to `gemfirePool`. -* `serverRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy] -using a GemFire http://data-docs-samples.cfapps.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/RegionShortcut.html[RegionShortcut] -(default is `PARTITION`). This attribute is only used when configuring server Regions, or when a p2p topology is employed. - -NOTE: It is important to remember that the GemFire client Region name must match a server Region by the same name if -the client Region is a `PROXY` or `CACHING_PROXY`. Client and server Region names are not required to match if -the client Region used to store Spring Sessions is `LOCAL`. However, keep in mind that your session state will not -be propagated to the server and you lose all the benefits of using GemFire to store and manage distributed, replicated -session state information in a cluster. - -[[httpsession-gemfire-boot-sample]] -== HttpSession with GemFire using Spring Boot Sample Application - -=== Running the httpsession-gemfire-boot Sample Application - -You can run the sample by obtaining the {download-url}[source code] and invoking the following commands. - -First, you must run the server: - ----- -$ ./gradlew :samples:httpsession-gemfire-boot:run [-Dgemfire.log-level=config] ----- - -Then, in a separate terminal, run the client: - ----- -$ ./gradlew :samples:httpsession-gemfire-boot:bootRun [-Dgemfire.log-level=config] ----- - -You should now be able to access the application at http://localhost:8080/. In this sample, the web application -is the client cache and the server is standalone. - -=== Exploring the httpsession-gemfire-boot Sample Application - -Try using the application. Fill out the form with the following information: - -* **Attribute Name:** _username_ -* **Attribute Value:** _test_ - -Now click the **Set Attribute** button. You should now see the attribute name and value displayed in the table -along with an additional attribute (`requestCount`) indicating the number of Session interactions (via HTTP requests). - -=== How does it work? - -We interact with the standard `HttpSession` in the the Spring MVC web service endpoint, shown here for convenience: - -.src/main/java/sample/SessionServlet.java -[source,java] ----- -@RequestMapping(method = RequestMethod.POST, path = "/session") -public String session(HttpSession session, ModelMap modelMap, - @RequestParam(name = "attributeName", required = false) String name, - @RequestParam(name = "attributeValue", required = false) String value) { - - modelMap.addAttribute("sessionAttributes", - attributes(setAttribute(updateRequestCount(session), name, value))); - - return INDEX_TEMPLATE_VIEW_NAME; -} ----- - -Instead of using the embedded HTTP server's `HttpSession`, we are actually persisting the Session state in GemFire. -_Spring Session_ creates a cookie named SESSION in your browser that contains the id of your session. -Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] -or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]). - -NOTE: The following instructions assume you have a local GemFire installation. For more information on installation, -see http://gemfire.docs.pivotal.io/docs-gemfire/latest/getting_started/installation/install_intro.html[Installing Pivotal GemFire]. - -NOTE: In order to run the following, you must uncomment the lines in the `GemFireServer` class, `gemfireProperties` bean -for the following GemFire System properties: `jmx-manager` and `jmx-manager-start`. - -If you like, you can easily remove the session using `gfsh`. For example, on a Linux-based system type the following -at the command-line: - - $ gfsh - -Then, enter the following commands in _Gfsh_ ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value -of your SESSION cookie, or the session ID returned by the GemFire OQL query (which should match): - -.... -gfsh>connect --jmx-manager=localhost[1099] - -gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet' - -Result : true -startCount : 0 -endCount : 20 -Rows : 1 - -Result ------------------------------------- -70002719-3c54-4c20-82c3-e7faa6b718f3 - -NEXT_STEP_NAME : END - -gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3" -.... - -NOTE: The _GemFire User Guide_ has more detailed instructions on using http://gemfire.docs.pivotal.io/docs-gemfire/latest/tools_modules/gfsh/chapter_overview.html[gfsh]. - -Now visit the application at http://localhost:8080/ again and observe that the attribute we added is no longer displayed. - -Alternatively, you can wait **20 seconds** for the session to expire and timeout, and then refresh the page. The attribute -we added should no longer be displayed in the table. diff --git a/docs/src/docs/asciidoc/guides/java-gemfire-clientserver.adoc b/docs/src/docs/asciidoc/guides/java-gemfire-clientserver.adoc deleted file mode 100644 index 5625fa15..00000000 --- a/docs/src/docs/asciidoc/guides/java-gemfire-clientserver.adoc +++ /dev/null @@ -1,272 +0,0 @@ -= Spring Session - HttpSession with GemFire Client/Server (Quick Start) -John Blum -:toc: - -This guide describes how to configure Spring Session to transparently leverage Pivotal GemFire to back a web application's -`HttpSession` using Java Configuration. - -NOTE: The completed guide can be found in the <>. - -== Updating Dependencies -Before using Spring Session, you must ensure that the required dependencies are included. -If you are using Maven, include the following `dependencies` in your _pom.xml_: - -.pom.xml -[source,xml] -[subs="verbatim,attributes"] ----- - - - - - org.springframework.session - spring-session-data-gemfire - {spring-session-version} - pom - - - org.springframework - spring-web - {spring-version} - - ----- - -ifeval::["{version-snapshot}" == "true"] -Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-snapshot - https://repo.spring.io/libs-snapshot - - ----- -endif::[] - -ifeval::["{version-milestone}" == "true"] -Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-milestone - https://repo.spring.io/libs-milestone - - ----- -endif::[] - -// tag::config[] -[[httpsession-spring-java-configuration]] -== Spring Java Configuration - -After adding the required dependencies and repository declarations, we can create our Spring configuration. -The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` -with an implementation backed by Spring Session and GemFire. - -Add the following Spring Configuration: - -[source,java] ----- -include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/ClientConfig.java[tags=class] ----- - -<1> The `@EnableGemFireHttpSession` annotation creates a Spring bean named `springSessionRepositoryFilter` that -implements `Filter`. The filter is what replaces the `HttpSession` with an implementation backed by Spring Session -and GemFire. -<2> Next, we register a `Properties` bean that allows us to configure certain aspects of the GemFire client cache -using http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html[GemFire's System properties]. -<3> We use the `Properties` to configure an instance of a GemFire `ClientCache`. -<4> Then, we configure a `Pool` of client connections to talk to the GemFire Server in our Client/Server topology. In our -configuration, we have used sensible settings for timeouts, number of connections and so on. Also, the `Pool` has been -configured to connect directly to a server. Learn more about various `Pool` configuration settings from the -http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/client/PoolFactory.html[PoolFactory API]. -<5> Finally, we include a Spring `BeanPostProcessor` to block the client until our GemFire Server is up and running, -listening for and accepting client connections. - -The `gemfireCacheServerReadyBeanPostProcessor` is necessary in order to coordinate the client and server in -an automated fashion during testing, but unnecessary in situations where the GemFire cluster is already presently -running, such as in production. - -The `BeanPostProcessor` uses a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/management/membership/ClientMembershipListener.html[ClientMembershipListener] -that will be notified when the client has successfully connected to the server. Once a connection has been established, -the listener releases the latch that the `BeanPostProcessor` will wait on (up to the specified timeout) in the -`postProcessAfterInitialization` callback to block the client. - -TIP: In typical GemFire deployments, where the cluster includes potentially hundreds of GemFire data nodes (servers), -it is more common for clients to connect to one or more GemFire Locators running in the cluster. A Locator passes meta-data -to clients about the servers available, load and which servers have the client's data of interest, which is particularly -important for single-hop, direct data access. See more details about the http://gemfire.docs.pivotal.io/docs-gemfire/latest/topologies_and_comm/cs_configuration/chapter_overview.html[Client/Server Topology in GemFire's User Guide]. - -NOTE: For more information on configuring _Spring Data GemFire_, refer to the http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[reference guide]. - -The `@EnableGemFireHttpSession` annotation enables a developer to configure certain aspects of both Spring Session -and GemFire out-of-the-box using the following attributes: - -* `maxInactiveIntervalInSeconds` - controls _HttpSession_ idle-timeout expiration (defaults to **30 minutes**). -* `regionName` - specifies the name of the GemFire Region used to store `HttpSession` state (defaults is "*ClusteredSpringSessions*"). -* `clientRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy] -with a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/client/ClientRegionShortcut.html[ClientRegionShortcut] -(default is `PROXY`). This attribute is only used when configuring client Region. -* `poolName` - name of the dedicated GemFire Pool used to connect a client to the cluster of servers. The attribute -is only used when the application is a GemFire cache client. Defaults to `gemfirePool`. -* `serverRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy] -using a GemFire http://data-docs-samples.cfapps.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/RegionShortcut.html[RegionShortcut] -(default is `PARTITION`). This attribute is only used when configuring server Regions, or when a p2p topology is employed. - -NOTE: It is important to note that the GemFire client Region name must match a server Region by the same name if -the client Region is a `PROXY` or `CACHING_PROXY`. Names are not required to match if the client Region used to -store Spring Sessions is `LOCAL`, however, keep in mind that your session state will not be propagated to the server -and you lose all benefits of using GemFire to store and manage distributed, replicated session state information -in a cluster. - -NOTE: `serverRegionShort` is ignored in a client/server cache configuration and only applies when -a peer-to-peer (P2P) topology, and more specifically, a GemFire peer cache is used. - -=== Server Configuration - -We have only covered one side of the equation. We also need a GemFire Server for our client to talk to and send -session state to the server to manage. - -In this sample, we will use the following GemFire Server Java Configuration: - -[source,java] ----- -include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/ServerConfig.java[tags=class] ----- - -<1> On the server, we also configure Spring Session using the `@EnableGemFireHttpSession` annotation. This ensures -the Region names on both the client and server match (in this sample, we use the default "_ClusteredSpringSessions_"). -We have also set the session timeout to **30 seconds**. Later, we will see how this timeout is used. -<2> Next, we configure the GemFire Server using GemFire System Properties very much like our P2P samples. -With the `mcast-port` set to 0 and no `locators` property specified, our server will be standalone. We also allow a -JMX client (e.g. _Gfsh_) to connect to our server with the use of the GemFire-specific JMX System properties. -<3> Then, we create an instance of a GemFire peer `Cache` initialized with our GemFire System Properties. -<4> We also setup a GemFire `CacheServer` instance running on **localhost**, listening to port **12480**, -ready to accept our client connection. -<5> Finally, we declare a `main` method as an entry point for launching and running our GemFire Server -from the command-line. - -== Java Servlet Container Initialization - -Our <> created a Spring bean named `springSessionRepositoryFilter` -that implements `Filter`. The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` -with a custom implementation backed by Spring Session and GemFire. - -In order for our `Filter` to do its magic, Spring needs to load our `ClientConfig` class. We also need to ensure our -Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request. Fortunately, Spring Session -provides a utility class named `AbstractHttpSessionApplicationInitializer` to make both of these steps extremely easy. - -You can find an example below: - -.src/main/java/sample/Initializer.java -[source,java] ----- -include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/Initializer.java[tags=class] ----- - -NOTE: The name of our class (`Initializer`) does not matter. What is important is that we extend `AbstractHttpSessionApplicationInitializer`. - -<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`. -This ensures that a Spring bean named `springSessionRepositoryFilter` is registered with our Servlet Container -and used for every request. -<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily allow Spring to load our `ClientConfig`. -// end::config[] - -[[httpsession-gemfire-clientserver-java-sample-app]] -== HttpSession with GemFire (Client/Server) Sample Application - - -=== Running the httpsession-gemfire-clientserver Sample Application - -You can run the sample by obtaining the {download-url}[source code] and invoking the following commands. - -First, you need to run the server using: - ----- -$ ./gradlew :samples:httpsession-gemfire-clientserver:run [-Dsample.httpsession.gemfire.log-level=info] ----- - -Then, in a separate terminal, you run the client using: - ----- -$ ./gradlew :samples:httpsession-gemfire-clientserver:tomcatRun [-Dsample.httpsession.gemfire.log-level=info] ----- - -You should now be able to access the application at http://localhost:8080/. In this sample, the web application -is the client cache and the server is standalone. - -=== Exploring the httpsession-gemfire-clientserver Sample Application - -Try using the application. Fill out the form with the following information: - -* **Attribute Name:** _username_ -* **Attribute Value:** _john_ - -Now click the **Set Attribute** button. You should now see the values displayed in the table. - -=== How does it work? - -We interact with the standard `HttpSession` in the `SessionServlet` shown below: - -.src/main/java/sample/SessionServlet.java -[source,java] ----- -include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/SessionServlet.java[tags=class] ----- - -Instead of using Tomcat's `HttpSession`, we are actually persisting the values in GemFire. -Spring Session creates a cookie named SESSION in your browser that contains the id of your session. -Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] -or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]). - -NOTE: The following instructions assume you have a local GemFire installation. For more information on installation, -see http://gemfire.docs.pivotal.io/docs-gemfire/latest/getting_started/installation/install_intro.html[Installing Pivotal GemFire]. - -If you like, you can easily remove the session using `gfsh`. For example, on a Linux-based system type the following -at the command-line: - - $ gfsh - -Then, enter the following commands in _Gfsh_ ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value -of your SESSION cookie, or the session ID returned by the GemFire OQL query (which should match): - -.... -gfsh>connect --jmx-manager=localhost[1099] - -gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet' - -Result : true -startCount : 0 -endCount : 20 -Rows : 1 - -Result ------------------------------------- -70002719-3c54-4c20-82c3-e7faa6b718f3 - -NEXT_STEP_NAME : END - -gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3" -.... - -NOTE: The _GemFire User Guide_ has more detailed instructions on using http://gemfire.docs.pivotal.io/docs-gemfire/latest/tools_modules/gfsh/chapter_overview.html[gfsh]. - -Now visit the application at http://localhost:8080/ again and observe that the attribute we added is no longer displayed. - -Alternatively, you can wait **30 seconds** for the session to expire and timeout, and then refresh the page. The attribute -we added should no longer be displayed in the table. However, keep in mind, that by refreshing the page, you will inadvertently -create a new (empty) session. If you run the query again, you will also see two session IDs, the new and the old, -since GemFire keeps a "tombstone" of the old session around. diff --git a/docs/src/docs/asciidoc/guides/java-gemfire-p2p.adoc b/docs/src/docs/asciidoc/guides/java-gemfire-p2p.adoc deleted file mode 100644 index d3c4d7ab..00000000 --- a/docs/src/docs/asciidoc/guides/java-gemfire-p2p.adoc +++ /dev/null @@ -1,209 +0,0 @@ -= Spring Session - HttpSession with GemFire P2P (Quick Start) -John Blum, Rob Winch -:toc: - -This guide describes how to configure Pivotal GemFire as a provider in Spring Session to transparently back -a web application's `HttpSession` using Java Configuration. - -NOTE: The completed guide can be found in the <>. - -== Updating Dependencies -Before using Spring Session, you must ensure that the required dependencies are included. -If you are using Maven, include the following `dependencies` in your _pom.xml_: - -.pom.xml -[source,xml] -[subs="verbatim,attributes"] ----- - - - - - org.springframework.session - spring-session-data-gemfire - {spring-session-version} - pom - - - org.springframework - spring-web - {spring-version} - - ----- - -ifeval::["{version-snapshot}" == "true"] -Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-snapshot - https://repo.spring.io/libs-snapshot - - ----- -endif::[] - -ifeval::["{version-milestone}" == "true"] -Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-milestone - https://repo.spring.io/libs-milestone - - ----- -endif::[] - -// tag::config[] -[[httpsession-spring-java-configuration]] -== Spring Java Configuration - -After adding the required dependencies and repository declarations, we can create our Spring configuration. -The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` -with an implementation backed by Spring Session and GemFire. - -Add the following Spring Configuration: - -[source,java] ----- -include::{samples-dir}javaconfig/gemfire-p2p/src/main/java/sample/Config.java[tags=class] ----- - -<1> The `@EnableGemFireHttpSession` annotation creates a Spring bean named `springSessionRepositoryFilter` that -implements `Filter`. The filter is what replaces the `HttpSession` with an implementation backed by Spring Session. -In this instance, Spring Session is backed by GemFire. -<2> Then, we configure a GemFire peer cache using standard GemFire System properties. We give the GemFire data node -a name using the `name` property and set `mcast-port` to 0. With the absence of a `locators` property, this data node -will be a standalone server. GemFire's `log-level` is set using an application-specific System property (`sample.httpsession.gemfire.log-level`) -that a user can specify on the command-line when running this sample application using either Maven or Gradle (default is "_warning_"). -<3> Finally, we create an instance of the GemFire peer cache that embeds GemFire in the same JVM process as the running -Spring Session sample application. - -TIP: Additionally, we have configured this data node (server) as a GemFire Manager as well using GemFire-specific -JMX System properties that enable JMX client (e.g. _Gfsh_) to connect to this running data node. - -NOTE: For more information on configuring _Spring Data GemFire_, refer to the http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[reference guide]. - -The `@EnableGemFireHttpSession` annotation enables a developer to configure certain aspects of Spring Session -and GemFire out-of-the-box using the following attributes: - -* `maxInactiveIntervalInSeconds` - controls HttpSession idle-timeout expiration (defaults to **30 minutes**). -* `regionName` - specifies the name of the GemFire Region used to store `HttpSession` state (defaults is "_ClusteredSpringSessions_"). -* `serverRegionShort` - specifies GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policies] -with a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/RegionShortcut.html[RegionShortcut] -(default is `PARTITION`). - -NOTE: `clientRegionShort` is ignored in a peer cache configuration and only applies when a client-server topology, -and more specifically, a GemFire client cache is used. - -== Java Servlet Container Initialization - -Our <> created a Spring bean named `springSessionRepositoryFilter` -that implements `Filter`. The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` -with a custom implementation backed by Spring Session and GemFire. - -In order for our `Filter` to do its magic, Spring needs to load our `Config` class. We also need to ensure our -Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request. Fortunately, Spring Session -provides a utility class named `AbstractHttpSessionApplicationInitializer` to make both of these steps extremely easy. - -You can find an example below: - -.src/main/java/sample/Initializer.java -[source,java] ----- -include::{samples-dir}javaconfig/gemfire-p2p/src/main/java/sample/Initializer.java[tags=class] ----- - -NOTE: The name of our class (`Initializer`) does not matter. What is important is that we extend `AbstractHttpSessionApplicationInitializer`. - -<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`. -This ensures that a Spring bean named `springSessionRepositoryFilter` is registered with our Servlet Container -and used for every request. -<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily allow Spring to load our `Config`. -// end::config[] - -[[httpsession-gemfire-p2p-java-sample-app]] -== HttpSession with GemFire (P2P) Sample Application - - -=== Running the httpsession-gemfire-p2p Sample Application - -You can run the sample by obtaining the {download-url}[source code] and invoking the following command: - ----- -$ ./gradlew :samples:httpsession-gemfire-p2p:tomcatRun [-Dsample.httpsession.gemfire.log-level=info] ----- - -You should now be able to access the application at http://localhost:8080/ - -=== Exploring the httpsession-gemfire-p2p Sample Application - -Try using the application. Fill out the form with the following information: - -* **Attribute Name:** _username_ -* **Attribute Value:** _john_ - -Now click the **Set Attribute** button. You should now see the values displayed in the table. - -=== How does it work? - -We interact with the standard `HttpSession` in the `SessionServlet` shown below: - -.src/main/java/sample/SessionServlet.java -[source,java] ----- -include::{samples-dir}javaconfig/gemfire-p2p/src/main/java/sample/SessionServlet.java[tags=class] ----- - -Instead of using Tomcat's `HttpSession`, we are actually persisting the values in GemFire. -Spring Session creates a cookie named SESSION in your browser that contains the id of your session. -Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] -or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]). - -NOTE: The following instructions assume you have a local GemFire installation. For more information on installation, -see http://gemfire.docs.pivotal.io/docs-gemfire/latest/getting_started/installation/install_intro.html[Installing Pivotal GemFire]. - -If you like, you can easily remove the session using `gfsh`. For example, on a Linux-based system type the following -at the command-line: - - $ gfsh - -Then, enter the following into _Gfsh_ ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value -of your SESSION cookie, or the session ID returned by the GemFire OQL query (which should match): - -.... -gfsh>connect --jmx-manager=localhost[1099] - -gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet' - -Result : true -startCount : 0 -endCount : 20 -Rows : 1 - -Result ------------------------------------- -70002719-3c54-4c20-82c3-e7faa6b718f3 - -NEXT_STEP_NAME : END - -gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3" -.... - -NOTE: The _GemFire User Guide_ has more detailed instructions on using http://gemfire.docs.pivotal.io/docs-gemfire/latest/tools_modules/gfsh/chapter_overview.html[gfsh]. - -Now visit the application at http://localhost:8080/ and observe that the attribute we added is no longer displayed. diff --git a/docs/src/docs/asciidoc/guides/xml-gemfire-clientserver.adoc b/docs/src/docs/asciidoc/guides/xml-gemfire-clientserver.adoc deleted file mode 100644 index cf0b10ce..00000000 --- a/docs/src/docs/asciidoc/guides/xml-gemfire-clientserver.adoc +++ /dev/null @@ -1,273 +0,0 @@ -= Spring Session - HttpSession with GemFire Client/Server using XML (Quick Start) -John Blum -:toc: - -This guide describes how to configure Spring Session to transparently leverage Pivotal GemFire to back a web application's -`HttpSession` using XML Configuration. - -NOTE: The completed guide can be found in the <>. - -== Updating Dependencies -Before using Spring Session, you must ensure that the required dependencies are included. -If you are using Maven, include the following `dependencies` in your _pom.xml_: - -.pom.xml -[source,xml] -[subs="verbatim,attributes"] ----- - - - - - org.springframework.session - spring-session-data-gemfire - {spring-session-version} - pom - - - org.springframework - spring-web - {spring-version} - - ----- - -ifeval::["{version-snapshot}" == "true"] -Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-snapshot - https://repo.spring.io/libs-snapshot - - ----- -endif::[] - -ifeval::["{version-milestone}" == "true"] -Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-milestone - https://repo.spring.io/libs-milestone - - ----- -endif::[] - -// tag::config[] -[[httpsession-spring-xml-configuration]] -== Spring XML Configuration - -After adding the required dependencies and repository declarations, we can create our Spring configuration. -The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` -with an implementation backed by Spring Session and GemFire. - -Add the following Spring Configuration: - -[source,xml] ----- -include::{samples-dir}xml/gemfire-clientserver/src/main/webapp/WEB-INF/spring/session-client.xml[tags=beans] ----- - -<1> Spring annotation configuration support is enabled with `` element so that any -Spring beans declared in the XML config that are annotated with either Spring or Standard Java annotations supported -by Spring will be configured appropriately. -<2> The `META-INF/spring/application.properties` file are used along with the `PropertySourcesPlaceholderConfigurer` -bean to replace placeholders in the Spring XML configuration meta-data with the approrpriate property values. -<3> Then the `GemFireCacheSeverReadyBeanPostProcessor`is registered to determine whether a GemFire Server -at the designated host/port is running and listening for client connections, blocking client startup until -the server is available and ready. -<4> Next, we include a `Properties` bean to configure certain aspects of the GemFire client cache using -http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html[GemFire's System Properties]. -In this case, we are just setting GemFire's `log-level` from a application-specific System property, defaulting -to `warning` if unspecified. -<5> Then we create a instance of a GemFire `ClientCache` initialized with our `gemfireProperties`. -<6> We configure a Pool of client connections to talk to the GemFire Server in our Client/Server topology. -In our configuration, we use sensible settings for timeouts, number of connections and so on. Also, our `Pool` -has been configured to connect directly to a server. -<7> Finally, the `GemFireHttpSessionConfiguration` is registered to enable Spring Session functionality. - -TIP: In typical GemFire deployments, where the cluster includes potentially hundreds of GemFire data nodes (servers), -it is more common for clients to connect to one or more GemFire Locators running in the cluster. A Locator passes meta-data -to clients about the servers available, load and which servers have the client's data of interest, which is particularly -important for single-hop, direct data access. See more details about the http://gemfire.docs.pivotal.io/docs-gemfire/latest/topologies_and_comm/cs_configuration/chapter_overview.html[Client/Server Topology in GemFire's User Guide]. - -NOTE: For more information on configuring _Spring Data GemFire_, refer to the http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[reference guide]. - -=== Server Configuration - -We have only covered one side of the equation. We also need a GemFire Server for our client to talk to and send -session state information to the server to manage. - -In this sample, we will use the following GemFire Server Java Configuration: - -[source,xml] ----- -include::{samples-dir}xml/gemfire-clientserver/src/main/resources/META-INF/spring/session-server.xml[tags=beans] ----- - -<1> First, we enable Spring annotation config support with the `` element so that any -Spring beans declared in the XML config that are annotated with either Spring or Standard Java annotations supported -by Spring will be configured appropriately. -<2> A `PropertySourcesPlaceholderConfigurer` is registered to replace placeholders in our Spring XML configuration -meta-data with property values in the `META-INF/spring/application.properties` file. -<3> Next, we configure the GemFire Server using GemFire System Properties very much like our P2P samples. -With the `mcast-port` set to 0 and no `locators` property specified, our server will be standalone. We also allow a -JMX client (e.g. _Gfsh_) to connect to our server with the use of the GemFire-specific JMX System properties. -<4> Then we create an instance of a GemFire peer `Cache` initialized with our GemFire System Properties. -<5> We also setup a GemFire `CacheServer` instance running on *localhost*, listening to port **11235**, -ready to accept our client connection. -<6> Finally, we enable the same Spring Session functionality we used on the client by registering an instance of -`GemFireHttpSessionConfiguration`, except that we set the session expiration timeout to **30 seconds**. -We will explain later what this means. - -The GemFire Server configuration gets bootstrapped with the following: - -[source,java] ----- -include::{samples-dir}xml/gemfire-clientserver/src/main/java/sample/Application.java[tags=class] ----- - -TIP: Instead of a simple Java class with a main method, you could also use _Spring Boot_. - -<1> The `@Configuration` annotation designates this Java class as a source for Spring configuration meta-data using -Spring's annotation configuration support. -<2> Primarily, the configuration comes from the `META-INF/spring/session-server.xml` file, which is also the reason -why _Spring Boot_ was not used in this sample, since using XML seemingly defeats the purpose and benefits -of using Spring Boot. However, this sample is about demonstrating how to use Spring XML to configure -the GemFire client and server. - -== XML Servlet Container Initialization - -Our <> created a Spring bean named `springSessionRepositoryFilter` -that implements `Filter`. The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with -a custom implementation that is backed by Spring Session and GemFire. - -In order for our `Filter` to do its magic, we need to instruct Spring to load our `session-client.xml` configuration file. -We do this with the following configuration: - -.src/main/webapp/WEB-INF/web.xml -[source,xml,indent=0] ----- -include::{samples-dir}xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml[tags=context-param] -include::{samples-dir}xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml[tags=listeners] ----- - -The http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-create[ContextLoaderListener] -reads the `contextConfigLocation` context parameter value and picks up our _session-client.xml_ configuration file. - -Finally, we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` -for every request. - -The following snippet performs this last step for us: - -.src/main/webapp/WEB-INF/web.xml -[source,xml,indent=0] ----- -include::{samples-dir}xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml[tags=springSessionRepositoryFilter] ----- - -The http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html[DelegatingFilterProxy] -will look up a bean by the name of `springSessionRepositoryFilter` and cast it to a `Filter`. For every request that `DelegatingFilterProxy` -is invoked, the `springSessionRepositoryFilter` will be invoked. -// end::config[] - -[[httpsession-gemfire-clientserver-xml-sample-app]] -== HttpSession with GemFire (Client/Server) using XML Sample Application - - -=== Running the httpsession-gemfire-clientserver-xml Sample Application - -You can run the sample by obtaining the {download-url}[source code] and invoking the following commands. - -First, you need to run the server using: - ----- -$ ./gradlew :samples:httpsession-gemfire-clientserver-xml:run [-Dsample.httpsession.gemfire.log-level=info] ----- - -Now, in a separate terminal, you can run the client using: - ----- -$ ./gradlew :samples:httpsession-gemfire-clientserver-xml:tomcatRun [-Dsample.httpsession.gemfire.log-level=info] ----- - -You should now be able to access the application at http://localhost:8080/. In this sample, the web application -is the client cache and the server is standalone. - -=== Exploring the httpsession-gemfire-clientserver-xml Sample Application - -Try using the application. Fill out the form with the following information: - -* **Attribute Name:** _username_ -* **Attribute Value:** _john_ - -Now click the **Set Attribute** button. You should now see the values displayed in the table. - -=== How does it work? - -We interact with the standard `HttpSession` in the `SessionServlet` shown below: - -.src/main/java/sample/SessionServlet.java -[source,java] ----- -include::{samples-dir}xml/gemfire-clientserver/src/main/java/sample/SessionServlet.java[tags=class] ----- - -Instead of using Tomcat's `HttpSession`, we are actually persisting the values in GemFire. -Spring Session creates a cookie named SESSION in your browser that contains the id of your session. -Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] -or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]). - -NOTE: The following instructions assume you have a local GemFire installation. For more information on installation, -see http://gemfire.docs.pivotal.io/docs-gemfire/latest/getting_started/installation/install_intro.html[Installing Pivotal GemFire]. - -If you like, you can easily remove the session using `gfsh`. For example, on a Linux-based system type the following -at the command-line: - - $ gfsh - -Then, enter the following commands in _Gfsh_ ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value -of your SESSION cookie, or the session ID returned by the GemFire OQL query (which should match): - -.... -gfsh>connect --jmx-manager=localhost[1099] - -gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet' - -Result : true -startCount : 0 -endCount : 20 -Rows : 1 - -Result ------------------------------------- -70002719-3c54-4c20-82c3-e7faa6b718f3 - -NEXT_STEP_NAME : END - -gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3" -.... - -NOTE: The _GemFire User Guide_ has more detailed instructions on using http://gemfire.docs.pivotal.io/docs-gemfire/latest/tools_modules/gfsh/chapter_overview.html[gfsh]. - -Now visit the application at http://localhost:8080/ again and observe that the attribute we added is no longer displayed. - -Alternatively, you can wait *30 seconds* for the session to timeout (i.e. expire) and refresh the page. Again, the -attribute we added should no longer be displayed in the table. However, keep in mind, that by refreshing the page, -you will inadvertently create a new (empty) session. If you run the query again, you will also see two session IDs, -the new and the old, since GemFire keeps a "tombstone" of the old session around. diff --git a/docs/src/docs/asciidoc/guides/xml-gemfire-p2p.adoc b/docs/src/docs/asciidoc/guides/xml-gemfire-p2p.adoc deleted file mode 100644 index e4b09593..00000000 --- a/docs/src/docs/asciidoc/guides/xml-gemfire-p2p.adoc +++ /dev/null @@ -1,210 +0,0 @@ -= Spring Session - HttpSession with GemFire P2P using XML (Quick Start) -John Blum, Rob Winch -:toc: - -This guide describes how to configure Pivotal GemFire as a provider in Spring Session to transparently back -a web application's `HttpSession` using XML Configuration. - -NOTE: The completed guide can be found in the <>. - -== Updating Dependencies -Before using Spring Session, you must ensure that the required dependencies are included. -If you are using Maven, include the following `dependencies` in your _pom.xml_: - -.pom.xml -[source,xml] -[subs="verbatim,attributes"] ----- - - - - - org.springframework.session - spring-session-data-gemfire - {spring-session-version} - pom - - - org.springframework - spring-web - {spring-version} - - ----- - -ifeval::["{version-snapshot}" == "true"] -Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-snapshot - https://repo.spring.io/libs-snapshot - - ----- -endif::[] - -ifeval::["{version-milestone}" == "true"] -Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository. -If you are using Maven, include the following `repository` declaration in your _pom.xml_: - -.pom.xml -[source,xml] ----- - - - - - spring-milestone - https://repo.spring.io/libs-milestone - - ----- -endif::[] - -// tag::config[] -[[httpsession-spring-xml-configuration]] -== Spring XML Configuration - -After adding the required dependencies and repository declarations, we can create our Spring configuration. -The Spring configuration is responsible for creating a Servlet Filter that replaces the `HttpSession` -with an implementation backed by Spring Session and GemFire. - -Add the following Spring Configuration: - -.src/main/webapp/WEB-INF/spring/session.xml -[source,xml,indent=0] ----- -include::{samples-dir}xml/gemfire-p2p/src/main/webapp/WEB-INF/spring/session.xml[tags=beans] ----- - -<1> We use the combination of `` and `GemFireHttpSessionConfiguration` because Spring Session -does not yet provide XML Namespace support (see https://github.com/spring-projects/spring-session/issues/104[gh-104]). -This creates a Spring bean with the name of `springSessionRepositoryFilter` that implements `Filter`. The filter is what -replaces the `HttpSession` with an implementation backed by Spring Session. -In this instance, Spring Session is backed by GemFire. -<2> Then, we configure a GemFire peer cache using standard GemFire System properties. We give the GemFire data node -a name using the `name` property and set `mcast-port` to 0. With the absence of a `locators` property, this data node -will be a standalone server. GemFire's `log-level` is set using an application-specific System property -(`sample.httpsession.gemfire.log-level`) that a user can specify on the command-line when running this application -using either Maven or Gradle (default is "_warning_"). -<3> Finally, we create an instance of the GemFire peer cache that embeds GemFire in the same JVM process as the running -Spring Session sample application. - -TIP: Additionally, we have configured this data node (server) as a GemFire Manager as well using GemFire-specific -JMX System properties that enable JMX client (e.g. _Gfsh_) to connect to this running data node. - -NOTE: For more information on configuring _Spring Data GemFire_, refer to the http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[reference guide]. - -== XML Servlet Container Initialization - -Our <> created a Spring bean named `springSessionRepositoryFilter` -that implements `Filter`. The `springSessionRepositoryFilter` bean is responsible for replacing the `HttpSession` with -a custom implementation that is backed by Spring Session and GemFire. - -In order for our `Filter` to do its magic, we need to instruct Spring to load our `session.xml` configuration file. -We do this with the following configuration: - -.src/main/webapp/WEB-INF/web.xml -[source,xml,indent=0] ----- -include::{samples-dir}xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml[tags=context-param] -include::{samples-dir}xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml[tags=listeners] ----- - -The http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#context-create[ContextLoaderListener] -reads the `contextConfigLocation` context parameter value and picks up our _session.xml_ configuration file. - -Finally, we need to ensure that our Servlet Container (i.e. Tomcat) uses our `springSessionRepositoryFilter` -for every request. - -The following snippet performs this last step for us: - -.src/main/webapp/WEB-INF/web.xml -[source,xml,indent=0] ----- -include::{samples-dir}xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml[tags=springSessionRepositoryFilter] ----- - -The http://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/web/filter/DelegatingFilterProxy.html[DelegatingFilterProxy] -will look up a bean by the name of `springSessionRepositoryFilter` and cast it to a `Filter`. For every request that `DelegatingFilterProxy` -is invoked, the `springSessionRepositoryFilter` will be invoked. -// end::config[] - -[[httpsession-gemfire-p2p-xml-sample-app]] -== HttpSession with GemFire (P2P) using XML Sample Application - - -=== Running the httpsession-gemfire-p2p-xml Sample Application - -You can run the sample by obtaining the {download-url}[source code] and invoking the following command: - ----- -$ ./gradlew :samples:httpsession-gemfire-p2p-xml:tomcatRun [-Dsample.httpsession.gemfire.log-level=info] ----- - -You should now be able to access the application at http://localhost:8080/ - -=== Exploring the httpsession-gemfire-p2p-xml Sample Application - -Try using the application. Fill out the form with the following information: - -* **Attribute Name:** _username_ -* **Attribute Value:** _john_ - -Now click the **Set Attribute** button. You should now see the values displayed in the table. - -=== How does it work? - -We interact with the standard `HttpSession` in the `SessionServlet` shown below: - -.src/main/java/sample/SessionServlet.java -[source,java] ----- -include::{samples-dir}xml/gemfire-p2p/src/main/java/sample/SessionServlet.java[tags=class] ----- - -Instead of using Tomcat's `HttpSession`, we are actually persisting the values in GemFire. -Spring Session creates a cookie named SESSION in your browser that contains the id of your session. -Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome] -or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]). - -NOTE: The following instructions assume you have a local GemFire installation. For more information on installation, -see http://gemfire.docs.pivotal.io/docs-gemfire/latest/getting_started/installation/install_intro.html[Installing Pivotal GemFire]. - -If you like, you can easily remove the session using `gfsh`. For example, on a Linux-based system type the following -at the command-line: - - $ gfsh - -Then, enter the following into _Gfsh_ ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value -of your SESSION cookie, or the session ID returned by the GemFire OQL query (which should match): - -.... -gfsh>connect --jmx-manager=localhost[1099] - -gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet' - -Result : true -startCount : 0 -endCount : 20 -Rows : 1 - -Result ------------------------------------- -70002719-3c54-4c20-82c3-e7faa6b718f3 - -NEXT_STEP_NAME : END - -gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3" -.... - -NOTE: The _GemFire User Guide_ has more detailed instructions on using http://gemfire.docs.pivotal.io/docs-gemfire/latest/tools_modules/gfsh/chapter_overview.html[gfsh]. - -Now visit the application at http://localhost:8080/ and observe that the attribute we added is no longer displayed. diff --git a/docs/src/docs/asciidoc/index.adoc b/docs/src/docs/asciidoc/index.adoc index 4a844607..7f78125c 100644 --- a/docs/src/docs/asciidoc/index.adoc +++ b/docs/src/docs/asciidoc/index.adoc @@ -52,10 +52,6 @@ If you are looking to get started with Spring Session, the best place to start i | Demonstrates how to use Spring Session to replace the `HttpSession` with Redis. | link:guides/boot.html[HttpSession with Redis Guide] -| {gh-samples-url}boot/gemfire[HttpSession with GemFire] -| Demonstrates how to use Spring Session to replace the `HttpSession` with GemFire using a Client/Server topology. -| link:guides/boot-gemfire.html[HttpSession with GemFire Guide] - | {gh-samples-url}boot/mongo[HttpSession with Mongo] | Demonstrates how to use Spring Session to replace the `HttpSession` with Mongo. | link:guides/boot-mongo.html[HttpSession with Mongo Guide] @@ -86,14 +82,6 @@ If you are looking to get started with Spring Session, the best place to start i | Demonstrates how to use Spring Session to replace the `HttpSession` with Redis. | link:guides/java-redis.html[HttpSession with Redis Guide] -| {gh-samples-url}javaconfig/gemfire-clientserver[HttpSession with GemFire (Client/Server)] -| Demonstrates how to use Spring Session to replace the `HttpSession` with GemFire using a Client/Server topology. -| link:guides/java-gemfire-clientserver.html[HttpSession with GemFire (Client/Server) Guide] - -| {gh-samples-url}javaconfig/gemfire-p2p[HttpSession with GemFire (P2P)] -| Demonstrates how to use Spring Session to replace the `HttpSession` with GemFire using a P2P topology. -| link:guides/java-gemfire-p2p.html[HttpSession with GemFire (P2P) Guide] - | {gh-samples-url}javaconfig/jdbc[HttpSession with JDBC] | Demonstrates how to use Spring Session to replace the `HttpSession` with a relational database store. | link:guides/java-jdbc.html[HttpSession with JDBC Guide] @@ -128,14 +116,6 @@ If you are looking to get started with Spring Session, the best place to start i | Demonstrates how to use Spring Session to replace the `HttpSession` with a Redis store. | link:guides/xml-redis.html[HttpSession with Redis Guide] -| {gh-samples-url}xml/gemfire-clientserver[HttpSession with GemFire (Client/Server)] -| Demonstrates how to use Spring Session to replace the `HttpSession` with GemFire using a Client/Server topology. -| link:guides/xml-gemfire-clientserver.html[HttpSession with GemFire (Client/Server) Guide] - -| {gh-samples-url}xml/gemfire-p2p[HttpSession with GemFire (P2P)] -| Demonstrates how to use Spring Session to replace the `HttpSession` with GemFire using a P2P topology. -| link:guides/xml-gemfire-p2p.html[HttpSession with GemFire (P2P) Guide] - | {gh-samples-url}xml/jdbc[HttpSession with JDBC] | Demonstrates how to use Spring Session to replace the `HttpSession` with a relational database store. | link:guides/xml-jdbc.html[HttpSession with JDBC Guide] @@ -200,110 +180,6 @@ You can read the basic steps for integration below, but you are encouraged to fo include::guides/xml-redis.adoc[tags=config,leveloffset=+3] -[[httpsession-gemfire]] -=== HttpSession with Pivotal GemFire - -When https://pivotal.io/big-data/pivotal-gemfire[Pivotal GemFire] is used with Spring Session, a web application's -`HttpSession` can be replaced with a **clustered** implementation managed by GemFire and conveniently accessed -with Spring Session's API. - -The two most common topologies to manage Spring Sessions using GemFire include: - -* <> -* <> - -Additionally, GemFire supports site-to-site replication using http://gemfire.docs.pivotal.io/docs-gemfire/topologies_and_comm/multi_site_configuration/chapter_overview.html[WAN functionality]. -The ability to configure and use GemFire's WAN support is independent of Spring Session, and is beyond the scope -of this document. More details on GemFire WAN functionality can be found http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/#bootstrap:gateway[here]. - -[[httpsession-gemfire-clientserver]] -==== GemFire Client-Server - -The http://gemfire.docs.pivotal.io/docs-gemfire/latest/topologies_and_comm/cs_configuration/chapter_overview.html[Client-Server] -topology will probably be the more common configuration preference for users when using GemFire as a provider in -Spring Session since a GemFire server will have significantly different and unique JVM heap requirements when compared -to the application. Using a client-server topology enables an application to manage (e.g. replicate) application state -independently from other application processes. - -In a client-server topology, an application using Spring Session will open a client cache connection to a (remote) -GemFire server cluster to manage and provide consistent access to all `HttpSession` state. - -You can configure a Client-Server topology with either: - -* <> -* <> - -[[httpsession-gemfire-clientserver-java]] -===== GemFire Client-Server Java-based Configuration - -This section describes how to use GemFire's Client-Server topology to back an `HttpSession` with Java-based configuration. - -NOTE: The <> provides a working sample on how to integrate -Spring Session and GemFire to replace the HttpSession using Java configuration. You can read the basic steps for -integration below, but you are encouraged to follow along with the detailed HttpSession with GemFire (Client-Server) -Guide when integrating with your own application. - -include::guides/java-gemfire-clientserver.adoc[tags=config,leveloffset=+3] - -[[http-session-gemfire-clientserver-xml]] -===== GemFire Client-Server XML-based Configuration - -This section describes how to use GemFire's Client-Server topology to back an `HttpSession` with XML-based configuration. - -NOTE: The <> provides a working sample on how to -integrate Spring Session and GemFire to replace the `HttpSession` using XML configuration. You can read the basic steps -for integration below, but you are encouraged to follow along with the detailed HttpSession with GemFire (Client-Server) -using XML Guide when integrating with your own application. - -include::guides/xml-gemfire-clientserver.adoc[tags=config,leveloffset=+3] - -[[httpsession-gemfire-p2p]] -==== GemFire Peer-To-Peer (P2P) - -Perhaps less common would be to configure the Spring Session application as a peer member in the GemFire cluster using -the http://gemfire.docs.pivotal.io/docs-gemfire/latest/topologies_and_comm/p2p_configuration/chapter_overview.html[Peer-To-Peer (P2P)] topology. -In this configuration, a Spring Session application would be an actual data node (server) in the GemFire cluster, -and **not** a cache client as before. - -One advantage to this approach is the proximity of the application to the application's state (i.e. it's data). However, -there are other effective means of accomplishing similar data dependent computations, such as using GemFire's -http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/function_exec/chapter_overview.html[Function Execution]. -Any of GemFire's other http://gemfire.docs.pivotal.io/docs-gemfire/latest/getting_started/product_intro.html[features] -can be used when GemFire is serving as a provider in Spring Session. - -P2P is very useful for both testing purposes as well as smaller, more focused and self-contained applications, -such as those found in a microservices architecture, and will most certainly improve on your application's latency, -throughput and consistency needs. - -You can configure a Peer-To-Peer (P2P) topology with either: - -* <> -* <> - -[[httpsession-gemfire-p2p-java]] -===== GemFire Peer-To-Peer (P2P) Java-based Configuration - -This section describes how to use GemFire's Peer-To-Peer (P2P) topology to back an `HttpSession` using Java-based configuration. - -NOTE: The <> provides a working sample on how to integrate -Spring Session and GemFire to replace the `HttpSession` using Java configuration. You can read the basic steps -for integration below, but you are encouraged to follow along with the detailed HttpSession with GemFire (P2P) Guide -when integrating with your own application. - -include::guides/java-gemfire-p2p.adoc[tags=config,leveloffset=+3] - -[[httpsession-gemfire-p2p-xml]] -===== GemFire Peer-To-Peer (P2P) XML-based Configuration - -This section describes how to use GemFire's Peer-To-Peer (P2P) topology to back an `HttpSession` using XML-based configuration. - -NOTE: The <> provides a working sample on how to integrate -Spring Session and GemFire to replace the `HttpSession` using XML configuration. You can read the basic steps for -integration below, but you are encouraged to follow along with the detailed HttpSession with GemFire (P2P) using XML -Guide when integrating with your own application. - -include::guides/xml-gemfire-p2p.adoc[tags=config,leveloffset=+3] - [[httpsession-jdbc]] === HttpSession with JDBC @@ -952,89 +828,6 @@ redis 127.0.0.1:6379> hget spring:session:sessions:4fc39ce3-63b3-4e17-b1c4-5e1ed "\xac\xed\x00\x05t\x00\x03rob" ---- -[[api-gemfireoperationssessionrepository]] -=== GemFireOperationsSessionRepository - -`GemFireOperationsSessionRepository` is a `SessionRepository` that is implemented using Spring Data's `GemFireOperationsSessionRepository`. -In a web environment, this is typically used in combination with `SessionRepositoryFilter`. -The implementation supports `SessionDestroyedEvent` and `SessionCreatedEvent` through `SessionMessageListener`. - -[[api-gemfireoperationssessionrepository-indexing]] -==== Using Indexes with GemFire - -While best practices concerning the proper definition of indexes that positively impact GemFire's performance is beyond -the scope of this document, it is important to realize that Spring Session Data GemFire creates and uses indexes to -query and find Sessions efficiently. - -Out-of-the-box, Spring Session Data GemFire creates 1 Hash-typed Index on the principal name. There are two different buit in -strategies for finding the principal name. The first strategy is that the value of the session attribute with the name -`FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME` will be indexed to the same index name. For example: - -[source,java,indent=0] ----- -include::{docs-itest-dir}docs/http/HttpSessionGemFireIndexingITests.java[tags=findbyindexname-set] -include::{docs-itest-dir}docs/http/HttpSessionGemFireIndexingITests.java[tags=findbyindexname-get] ----- - -[[api-gemfireoperationssessionrepository-indexing-security]] -==== Using Indexes with GemFire & Spring Security - -Alternatively, Spring Session Data GemFire will map Spring Security's current `Authentication#getName()` to the index -`FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME`. For example, if you are using Spring Security you can -find the current user's sessions using: - -[source,java,indent=0] ----- -include::{docs-itest-dir}docs/http/HttpSessionGemFireIndexingITests.java[tags=findbyspringsecurityindexname-context] -include::{docs-itest-dir}docs/http/HttpSessionGemFireIndexingITests.java[tags=findbyspringsecurityindexname-get] ----- - -[[api-gemfireoperationssessionrepository-indexing-custom]] -==== Using Custom Indexes with GemFire - -This enables developers using the `GemFireOperationsSessionRepository` programmatically to query and find all Sessions -with a given principal name efficiently. - -Additionally, Spring Session Data GemFire will create a Range-based Index on the implementing Session's Map-type -`attributes` property (i.e. on any arbitrary Session attribute) when a developer identifies 1 or more named Session -attributes that should be indexed by GemFire. - -Sessions attributes to index can be specified with the `indexableSessionAttributes` attribute on the `@EnableGemFireHttpSession` -annotation. A developer adds this annotation to their Spring application `@Configuration` class when s/he wishes to -enable Spring Session support for HttpSession backed by GemFire. - -For example, the following configuration: - -[source,java,indent=0] ----- -include::{docs-itest-dir}docs/http/gemfire/indexablesessionattributes/GemFireHttpSessionConfig.java[tags=class-start] - // ... -} ----- - -will allow searching for sessions using the following: - -[source,java,indent=0] ----- -include::{docs-itest-dir}docs/http/gemfire/indexablesessionattributes/HttpSessionGemFireIndexingCustomITests.java[tags=findbyindexname-set] -include::{docs-itest-dir}docs/http/gemfire/indexablesessionattributes/HttpSessionGemFireIndexingCustomITests.java[tags=findbyindexname-get] ----- - -NOTE: Only Session attribute names identified in the `@EnableGemFireHttpSession` annotation's `indexableSessionAttributes` -attribute will have an Index defined. All other Session attributes will not be indexed. - -However, there is one caveat. Any values stored in indexable Session attributes must implement the `java.lang.Comparable` -interface. If those object values do not implement `Comparable`, then GemFire will throw an error on startup when the -Index is defined for Regions with persistent Session data, or when an attempt is made at runtime to assign the indexable -Session attribute a value that is not `Comparable` and the Session is saved to GemFire. - -NOTE: Any Session attribute that is not indexed may store non-`Comparable` values. - -To learn more about GemFire's Range-based Indexes, see http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/query_index/creating_map_indexes.html[Creating Indexes on Map Fields]. - -To learn more about GemFire Indexing in general, see http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/query_index/query_index.html[Working with Indexes]. - - [[api-mapsessionrepository]] === MapSessionRepository diff --git a/docs/src/integration-test/java/docs/http/HttpSessionGemFireIndexingITests.java b/docs/src/integration-test/java/docs/http/HttpSessionGemFireIndexingITests.java deleted file mode 100644 index 20510cc9..00000000 --- a/docs/src/integration-test/java/docs/http/HttpSessionGemFireIndexingITests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package docs.http; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.gemfire.config.annotation.PeerCacheApplication; -import org.springframework.security.core.Authentication; -import org.springframework.security.core.context.SecurityContext; -import org.springframework.security.core.context.SecurityContextHolder; -import org.springframework.security.test.context.support.WithMockUser; -import org.springframework.security.web.context.HttpSessionSecurityContextRepository; -import org.springframework.session.ExpiringSession; -import org.springframework.session.FindByIndexNameSessionRepository; -import org.springframework.session.data.gemfire.GemFireOperationsSessionRepository; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Rob Winch - * @author John Blum - */ -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = HttpSessionGemFireIndexingITests.Config.class) -public class HttpSessionGemFireIndexingITests { - - @Autowired - private GemFireOperationsSessionRepository sessionRepository; - - @Test - public void findByIndexName() { - ExpiringSession session = this.sessionRepository.createSession(); - String username = "HttpSessionGemFireIndexingITests-findByIndexName-username"; - - // tag::findbyindexname-set[] - String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME; - - session.setAttribute(indexName, username); - // end::findbyindexname-set[] - - this.sessionRepository.save(session); - - // tag::findbyindexname-get[] - Map idToSessions = - this.sessionRepository.findByIndexNameAndIndexValue(indexName, username); - // end::findbyindexname-get[] - - assertThat(idToSessions.keySet()).containsOnly(session.getId()); - - this.sessionRepository.delete(session.getId()); - } - - @Test - @WithMockUser("HttpSessionGemFireIndexingITests-findBySpringSecurityIndexName") - public void findBySpringSecurityIndexName() { - ExpiringSession session = this.sessionRepository.createSession(); - - // tag::findbyspringsecurityindexname-context[] - SecurityContext context = SecurityContextHolder.getContext(); - Authentication authentication = context.getAuthentication(); - // end::findbyspringsecurityindexname-context[] - - session.setAttribute(HttpSessionSecurityContextRepository.SPRING_SECURITY_CONTEXT_KEY, context); - this.sessionRepository.save(session); - - // tag::findbyspringsecurityindexname-get[] - String indexName = FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME; - Map idToSessions = - this.sessionRepository.findByIndexNameAndIndexValue(indexName, authentication.getName()); - // end::findbyspringsecurityindexname-get[] - - assertThat(idToSessions.keySet()).containsOnly(session.getId()); - - this.sessionRepository.delete(session.getId()); - } - - @PeerCacheApplication(name = "HttpSessionGemFireIndexingITests", logLevel = "error") - @EnableGemFireHttpSession(regionName = "HttpSessionGemFireIndexingTestRegion") - static class Config { - } -} diff --git a/docs/src/integration-test/java/docs/http/gemfire/indexablesessionattributes/HttpSessionGemFireIndexingCustomITests.java b/docs/src/integration-test/java/docs/http/gemfire/indexablesessionattributes/HttpSessionGemFireIndexingCustomITests.java deleted file mode 100644 index 1d96d02d..00000000 --- a/docs/src/integration-test/java/docs/http/gemfire/indexablesessionattributes/HttpSessionGemFireIndexingCustomITests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package docs.http.gemfire.indexablesessionattributes; - -import java.util.Map; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.data.gemfire.config.annotation.PeerCacheApplication; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.GemFireOperationsSessionRepository; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Rob Winch - * @author John Blum - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = HttpSessionGemFireIndexingCustomITests.Config.class) -public class HttpSessionGemFireIndexingCustomITests { - - @Autowired - private GemFireOperationsSessionRepository sessionRepository; - - @Test - public void findByIndexName() { - ExpiringSession session = this.sessionRepository.createSession(); - String attrValue = "HttpSessionGemFireIndexingCustomITests-findByIndexName"; - - // tag::findbyindexname-set[] - String indexName = "name1"; - session.setAttribute(indexName, attrValue); - // end::findbyindexname-set[] - - this.sessionRepository.save(session); - - // tag::findbyindexname-get[] - Map idToSessions = - this.sessionRepository.findByIndexNameAndIndexValue(indexName, attrValue); - // end::findbyindexname-get[] - - assertThat(idToSessions.keySet()).containsOnly(session.getId()); - - this.sessionRepository.delete(session.getId()); - } - - @PeerCacheApplication(name = "HttpSessionGemFireIndexingCustomITests", logLevel = "error") - @EnableGemFireHttpSession(indexableSessionAttributes = { "name1", "name2", "name3" }, - regionName = "HttpSessionGemFireIndexingCustomTestRegion") - static class Config { - } -} diff --git a/gradle/spring3.gradle b/gradle/spring3.gradle index a2551ae0..14880836 100644 --- a/gradle/spring3.gradle +++ b/gradle/spring3.gradle @@ -13,9 +13,6 @@ configurations.spring3TestRuntime { if (details.requested.name == 'spring-data-commons') { details.useVersion '1.12.1.RELEASE' } - if (details.requested.name == 'spring-data-gemfire') { - details.useVersion '1.8.1.RELEASE' - } if (details.requested.name == 'spring-data-keyvalue') { details.useVersion '1.1.1.RELEASE' } diff --git a/samples/boot/gemfire/spring-session-sample-boot-gemfire.gradle b/samples/boot/gemfire/spring-session-sample-boot-gemfire.gradle deleted file mode 100644 index 9765a9f1..00000000 --- a/samples/boot/gemfire/spring-session-sample-boot-gemfire.gradle +++ /dev/null @@ -1,87 +0,0 @@ -apply plugin: 'io.spring.convention.spring-sample-boot' -apply plugin: "application" - -dependencies { - compile project(':spring-session-data-gemfire') - compile "org.springframework.boot:spring-boot-starter-thymeleaf" - compile "org.springframework.boot:spring-boot-starter-web" - compile "org.webjars:bootstrap" - compile "org.webjars:webjars-locator" - - runtime "org.springframework.shell:spring-shell" - - testCompile "org.springframework.boot:spring-boot-starter-test" - - integrationTestCompile seleniumDependencies - - integrationTestRuntime "org.springframework.shell:spring-shell" -} - -run { - doFirst { - mainClassName = 'sample.server.GemFireServer' - } -} - -bootJar { - mainClass = 'sample.client.Application' -} - -task runGemFireServer() { - doLast { - ext.port = reservePort() - - println "Starting GemFire Server on port [$port] ..." - - def out = new StringBuilder() - def err = new StringBuilder() - - String classpath = sourceSets.main.runtimeClasspath.collect { it }.join(File.pathSeparator) - - String[] commandLine = [ - 'java', '-server', '-ea', '-classpath', classpath, - //"-Dgemfire.log-file=gemfire-server.log", - //"-Dgemfire.log-level=config", - "-Dspring-session-data-gemfire.cache.server.port=$port", - "-Dspring-session-data-gemfire.log.level=" - + System.getProperty('spring-session-data-gemfire.log.level', 'warning'), - 'sample.server.GemFireServer' - ] - - //println commandLine - - ext.process = commandLine.execute() - //ext.process = new ProcessBuilder().command(commandLine).redirectErrorStream(true).start(); - - ext.process.consumeProcessOutput(out, err) - - //println 'OUT: ' + out - //println 'ERR: ' + err - } -} - - -integrationTest { - dependsOn runGemFireServer - doFirst { - def port = reservePort() - systemProperties['management.port'] = 0 - systemProperties['server.port'] = port - //systemProperties['gemfire.log-file'] = "gemfire-client.log" - //systemProperties['gemfire.log-level'] = "config" - systemProperties['spring-session-data-gemfire.cache.server.port'] = runGemFireServer.port - systemProperties['spring-session-data-gemfire.log.level'] = System.getProperty("spring-session-data-gemfire.log.level", "warning") - } - doLast { - println 'Stopping GemFire Server...' - runGemFireServer.process?.destroyForcibly() - } -} - - -def reservePort() { - def socket = new ServerSocket(0) - def result = socket.localPort - socket.close() - result -} diff --git a/samples/boot/gemfire/src/integration-test/java/sample/AttributeTests.java b/samples/boot/gemfire/src/integration-test/java/sample/AttributeTests.java deleted file mode 100644 index 6db2fac7..00000000 --- a/samples/boot/gemfire/src/integration-test/java/sample/AttributeTests.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.openqa.selenium.WebDriver; -import sample.client.Application; -import sample.pages.HomePage; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.web.servlet.MockMvc; -import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.MOCK) -@AutoConfigureMockMvc -public class AttributeTests { - - @Autowired - private MockMvc mockMvc; - - private WebDriver driver; - - @Before - public void setup() { - this.driver = MockMvcHtmlUnitDriverBuilder.mockMvcSetup(this.mockMvc).build(); - } - - @After - public void tearDown() { - this.driver.quit(); - } - - @Test - public void noAttributes() { - HomePage home = HomePage.go(this.driver, HomePage.class); - assertThat(home.attributes().size()).isEqualTo(0); - } - - @Test - public void createAttribute() { - HomePage home = HomePage.go(this.driver, HomePage.class); - home = home.form() - .attributeName("a") - .attributeValue("b") - .submit(HomePage.class); - assertThat(home.attributes()).extracting("attributeName").containsOnly("requestCount", "a"); - assertThat(home.attributes()).extracting("attributeValue").containsOnly("1", "b"); - } -} diff --git a/samples/boot/gemfire/src/integration-test/java/sample/pages/HomePage.java b/samples/boot/gemfire/src/integration-test/java/sample/pages/HomePage.java deleted file mode 100644 index 0f43fda0..00000000 --- a/samples/boot/gemfire/src/integration-test/java/sample/pages/HomePage.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.pages; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.openqa.selenium.By; -import org.openqa.selenium.Cookie; -import org.openqa.selenium.SearchContext; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - * @author Rob Winch - */ -public class HomePage { - - private WebDriver driver; - - @FindBy(tagName = "form") - WebElement form; - - @FindBy(css = "table tbody tr") - List trs; - - List attributes; - - public HomePage(WebDriver driver) { - this.driver = driver; - this.attributes = new ArrayList(); - } - - private static void get(WebDriver driver, String get) { - String baseUrl = "http://localhost:" + System.getProperty("app.port", "8080"); - driver.get(baseUrl + get); - } - - public static T go(WebDriver driver, Class page) { - get(driver, "/"); - return PageFactory.initElements(driver, page); - } - - public void containCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").contains(cookieName); - } - - public void doesNotContainCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").doesNotContain(cookieName); - } - - public HomePage logout() { - WebElement logout = this.driver - .findElement(By.cssSelector("input[type=\"submit\"]")); - logout.click(); - return PageFactory.initElements(this.driver, HomePage.class); - } - - public List attributes() { - List rows = new ArrayList(); - for (WebElement tr : this.trs) { - rows.add(new Attribute(tr)); - } - this.attributes.addAll(rows); - return this.attributes; - } - - public Form form() { - return new Form(this.form); - } - - public class Form { - @FindBy(name = "attributeName") - WebElement attributeName; - - @FindBy(name = "attributeValue") - WebElement attributeValue; - - @FindBy(css = "input[type=\"submit\"]") - WebElement submit; - - public Form(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - public Form attributeName(String text) { - this.attributeName.sendKeys(text); - return this; - } - - public Form attributeValue(String text) { - this.attributeValue.sendKeys(text); - return this; - } - - public T submit(Class page) { - this.submit.click(); - return PageFactory.initElements(HomePage.this.driver, page); - } - } - - public static class Attribute { - @FindBy(xpath = ".//td[1]") - WebElement attributeName; - - @FindBy(xpath = ".//td[2]") - WebElement attributeValue; - - public Attribute(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - /** - * @return the attributeName - */ - public String getAttributeName() { - return this.attributeName.getText(); - } - - /** - * @return the attributeValue - */ - public String getAttributeValue() { - return this.attributeValue.getText(); - } - } - -} diff --git a/samples/boot/gemfire/src/main/java/sample/client/Application.java b/samples/boot/gemfire/src/main/java/sample/client/Application.java deleted file mode 100644 index b296d2aa..00000000 --- a/samples/boot/gemfire/src/main/java/sample/client/Application.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.client; - -import java.util.Collections; -import java.util.Enumeration; -import java.util.HashMap; -import java.util.Iterator; -import java.util.Map; -import java.util.Properties; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import javax.servlet.http.HttpSession; - -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.Pool; -import org.apache.geode.cache.client.PoolManager; -import org.apache.geode.cache.client.internal.PoolImpl; -import org.apache.geode.management.membership.ClientMembership; -import org.apache.geode.management.membership.ClientMembershipEvent; -import org.apache.geode.management.membership.ClientMembershipListenerAdapter; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.client.ClientCacheFactoryBean; -import org.springframework.data.gemfire.config.xml.GemfireConstants; -import org.springframework.data.gemfire.support.ConnectionEndpoint; -import org.springframework.data.gemfire.util.CollectionUtils; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.RequestParam; -import org.springframework.web.bind.annotation.ResponseBody; - -/** - * A Spring Boot, GemFire cache client, web application that reveals the current state of the HTTP Session. - * - * @author John Blum - * @see javax.servlet.http.HttpSession - * @see org.springframework.boot.SpringApplication - * @see org.springframework.boot.autoconfigure.SpringBootApplication - * @see org.springframework.context.annotation.Bean - * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession - * @see org.springframework.stereotype.Controller - * @see org.apache.geode.cache.client.ClientCache - * @see org.apache.geode.cache.client.Pool - * @since 1.2.1 - */ -// tag::class[] -@SpringBootApplication -@EnableGemFireHttpSession(poolName = "DEFAULT")// <1> -@Controller -public class Application { - - static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(60); - - static final CountDownLatch LATCH = new CountDownLatch(1); - - static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning"; - static final String GEMFIRE_DEFAULT_POOL_NAME = "DEFAULT"; - static final String INDEX_TEMPLATE_VIEW_NAME = "index"; - static final String PING_RESPONSE = "PONG"; - static final String REQUEST_COUNT_ATTRIBUTE_NAME = "requestCount"; - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } - - @Bean - static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { // <2> - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", applicationName()); - //gemfireProperties.setProperty("log-file", "gemfire-client.log"); - gemfireProperties.setProperty("log-level", logLevel()); - - return gemfireProperties; - } - - String applicationName() { - return "spring-session-data-gemfire-boot-sample.".concat(getClass().getSimpleName()); - } - - String logLevel() { - return System.getProperty("spring-session-data-gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL); - } - - @Bean - ClientCacheFactoryBean gemfireCache( - @Value("${spring-session-data-gemfire.cache.server.host:localhost}") String host, - @Value("${spring-session-data-gemfire.cache.server.port:12480}") int port) { // <3> - - ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - // GemFire Pool settings <4> - gemfireCache.setKeepAlive(false); - gemfireCache.setPingInterval(TimeUnit.SECONDS.toMillis(5)); - gemfireCache.setReadTimeout(intValue(TimeUnit.SECONDS.toMillis(15))); - gemfireCache.setRetryAttempts(1); - gemfireCache.setSubscriptionEnabled(true); - gemfireCache.setThreadLocalConnections(false); - gemfireCache.setServers(Collections.singletonList(newConnectionEndpoint(host, port))); - - registerClientMembershipListener(); // <5> - - return gemfireCache; - } - - int intValue(Number number) { - return number.intValue(); - } - - ConnectionEndpoint newConnectionEndpoint(String host, int port) { - return new ConnectionEndpoint(host, port); - } - - void registerClientMembershipListener() { - ClientMembership.registerClientMembershipListener(new ClientMembershipListenerAdapter() { - @Override - public void memberJoined(ClientMembershipEvent event) { - LATCH.countDown(); - } - }); - } - - @Bean - BeanPostProcessor gemfireClientServerReadyBeanPostProcessor( - @Value("${spring-session-data-gemfire.cache.server.host:localhost}") final String host, - @Value("${spring-session-data-gemfire.cache.server.port:12480}") final int port) { // <5> - - return new BeanPostProcessor() { - - private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true); - private final AtomicReference defaultPool = new AtomicReference(null); - - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) { - try { - validateCacheClientNotified(); - validateCacheClientSubscriptionQueueConnectionEstablished(); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - return bean; - } - - private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) { - return (isGemFireRegion(bean, beanName) - ? checkGemFireServerIsRunning.compareAndSet(true, false) - : whenGemFireCache(bean, beanName)); - } - - private boolean isGemFireRegion(Object bean, String beanName) { - return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName) - || bean instanceof Region); - } - - private boolean whenGemFireCache(Object bean, String beanName) { - if (bean instanceof ClientCache) { - defaultPool.compareAndSet(null, ((ClientCache) bean).getDefaultPool()); - } - - return false; - } - - private void validateCacheClientNotified() throws InterruptedException { - boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - - Assert.state(didNotTimeout, String.format( - "GemFire Cache Server failed to start on host [%s] and port [%d]", host, port)); - } - - @SuppressWarnings("all") - private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException { - boolean cacheClientSubscriptionQueueConnectionEstablished = false; - - Pool pool = defaultIfNull(this.defaultPool.get(), GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, - GEMFIRE_DEFAULT_POOL_NAME); - - if (pool instanceof PoolImpl) { - long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT); - - while (System.currentTimeMillis() < timeout - && !((PoolImpl) pool).isPrimaryUpdaterAlive()) { - - synchronized (pool) { - TimeUnit.MILLISECONDS.timedWait(pool, 500L); - } - - } - - cacheClientSubscriptionQueueConnectionEstablished |= - ((PoolImpl) pool).isPrimaryUpdaterAlive(); - } - - Assert.state(cacheClientSubscriptionQueueConnectionEstablished, String.format( - "Cache client subscription queue connection not established; GemFire Pool was [%s];" - + " GemFire Pool configuration was [locators = %s, servers = %s]", - pool, pool.getLocators(), pool.getServers())); - } - - private Pool defaultIfNull(Pool pool, String... poolNames) { - for (String poolName : poolNames) { - pool = (pool != null ? pool : PoolManager.find(poolName)); - } - - return pool; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - }; - } - - @RequestMapping("/") - public String index() { // <6> - return INDEX_TEMPLATE_VIEW_NAME; - } - - @RequestMapping(method = RequestMethod.GET, path = "/ping") - @ResponseBody - public String ping() { // <7> - return PING_RESPONSE; - } - - @RequestMapping(method = RequestMethod.POST, path = "/session") - public String session(HttpSession session, ModelMap modelMap, - @RequestParam(name = "attributeName", required = false) String name, - @RequestParam(name = "attributeValue", required = false) String value) { // <8> - - modelMap.addAttribute("sessionAttributes", attributes(setAttribute(updateRequestCount(session), name, value))); - - return INDEX_TEMPLATE_VIEW_NAME; - } - // end::class[] - - /* (non-Javadoc) */ - @SuppressWarnings("all") - HttpSession updateRequestCount(HttpSession session) { - synchronized (session) { - Integer currentRequestCount = (Integer) session.getAttribute(REQUEST_COUNT_ATTRIBUTE_NAME); - session.setAttribute(REQUEST_COUNT_ATTRIBUTE_NAME, nullSafeIncrement(currentRequestCount)); - return session; - } - } - - /* (non-Javadoc) */ - Integer nullSafeIncrement(Integer value) { - return (nullSafeIntValue(value) + 1); - } - - /* (non-Javadoc) */ - int nullSafeIntValue(Number value) { - return (value != null ? value.intValue() : 0); - } - - /* (non-Javadoc) */ - HttpSession setAttribute(HttpSession session, String attributeName, String attributeValue) { - if (isSet(attributeName, attributeValue)) { - session.setAttribute(attributeName, attributeValue); - } - - return session; - } - - /* (non-Javadoc) */ - boolean isSet(String... values) { - boolean set = true; - - for (String value : values) { - set &= StringUtils.hasText(value); - } - - return set; - } - - /* (non-Javadoc) */ - Map attributes(HttpSession session) { - Map sessionAttributes = new HashMap(); - - for (String attributeName : toIterable(session.getAttributeNames())) { - sessionAttributes.put(attributeName, String.valueOf(session.getAttribute(attributeName))); - } - - return sessionAttributes; - } - - /* (non-Javadoc) */ - Iterable toIterable(final Enumeration enumeration) { - return new Iterable() { - public Iterator iterator() { - return (enumeration == null ? Collections.emptyIterator() - : CollectionUtils.toIterator(enumeration)); - } - }; - } -} diff --git a/samples/boot/gemfire/src/main/java/sample/server/GemFireServer.java b/samples/boot/gemfire/src/main/java/sample/server/GemFireServer.java deleted file mode 100644 index 0f65756b..00000000 --- a/samples/boot/gemfire/src/main/java/sample/server/GemFireServer.java +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.server; - -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.Cache; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.data.gemfire.server.CacheServerFactoryBean; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; - -/** - * A Spring Boot application bootstrapping a GemFire Cache Server JVM process. - * - * @author John Blum - * @see org.springframework.boot.SpringApplication - * @see org.springframework.boot.autoconfigure.SpringBootApplication - * @see org.springframework.context.annotation.Bean - * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession - * @see org.apache.geode.cache.Cache - * @since 1.2.1 - */ -// tag::class[] -@SpringBootApplication -@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 20) // <1> -public class GemFireServer { - - static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning"; - - public static void main(String[] args) { - SpringApplication springApplication = new SpringApplication(GemFireServer.class); - springApplication.setWebEnvironment(false); - springApplication.run(args); - } - - @Bean - static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { // <2> - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", applicationName()); - //gemfireProperties.setProperty("log-file", "gemfire-server.log"); - gemfireProperties.setProperty("log-level", logLevel()); - //gemfireProperties.setProperty("jmx-manager", "true"); - //gemfireProperties.setProperty("jmx-manager-start", "true"); - - return gemfireProperties; - } - - String applicationName() { - return "spring-session-data-gemfire-boot-sample:".concat(getClass().getSimpleName()); - } - - String logLevel() { - return System.getProperty("spring-session-data-gemfire.log.level", DEFAULT_GEMFIRE_LOG_LEVEL); - } - - @Bean - CacheFactoryBean gemfireCache() { // <3> - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, - @Value("${spring-session-data-gemfire.cache.server.bind-address:localhost}") String bindAddress, - @Value("${spring-session-data-gemfire.cache.server.hostname-for-clients:localhost}") String hostnameForClients, - @Value("${spring-session-data-gemfire.cache.server.port:12480}") int port) { // <4> - - CacheServerFactoryBean gemfireCacheServer = new CacheServerFactoryBean(); - - gemfireCacheServer.setAutoStartup(true); - gemfireCacheServer.setBindAddress(bindAddress); - gemfireCacheServer.setCache(gemfireCache); - gemfireCacheServer.setHostNameForClients(hostnameForClients); - gemfireCacheServer.setMaxTimeBetweenPings(Long.valueOf(TimeUnit.SECONDS.toMillis(60)).intValue()); - gemfireCacheServer.setPort(port); - - return gemfireCacheServer; - } -} -// end::class[] diff --git a/samples/boot/gemfire/src/main/java/sample/server/NativeGemFireServer.java b/samples/boot/gemfire/src/main/java/sample/server/NativeGemFireServer.java deleted file mode 100644 index 80d11e34..00000000 --- a/samples/boot/gemfire/src/main/java/sample/server/NativeGemFireServer.java +++ /dev/null @@ -1,186 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.server; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.io.PrintWriter; -import java.util.Properties; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.CacheFactory; -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.ExpirationAttributes; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionFactory; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.server.CacheServer; - -import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository; -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; -import org.springframework.util.StringUtils; - -/** - * The {@link NativeGemFireServer} class uses the GemFire API to create a GemFire (cache) instance. - * - * @author John Blum - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.server.CacheServer - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @since 1.3.0 - */ -@SuppressWarnings("unused") -public final class NativeGemFireServer implements Runnable { - - private static final int GEMFIRE_CACHE_SERVER_PORT = - Integer.getInteger("spring-session-data-gemfire.cache.server.port", 12480); - - private static final String GEMFIRE_CACHE_SERVER_HOST = "localhost"; - private static final String GEMFIRE_CACHE_SERVER_HOSTNAME_FOR_CLIENTS = GEMFIRE_CACHE_SERVER_HOST; - private static final String GEMFIRE_LOG_FILENAME_PATTERN = - String.format("%s", NativeGemFireServer.class.getSimpleName()).concat("-%s.log"); - - public static void main(String[] args) { - newNativeGemFireServer(args).run(); - } - - private final String[] args; - - private static File newGemFireLogFile(String suffix) { - return new File(String.format(GEMFIRE_LOG_FILENAME_PATTERN, suffix)); - } - - private static NativeGemFireServer newNativeGemFireServer(String[] args) { - return new NativeGemFireServer(args); - } - - private static String[] nullSafeStringArray(String[] array) { - return (array != null ? array.clone() : new String[0]); - } - - private static void writeStringTo(File file, String fileContents) { - PrintWriter fileWriter = null; - - try { - fileWriter = new PrintWriter(new BufferedWriter(new FileWriter(file, true)), true); - fileWriter.println(fileContents); - fileWriter.flush(); - } - catch (IOException e) { - throw new RuntimeException(String.format("Failed to write [%s] to file [%s]", fileContents, file), e); - } - finally { - if (fileWriter != null) { - fileWriter.close(); - } - } - } - private NativeGemFireServer(String[] args) { - this.args = nullSafeStringArray(args); - } - - /** - * @inheritDoc - */ - public void run() { - run(this.args); - } - - private void run(String[] args) { - try { - writeStringTo(newGemFireLogFile("stdout"), "Before"); - - registerShutdownHook(addCacheServer(createRegion(gemfireCache( - gemfireProperties(applicationName()))))); - - writeStringTo(newGemFireLogFile("stdout"), "After"); - } - catch (Throwable e) { - writeStringTo(newGemFireLogFile("stderr"), e.toString()); - } - } - - private String applicationName() { - return applicationName(null); - } - - private String applicationName(String applicationName) { - return StringUtils.hasText(applicationName) ? applicationName - : "spring-session-data-gemfire.boot.sample." + NativeGemFireServer.class.getSimpleName(); - } - - private Properties gemfireProperties(String applicationName) { - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", applicationName); - gemfireProperties.setProperty("log-file", "gemfire-server.log"); - gemfireProperties.setProperty("log-level", "config"); - //gemfireProperties.setProperty("jmx-manager", "true"); - //gemfireProperties.setProperty("jmx-manager-start", "true"); - - return gemfireProperties; - } - - private Cache gemfireCache(Properties gemfireProperties) { - return new CacheFactory(gemfireProperties).create(); - } - - private Cache createRegion(Cache gemfireCache) { - RegionFactory regionFactory = - gemfireCache.createRegionFactory(RegionShortcut.PARTITION); - - regionFactory.setKeyConstraint(Object.class); - regionFactory.setValueConstraint(AbstractGemFireOperationsSessionRepository.GemFireSession.class); - regionFactory.setStatisticsEnabled(true); - regionFactory.setEntryIdleTimeout(newExpirationAttributes(1800, ExpirationAction.INVALIDATE)); - - Region region = regionFactory.create( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - - return gemfireCache; - } - - private ExpirationAttributes newExpirationAttributes(int expirationTime, ExpirationAction expirationAction) { - return new ExpirationAttributes(expirationTime, expirationAction); - } - - private Cache addCacheServer(Cache gemfireCache) throws IOException { - CacheServer cacheServer = gemfireCache.addCacheServer(); - - cacheServer.setBindAddress(GEMFIRE_CACHE_SERVER_HOST); - cacheServer.setHostnameForClients(GEMFIRE_CACHE_SERVER_HOSTNAME_FOR_CLIENTS); - cacheServer.setPort(GEMFIRE_CACHE_SERVER_PORT); - cacheServer.start(); - - return gemfireCache; - } - - private Cache registerShutdownHook(final Cache gemfireCache) { - Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() { - public void run() { - if (gemfireCache != null) { - gemfireCache.close(); - } - } - })); - - return gemfireCache; - } -} diff --git a/samples/boot/gemfire/src/main/resources/templates/index.html b/samples/boot/gemfire/src/main/resources/templates/index.html deleted file mode 100644 index e84fe930..00000000 --- a/samples/boot/gemfire/src/main/resources/templates/index.html +++ /dev/null @@ -1,49 +0,0 @@ - - - - Session Attributes - - - - -
-

Description

-

- This application demonstrates how to use a GemFire 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

- -
- - - - - -
- -
- - - - - - - - - - - - - - -
Attribute NameAttribute Value
namevalue
-
- - diff --git a/samples/javaconfig/gemfire-clientserver/spring-session-sample-javaconfig-gemfire-clientserver.gradle b/samples/javaconfig/gemfire-clientserver/spring-session-sample-javaconfig-gemfire-clientserver.gradle deleted file mode 100644 index fc01dbc1..00000000 --- a/samples/javaconfig/gemfire-clientserver/spring-session-sample-javaconfig-gemfire-clientserver.gradle +++ /dev/null @@ -1,22 +0,0 @@ -apply plugin: 'io.spring.convention.spring-sample-war' -apply plugin: "gemfire-server" - -dependencies { - compile project(':spring-session-data-gemfire') - compile "org.springframework:spring-web" - compile "org.webjars:bootstrap" - compile "org.webjars:webjars-taglib" - compile jstlDependencies - compile slf4jDependencies - - providedCompile "javax.servlet:javax.servlet-api" - - runtime "org.springframework.shell:spring-shell" - - testCompile "junit:junit" - testCompile "org.assertj:assertj-core" - - integrationTestCompile seleniumDependencies - - integrationTestRuntime "org.springframework.shell:spring-shell" -} \ No newline at end of file diff --git a/samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java b/samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java deleted file mode 100644 index 83138ff7..00000000 --- a/samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.htmlunit.HtmlUnitDriver; -import sample.pages.HomePage; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - */ -public class AttributeTests { - - private WebDriver driver; - - @Before - public void setup() { - this.driver = new HtmlUnitDriver(); - } - - @After - public void tearDown() { - this.driver.quit(); - } - - @Test - public void noAttributes() { - HomePage home = HomePage.go(this.driver, HomePage.class); - assertThat(home.attributes().size()).isEqualTo(0); - } - - @Test - public void createAttribute() { - HomePage home = HomePage.go(this.driver, HomePage.class); - home = home.form() - .attributeName("a") - .attributeValue("b") - .submit(HomePage.class); - assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); - assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); - } - -} diff --git a/samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java b/samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java deleted file mode 100644 index 0f43fda0..00000000 --- a/samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.pages; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.openqa.selenium.By; -import org.openqa.selenium.Cookie; -import org.openqa.selenium.SearchContext; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - * @author Rob Winch - */ -public class HomePage { - - private WebDriver driver; - - @FindBy(tagName = "form") - WebElement form; - - @FindBy(css = "table tbody tr") - List trs; - - List attributes; - - public HomePage(WebDriver driver) { - this.driver = driver; - this.attributes = new ArrayList(); - } - - private static void get(WebDriver driver, String get) { - String baseUrl = "http://localhost:" + System.getProperty("app.port", "8080"); - driver.get(baseUrl + get); - } - - public static T go(WebDriver driver, Class page) { - get(driver, "/"); - return PageFactory.initElements(driver, page); - } - - public void containCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").contains(cookieName); - } - - public void doesNotContainCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").doesNotContain(cookieName); - } - - public HomePage logout() { - WebElement logout = this.driver - .findElement(By.cssSelector("input[type=\"submit\"]")); - logout.click(); - return PageFactory.initElements(this.driver, HomePage.class); - } - - public List attributes() { - List rows = new ArrayList(); - for (WebElement tr : this.trs) { - rows.add(new Attribute(tr)); - } - this.attributes.addAll(rows); - return this.attributes; - } - - public Form form() { - return new Form(this.form); - } - - public class Form { - @FindBy(name = "attributeName") - WebElement attributeName; - - @FindBy(name = "attributeValue") - WebElement attributeValue; - - @FindBy(css = "input[type=\"submit\"]") - WebElement submit; - - public Form(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - public Form attributeName(String text) { - this.attributeName.sendKeys(text); - return this; - } - - public Form attributeValue(String text) { - this.attributeValue.sendKeys(text); - return this; - } - - public T submit(Class page) { - this.submit.click(); - return PageFactory.initElements(HomePage.this.driver, page); - } - } - - public static class Attribute { - @FindBy(xpath = ".//td[1]") - WebElement attributeName; - - @FindBy(xpath = ".//td[2]") - WebElement attributeValue; - - public Attribute(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - /** - * @return the attributeName - */ - public String getAttributeName() { - return this.attributeName.getText(); - } - - /** - * @return the attributeValue - */ - public String getAttributeValue() { - return this.attributeValue.getText(); - } - } - -} diff --git a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/ClientConfig.java b/samples/javaconfig/gemfire-clientserver/src/main/java/sample/ClientConfig.java deleted file mode 100644 index 2c73b8c6..00000000 --- a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/ClientConfig.java +++ /dev/null @@ -1,216 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.util.Collections; -import java.util.Properties; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.Pool; -import org.apache.geode.cache.client.PoolManager; -import org.apache.geode.cache.client.internal.PoolImpl; -import org.apache.geode.management.membership.ClientMembership; -import org.apache.geode.management.membership.ClientMembershipEvent; -import org.apache.geode.management.membership.ClientMembershipListenerAdapter; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.client.ClientCacheFactoryBean; -import org.springframework.data.gemfire.config.xml.GemfireConstants; -import org.springframework.data.gemfire.support.ConnectionEndpoint; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; -import org.springframework.util.Assert; - -// tag::class[] -@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30, poolName = "DEFAULT") // <1> -public class ClientConfig { - - static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(60); - - static final CountDownLatch LATCH = new CountDownLatch(1); - - static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning"; - static final String GEMFIRE_DEFAULT_POOL_NAME = "DEFAULT"; - static final String PROXY_HOST = "dummy.example.com"; - static final String PROXY_PORT = "3128"; - - @Bean - static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { // <2> - Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("name", applicationName()); - // gemfireProperties.setProperty("log-file", "gemfire-client.log"); - gemfireProperties.setProperty("log-level", logLevel()); - return gemfireProperties; - } - - String applicationName() { - return "spring-session-data-gemfire-clientserver-javaconfig-sample:".concat(getClass().getSimpleName()); - } - - String logLevel() { - return System.getProperty("spring.session.data.gemfire.log-level", DEFAULT_GEMFIRE_LOG_LEVEL); - } - - @Bean - ClientCacheFactoryBean gemfireCache( - @Value("${spring.session.data.gemfire.host:" + ServerConfig.SERVER_HOST + "}") String host, - @Value("${spring.session.data.gemfire.port:" + ServerConfig.SERVER_PORT + "}") int port) { // <3> - - ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean(); - - clientCacheFactory.setClose(true); - clientCacheFactory.setProperties(gemfireProperties()); - - // GemFire Pool settings <4> - clientCacheFactory.setKeepAlive(false); - clientCacheFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5)); - clientCacheFactory.setReadTimeout(intValue(TimeUnit.SECONDS.toMillis(15))); - clientCacheFactory.setRetryAttempts(1); - clientCacheFactory.setSubscriptionEnabled(true); - clientCacheFactory.setThreadLocalConnections(false); - clientCacheFactory.setServers(Collections.singletonList(newConnectionEndpoint(host, port))); - - registerClientMembershipListener(); // <5> - - return clientCacheFactory; - } - - int intValue(Number number) { - return number.intValue(); - } - - ConnectionEndpoint newConnectionEndpoint(String host, int port) { - return new ConnectionEndpoint(host, port); - } - - void registerClientMembershipListener() { - ClientMembership.registerClientMembershipListener( - new ClientMembershipListenerAdapter() { - @Override - public void memberJoined(ClientMembershipEvent event) { - LATCH.countDown(); - } - }); - } - - @Bean - BeanPostProcessor gemfireClientServerReadyBeanPostProcessor( - @Value("${spring-session-data-gemfire.cache.server.host:localhost}") final String host, - @Value("${spring-session-data-gemfire.cache.server.port:12480}") final int port) { // <5> - - return new BeanPostProcessor() { - - private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true); - private final AtomicReference defaultPool = new AtomicReference(null); - - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) { - try { - validateCacheClientNotified(); - validateCacheClientSubscriptionQueueConnectionEstablished(); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - return bean; - } - - private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) { - return (isGemFireRegion(bean, beanName) - ? checkGemFireServerIsRunning.compareAndSet(true, false) - : whenGemFireCache(bean, beanName)); - } - - private boolean isGemFireRegion(Object bean, String beanName) { - return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName) - || bean instanceof Region); - } - - private boolean whenGemFireCache(Object bean, String beanName) { - if (bean instanceof ClientCache) { - defaultPool.compareAndSet(null, ((ClientCache) bean).getDefaultPool()); - } - - return false; - } - - private void validateCacheClientNotified() throws InterruptedException { - boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - - Assert.state(didNotTimeout, String.format( - "GemFire Cache Server failed to start on host [%s] and port [%d]", host, port)); - } - - @SuppressWarnings("all") - private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException { - boolean cacheClientSubscriptionQueueConnectionEstablished = false; - - Pool pool = defaultIfNull(this.defaultPool.get(), GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, - GEMFIRE_DEFAULT_POOL_NAME); - - if (pool instanceof PoolImpl) { - long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT); - - while (System.currentTimeMillis() < timeout - && !((PoolImpl) pool).isPrimaryUpdaterAlive()) { - - synchronized (pool) { - TimeUnit.MILLISECONDS.timedWait(pool, 500L); - } - - } - - cacheClientSubscriptionQueueConnectionEstablished |= - ((PoolImpl) pool).isPrimaryUpdaterAlive(); - } - - Assert.state(cacheClientSubscriptionQueueConnectionEstablished, String.format( - "Cache client subscription queue connection not established; GemFire Pool was [%s];" - + " GemFire Pool configuration was [locators = %s, servers = %s]", - pool, pool.getLocators(), pool.getServers())); - } - - private Pool defaultIfNull(Pool pool, String... poolNames) { - for (String poolName : poolNames) { - pool = (pool != null ? pool : PoolManager.find(poolName)); - } - - return pool; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } - }; - } - // end::class[] -} diff --git a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/Initializer.java b/samples/javaconfig/gemfire-clientserver/src/main/java/sample/Initializer.java deleted file mode 100644 index bc5a71cf..00000000 --- a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/Initializer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; - -// tag::class[] -public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1> - - public Initializer() { - super(ClientConfig.class); // <2> - } -} -// end::class[] diff --git a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/ServerConfig.java b/samples/javaconfig/gemfire-clientserver/src/main/java/sample/ServerConfig.java deleted file mode 100644 index 6bca62d3..00000000 --- a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/ServerConfig.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.io.IOException; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.Cache; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.data.gemfire.server.CacheServerFactoryBean; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; - -// tag::class[] -@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) // <1> -public class ServerConfig { - - static final int SERVER_PORT = 12480; - - static final String DEFAULT_GEMFIRE_LOG_LEVEL = "warning"; - static final String SERVER_HOST = "localhost"; - - @SuppressWarnings("resource") - public static void main(String[] args) throws IOException { // <5> - new AnnotationConfigApplicationContext(ServerConfig.class).registerShutdownHook(); - } - - @Bean - static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { // <2> - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", applicationName()); - gemfireProperties.setProperty("mcast-port", "0"); - // gemfireProperties.setProperty("log-file", "gemfire-server.log"); - gemfireProperties.setProperty("log-level", logLevel()); - // gemfireProperties.setProperty("jmx-manager", "true"); - // gemfireProperties.setProperty("jmx-manager-start", "true"); - - return gemfireProperties; - } - - String applicationName() { - return "samples:httpsession-gemfire-clientserver:".concat(getClass().getSimpleName()); - } - - String logLevel() { - return System.getProperty("sample.httpsession.gemfire.log-level", DEFAULT_GEMFIRE_LOG_LEVEL); - } - - @Bean - CacheFactoryBean gemfireCache() { // <3> - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, - @Value("${spring.session.data.gemfire.port:" + SERVER_PORT + "}") int port) { // <4> - - CacheServerFactoryBean gemfireCacheServer = new CacheServerFactoryBean(); - - gemfireCacheServer.setAutoStartup(true); - gemfireCacheServer.setBindAddress(SERVER_HOST); - gemfireCacheServer.setCache(gemfireCache); - gemfireCacheServer.setHostNameForClients(SERVER_HOST); - gemfireCacheServer.setMaxTimeBetweenPings(Long.valueOf(TimeUnit.SECONDS.toMillis(60)).intValue()); - gemfireCacheServer.setPort(port); - - return gemfireCacheServer; - } -} -// end::class[] diff --git a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/SessionServlet.java b/samples/javaconfig/gemfire-clientserver/src/main/java/sample/SessionServlet.java deleted file mode 100644 index 98f3ae85..00000000 --- a/samples/javaconfig/gemfire-clientserver/src/main/java/sample/SessionServlet.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -// tag::class[] -@WebServlet("/session") -public class SessionServlet extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String attributeName = request.getParameter("attributeName"); - String attributeValue = request.getParameter("attributeValue"); - request.getSession().setAttribute(attributeName, attributeValue); - response.sendRedirect(request.getContextPath() + "/"); - } - - private static final long serialVersionUID = 2878267318695777395L; -} -// tag::end[] diff --git a/samples/javaconfig/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF b/samples/javaconfig/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF deleted file mode 100644 index e69de29b..00000000 diff --git a/samples/javaconfig/gemfire-clientserver/src/main/webapp/index.jsp b/samples/javaconfig/gemfire-clientserver/src/main/webapp/index.jsp deleted file mode 100644 index 5d24a6b3..00000000 --- a/samples/javaconfig/gemfire-clientserver/src/main/webapp/index.jsp +++ /dev/null @@ -1,50 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="wj" uri="http://www.webjars.org/tags" %> - - - - Session Attributes - - "> - - - -
-

Description

-

This application demonstrates how to use a GemFire 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

- -
- - - - - -
- -
- - - - - - - - - - - - - - - - -
Attribute NameAttribute Value
-
- - diff --git a/samples/javaconfig/gemfire-p2p/spring-session-sample-javaconfig-gemfire-p2p.gradle b/samples/javaconfig/gemfire-p2p/spring-session-sample-javaconfig-gemfire-p2p.gradle deleted file mode 100644 index 3f2c8805..00000000 --- a/samples/javaconfig/gemfire-p2p/spring-session-sample-javaconfig-gemfire-p2p.gradle +++ /dev/null @@ -1,19 +0,0 @@ -apply plugin: 'io.spring.convention.spring-sample-war' - -dependencies { - compile project(':spring-session-data-gemfire') - compile "org.springframework:spring-web" - compile "org.webjars:bootstrap" - compile "org.webjars:webjars-taglib" - compile jstlDependencies - compile slf4jDependencies - - providedCompile "javax.servlet:javax.servlet-api" - - testCompile "junit:junit" - - integrationTestCompile seleniumDependencies - integrationTestCompile "org.assertj:assertj-core" - - integrationTestRuntime "org.springframework.shell:spring-shell" -} diff --git a/samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java b/samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java deleted file mode 100644 index 83138ff7..00000000 --- a/samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.htmlunit.HtmlUnitDriver; -import sample.pages.HomePage; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - */ -public class AttributeTests { - - private WebDriver driver; - - @Before - public void setup() { - this.driver = new HtmlUnitDriver(); - } - - @After - public void tearDown() { - this.driver.quit(); - } - - @Test - public void noAttributes() { - HomePage home = HomePage.go(this.driver, HomePage.class); - assertThat(home.attributes().size()).isEqualTo(0); - } - - @Test - public void createAttribute() { - HomePage home = HomePage.go(this.driver, HomePage.class); - home = home.form() - .attributeName("a") - .attributeValue("b") - .submit(HomePage.class); - assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); - assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); - } - -} diff --git a/samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java b/samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java deleted file mode 100644 index 0f43fda0..00000000 --- a/samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.pages; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.openqa.selenium.By; -import org.openqa.selenium.Cookie; -import org.openqa.selenium.SearchContext; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - * @author Rob Winch - */ -public class HomePage { - - private WebDriver driver; - - @FindBy(tagName = "form") - WebElement form; - - @FindBy(css = "table tbody tr") - List trs; - - List attributes; - - public HomePage(WebDriver driver) { - this.driver = driver; - this.attributes = new ArrayList(); - } - - private static void get(WebDriver driver, String get) { - String baseUrl = "http://localhost:" + System.getProperty("app.port", "8080"); - driver.get(baseUrl + get); - } - - public static T go(WebDriver driver, Class page) { - get(driver, "/"); - return PageFactory.initElements(driver, page); - } - - public void containCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").contains(cookieName); - } - - public void doesNotContainCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").doesNotContain(cookieName); - } - - public HomePage logout() { - WebElement logout = this.driver - .findElement(By.cssSelector("input[type=\"submit\"]")); - logout.click(); - return PageFactory.initElements(this.driver, HomePage.class); - } - - public List attributes() { - List rows = new ArrayList(); - for (WebElement tr : this.trs) { - rows.add(new Attribute(tr)); - } - this.attributes.addAll(rows); - return this.attributes; - } - - public Form form() { - return new Form(this.form); - } - - public class Form { - @FindBy(name = "attributeName") - WebElement attributeName; - - @FindBy(name = "attributeValue") - WebElement attributeValue; - - @FindBy(css = "input[type=\"submit\"]") - WebElement submit; - - public Form(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - public Form attributeName(String text) { - this.attributeName.sendKeys(text); - return this; - } - - public Form attributeValue(String text) { - this.attributeValue.sendKeys(text); - return this; - } - - public T submit(Class page) { - this.submit.click(); - return PageFactory.initElements(HomePage.this.driver, page); - } - } - - public static class Attribute { - @FindBy(xpath = ".//td[1]") - WebElement attributeName; - - @FindBy(xpath = ".//td[2]") - WebElement attributeValue; - - public Attribute(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - /** - * @return the attributeName - */ - public String getAttributeName() { - return this.attributeName.getText(); - } - - /** - * @return the attributeValue - */ - public String getAttributeValue() { - return this.attributeValue.getText(); - } - } - -} diff --git a/samples/javaconfig/gemfire-p2p/src/main/java/sample/Config.java b/samples/javaconfig/gemfire-p2p/src/main/java/sample/Config.java deleted file mode 100644 index 7be47047..00000000 --- a/samples/javaconfig/gemfire-p2p/src/main/java/sample/Config.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.util.Properties; - -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; - -// tag::class[] -@EnableGemFireHttpSession // <1> -public class Config { - - @Bean - Properties gemfireProperties() { // <2> - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", "GemFireP2PHttpSessionSample"); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-level", - System.getProperty("sample.httpsession.gemfire.log-level", "warning")); - gemfireProperties.setProperty("jmx-manager", "true"); - gemfireProperties.setProperty("jmx-manager-start", "true"); - - return gemfireProperties; - } - - @Bean - CacheFactoryBean gemfireCache() { // <3> - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } -} -// end::class[] diff --git a/samples/javaconfig/gemfire-p2p/src/main/java/sample/Initializer.java b/samples/javaconfig/gemfire-p2p/src/main/java/sample/Initializer.java deleted file mode 100644 index b7472d14..00000000 --- a/samples/javaconfig/gemfire-p2p/src/main/java/sample/Initializer.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; - -// tag::class[] -public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1> - - public Initializer() { - super(Config.class); // <2> - } -} -// end::class[] diff --git a/samples/javaconfig/gemfire-p2p/src/main/java/sample/SessionServlet.java b/samples/javaconfig/gemfire-p2p/src/main/java/sample/SessionServlet.java deleted file mode 100644 index 98f3ae85..00000000 --- a/samples/javaconfig/gemfire-p2p/src/main/java/sample/SessionServlet.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.annotation.WebServlet; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -// tag::class[] -@WebServlet("/session") -public class SessionServlet extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String attributeName = request.getParameter("attributeName"); - String attributeValue = request.getParameter("attributeValue"); - request.getSession().setAttribute(attributeName, attributeValue); - response.sendRedirect(request.getContextPath() + "/"); - } - - private static final long serialVersionUID = 2878267318695777395L; -} -// tag::end[] diff --git a/samples/javaconfig/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF b/samples/javaconfig/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF deleted file mode 100644 index e69de29b..00000000 diff --git a/samples/javaconfig/gemfire-p2p/src/main/webapp/index.jsp b/samples/javaconfig/gemfire-p2p/src/main/webapp/index.jsp deleted file mode 100644 index 5d24a6b3..00000000 --- a/samples/javaconfig/gemfire-p2p/src/main/webapp/index.jsp +++ /dev/null @@ -1,50 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="wj" uri="http://www.webjars.org/tags" %> - - - - Session Attributes - - "> - - - -
-

Description

-

This application demonstrates how to use a GemFire 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

- -
- - - - - -
- -
- - - - - - - - - - - - - - - - -
Attribute NameAttribute Value
-
- - diff --git a/samples/xml/gemfire-clientserver/spring-session-sample-xml-gemfire-clientserver.gradle b/samples/xml/gemfire-clientserver/spring-session-sample-xml-gemfire-clientserver.gradle deleted file mode 100644 index f59a78fa..00000000 --- a/samples/xml/gemfire-clientserver/spring-session-sample-xml-gemfire-clientserver.gradle +++ /dev/null @@ -1,22 +0,0 @@ -apply plugin: 'io.spring.convention.spring-sample-war' -apply plugin: "gemfire-server" - -dependencies { - compile project(':spring-session-data-gemfire') - compile "org.springframework:spring-web" - compile "org.webjars:bootstrap" - compile "org.webjars:webjars-taglib" - compile jstlDependencies - compile slf4jDependencies - - providedCompile "javax.servlet:javax.servlet-api" - - runtime "org.springframework.shell:spring-shell" - - testCompile "junit:junit" - testCompile "org.assertj:assertj-core" - - integrationTestCompile seleniumDependencies - - integrationTestRuntime "org.springframework.shell:spring-shell" -} diff --git a/samples/xml/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java b/samples/xml/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java deleted file mode 100644 index 83138ff7..00000000 --- a/samples/xml/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.htmlunit.HtmlUnitDriver; -import sample.pages.HomePage; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - */ -public class AttributeTests { - - private WebDriver driver; - - @Before - public void setup() { - this.driver = new HtmlUnitDriver(); - } - - @After - public void tearDown() { - this.driver.quit(); - } - - @Test - public void noAttributes() { - HomePage home = HomePage.go(this.driver, HomePage.class); - assertThat(home.attributes().size()).isEqualTo(0); - } - - @Test - public void createAttribute() { - HomePage home = HomePage.go(this.driver, HomePage.class); - home = home.form() - .attributeName("a") - .attributeValue("b") - .submit(HomePage.class); - assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); - assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); - } - -} diff --git a/samples/xml/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java b/samples/xml/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java deleted file mode 100644 index 0f43fda0..00000000 --- a/samples/xml/gemfire-clientserver/src/integration-test/java/sample/pages/HomePage.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.pages; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.openqa.selenium.By; -import org.openqa.selenium.Cookie; -import org.openqa.selenium.SearchContext; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - * @author Rob Winch - */ -public class HomePage { - - private WebDriver driver; - - @FindBy(tagName = "form") - WebElement form; - - @FindBy(css = "table tbody tr") - List trs; - - List attributes; - - public HomePage(WebDriver driver) { - this.driver = driver; - this.attributes = new ArrayList(); - } - - private static void get(WebDriver driver, String get) { - String baseUrl = "http://localhost:" + System.getProperty("app.port", "8080"); - driver.get(baseUrl + get); - } - - public static T go(WebDriver driver, Class page) { - get(driver, "/"); - return PageFactory.initElements(driver, page); - } - - public void containCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").contains(cookieName); - } - - public void doesNotContainCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").doesNotContain(cookieName); - } - - public HomePage logout() { - WebElement logout = this.driver - .findElement(By.cssSelector("input[type=\"submit\"]")); - logout.click(); - return PageFactory.initElements(this.driver, HomePage.class); - } - - public List attributes() { - List rows = new ArrayList(); - for (WebElement tr : this.trs) { - rows.add(new Attribute(tr)); - } - this.attributes.addAll(rows); - return this.attributes; - } - - public Form form() { - return new Form(this.form); - } - - public class Form { - @FindBy(name = "attributeName") - WebElement attributeName; - - @FindBy(name = "attributeValue") - WebElement attributeValue; - - @FindBy(css = "input[type=\"submit\"]") - WebElement submit; - - public Form(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - public Form attributeName(String text) { - this.attributeName.sendKeys(text); - return this; - } - - public Form attributeValue(String text) { - this.attributeValue.sendKeys(text); - return this; - } - - public T submit(Class page) { - this.submit.click(); - return PageFactory.initElements(HomePage.this.driver, page); - } - } - - public static class Attribute { - @FindBy(xpath = ".//td[1]") - WebElement attributeName; - - @FindBy(xpath = ".//td[2]") - WebElement attributeValue; - - public Attribute(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - /** - * @return the attributeName - */ - public String getAttributeName() { - return this.attributeName.getText(); - } - - /** - * @return the attributeValue - */ - public String getAttributeValue() { - return this.attributeValue.getText(); - } - } - -} diff --git a/samples/xml/gemfire-clientserver/src/main/java/sample/Application.java b/samples/xml/gemfire-clientserver/src/main/java/sample/Application.java deleted file mode 100644 index 4c477df7..00000000 --- a/samples/xml/gemfire-clientserver/src/main/java/sample/Application.java +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.ImportResource; - -@SuppressWarnings("resource") -// tag::class[] -@Configuration // <1> -@ImportResource("META-INF/spring/session-server.xml") // <2> -public class Application { - - public static void main(String[] args) { - new AnnotationConfigApplicationContext(Application.class).registerShutdownHook(); - } -} -// tag::end[] diff --git a/samples/xml/gemfire-clientserver/src/main/java/sample/GemFireClientServerReadyBeanPostProcessor.java b/samples/xml/gemfire-clientserver/src/main/java/sample/GemFireClientServerReadyBeanPostProcessor.java deleted file mode 100644 index ab51f0be..00000000 --- a/samples/xml/gemfire-clientserver/src/main/java/sample/GemFireClientServerReadyBeanPostProcessor.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicReference; - -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.Pool; -import org.apache.geode.cache.client.PoolManager; -import org.apache.geode.cache.client.internal.PoolImpl; -import org.apache.geode.management.membership.ClientMembership; -import org.apache.geode.management.membership.ClientMembershipEvent; -import org.apache.geode.management.membership.ClientMembershipListenerAdapter; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.beans.factory.config.BeanPostProcessor; -import org.springframework.data.gemfire.config.xml.GemfireConstants; -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; -import org.springframework.util.Assert; - -public class GemFireClientServerReadyBeanPostProcessor implements BeanPostProcessor { - - private static final long DEFAULT_TIMEOUT = TimeUnit.SECONDS.toMillis(60); - - private static final CountDownLatch LATCH = new CountDownLatch(1); - - private static final String GEMFIRE_DEFAULT_POOL_NAME = "DEFAULT"; - - static { - ClientMembership.registerClientMembershipListener( - new ClientMembershipListenerAdapter() { - @Override - public void memberJoined(ClientMembershipEvent event) { - LATCH.countDown(); - } - } - ); - } - - @Value("${spring.session.data.gemfire.port:${application.gemfire.client-server.port}}") - private int port; - - @Value("${application.gemfire.client-server.host:localhost}") - private String host; - - private final AtomicBoolean checkGemFireServerIsRunning = new AtomicBoolean(true); - private final AtomicReference gemfirePool = new AtomicReference(null); - - public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { - if (shouldCheckWhetherGemFireServerIsRunning(bean, beanName)) { - try { - validateCacheClientNotified(); - validateCacheClientSubscriptionQueueConnectionEstablished(); - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - } - - return bean; - } - - private boolean shouldCheckWhetherGemFireServerIsRunning(Object bean, String beanName) { - return (isGemFireRegion(bean, beanName) - ? this.checkGemFireServerIsRunning.compareAndSet(true, false) - : whenGemFirePool(bean, beanName)); - } - - private boolean isGemFireRegion(Object bean, String beanName) { - return (GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME.equals(beanName) - || bean instanceof Region); - } - - private boolean whenGemFirePool(Object bean, String beanName) { - if (bean instanceof Pool) { - this.gemfirePool.compareAndSet(null, (Pool) bean); - } - - return false; - } - - private void validateCacheClientNotified() throws InterruptedException { - boolean didNotTimeout = LATCH.await(DEFAULT_TIMEOUT, TimeUnit.MILLISECONDS); - - Assert.state(didNotTimeout, String.format( - "GemFire Cache Server failed to start on host [%s] and port [%d]", this.host, this.port)); - } - - @SuppressWarnings("all") - private void validateCacheClientSubscriptionQueueConnectionEstablished() throws InterruptedException { - boolean cacheClientSubscriptionQueueConnectionEstablished = false; - - Pool pool = defaultIfNull(this.gemfirePool.get(), - GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME, GEMFIRE_DEFAULT_POOL_NAME); - - if (pool instanceof PoolImpl) { - long timeout = (System.currentTimeMillis() + DEFAULT_TIMEOUT); - - while (System.currentTimeMillis() < timeout - && !((PoolImpl) pool).isPrimaryUpdaterAlive()) { - - synchronized (pool) { - TimeUnit.MILLISECONDS.timedWait(pool, 500L); - } - - } - - cacheClientSubscriptionQueueConnectionEstablished |= - ((PoolImpl) pool).isPrimaryUpdaterAlive(); - } - - Assert.state(cacheClientSubscriptionQueueConnectionEstablished, String.format( - "Cache client subscription queue connection not established; GemFire Pool was [%s];" - + " GemFire Pool configuration was [locators = %s, servers = %s]", - pool, pool.getLocators(), pool.getServers())); - } - - private Pool defaultIfNull(Pool pool, String... poolNames) { - for (String poolName : poolNames) { - pool = (pool != null ? pool : PoolManager.find(poolName)); - } - - return pool; - } - - public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { - return bean; - } -} -// tag::end[] diff --git a/samples/xml/gemfire-clientserver/src/main/java/sample/SessionServlet.java b/samples/xml/gemfire-clientserver/src/main/java/sample/SessionServlet.java deleted file mode 100644 index b030339b..00000000 --- a/samples/xml/gemfire-clientserver/src/main/java/sample/SessionServlet.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -// tag::class[] -public class SessionServlet extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String attributeName = request.getParameter("attributeName"); - String attributeValue = request.getParameter("attributeValue"); - request.getSession().setAttribute(attributeName, attributeValue); - response.sendRedirect(request.getContextPath() + "/"); - } - - private static final long serialVersionUID = 2878267318695777395L; -} -// tag::end[] diff --git a/samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/application.properties b/samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/application.properties deleted file mode 100644 index 98fbf193..00000000 --- a/samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/application.properties +++ /dev/null @@ -1,2 +0,0 @@ -application.gemfire.client-server.host=localhost -application.gemfire.client-server.port=12480 diff --git a/samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/session-server.xml b/samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/session-server.xml deleted file mode 100644 index 6426b7f4..00000000 --- a/samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/session-server.xml +++ /dev/null @@ -1,48 +0,0 @@ - - - - - - - - - - - - - GemFireClientServerHttpSessionXmlSample - 0 - - ${spring.session.data.gemfire.log-level:warning} - - - - - - - - - - - - - - diff --git a/samples/xml/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF b/samples/xml/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF deleted file mode 100644 index e69de29b..00000000 diff --git a/samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/spring/session-client.xml b/samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/spring/session-client.xml deleted file mode 100644 index bde07b38..00000000 --- a/samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/spring/session-client.xml +++ /dev/null @@ -1,50 +0,0 @@ - - - - - - - - - - - - - - - - - ${spring.session.data.gemfire.log-level:warning} - - - - - - - - - - - - - - - diff --git a/samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml b/samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index 3d1d375e..00000000 --- a/samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - contextConfigLocation - /WEB-INF/spring/session-client.xml - - - - - - springSessionRepositoryFilter - org.springframework.web.filter.DelegatingFilterProxy - - - springSessionRepositoryFilter - /* - REQUEST - ERROR - - - - - - - org.springframework.web.context.ContextLoaderListener - - - - - session - sample.SessionServlet - - - - session - /session - - - - index.jsp - - diff --git a/samples/xml/gemfire-clientserver/src/main/webapp/index.jsp b/samples/xml/gemfire-clientserver/src/main/webapp/index.jsp deleted file mode 100644 index 5d24a6b3..00000000 --- a/samples/xml/gemfire-clientserver/src/main/webapp/index.jsp +++ /dev/null @@ -1,50 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="wj" uri="http://www.webjars.org/tags" %> - - - - Session Attributes - - "> - - - -
-

Description

-

This application demonstrates how to use a GemFire 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

- -
- - - - - -
- -
- - - - - - - - - - - - - - - - -
Attribute NameAttribute Value
-
- - diff --git a/samples/xml/gemfire-p2p/spring-session-sample-xml-gemfire-p2p.gradle b/samples/xml/gemfire-p2p/spring-session-sample-xml-gemfire-p2p.gradle deleted file mode 100644 index 3f2c8805..00000000 --- a/samples/xml/gemfire-p2p/spring-session-sample-xml-gemfire-p2p.gradle +++ /dev/null @@ -1,19 +0,0 @@ -apply plugin: 'io.spring.convention.spring-sample-war' - -dependencies { - compile project(':spring-session-data-gemfire') - compile "org.springframework:spring-web" - compile "org.webjars:bootstrap" - compile "org.webjars:webjars-taglib" - compile jstlDependencies - compile slf4jDependencies - - providedCompile "javax.servlet:javax.servlet-api" - - testCompile "junit:junit" - - integrationTestCompile seleniumDependencies - integrationTestCompile "org.assertj:assertj-core" - - integrationTestRuntime "org.springframework.shell:spring-shell" -} diff --git a/samples/xml/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java b/samples/xml/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java deleted file mode 100644 index 83138ff7..00000000 --- a/samples/xml/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.htmlunit.HtmlUnitDriver; -import sample.pages.HomePage; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - */ -public class AttributeTests { - - private WebDriver driver; - - @Before - public void setup() { - this.driver = new HtmlUnitDriver(); - } - - @After - public void tearDown() { - this.driver.quit(); - } - - @Test - public void noAttributes() { - HomePage home = HomePage.go(this.driver, HomePage.class); - assertThat(home.attributes().size()).isEqualTo(0); - } - - @Test - public void createAttribute() { - HomePage home = HomePage.go(this.driver, HomePage.class); - home = home.form() - .attributeName("a") - .attributeValue("b") - .submit(HomePage.class); - assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); - assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); - } - -} diff --git a/samples/xml/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java b/samples/xml/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java deleted file mode 100644 index 0f43fda0..00000000 --- a/samples/xml/gemfire-p2p/src/integration-test/java/sample/pages/HomePage.java +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample.pages; - -import java.util.ArrayList; -import java.util.List; -import java.util.Set; - -import org.openqa.selenium.By; -import org.openqa.selenium.Cookie; -import org.openqa.selenium.SearchContext; -import org.openqa.selenium.WebDriver; -import org.openqa.selenium.WebElement; -import org.openqa.selenium.support.FindBy; -import org.openqa.selenium.support.PageFactory; -import org.openqa.selenium.support.pagefactory.DefaultElementLocatorFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Eddú Meléndez - * @author Rob Winch - */ -public class HomePage { - - private WebDriver driver; - - @FindBy(tagName = "form") - WebElement form; - - @FindBy(css = "table tbody tr") - List trs; - - List attributes; - - public HomePage(WebDriver driver) { - this.driver = driver; - this.attributes = new ArrayList(); - } - - private static void get(WebDriver driver, String get) { - String baseUrl = "http://localhost:" + System.getProperty("app.port", "8080"); - driver.get(baseUrl + get); - } - - public static T go(WebDriver driver, Class page) { - get(driver, "/"); - return PageFactory.initElements(driver, page); - } - - public void containCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").contains(cookieName); - } - - public void doesNotContainCookie(String cookieName) { - Set cookies = this.driver.manage().getCookies(); - assertThat(cookies).extracting("name").doesNotContain(cookieName); - } - - public HomePage logout() { - WebElement logout = this.driver - .findElement(By.cssSelector("input[type=\"submit\"]")); - logout.click(); - return PageFactory.initElements(this.driver, HomePage.class); - } - - public List attributes() { - List rows = new ArrayList(); - for (WebElement tr : this.trs) { - rows.add(new Attribute(tr)); - } - this.attributes.addAll(rows); - return this.attributes; - } - - public Form form() { - return new Form(this.form); - } - - public class Form { - @FindBy(name = "attributeName") - WebElement attributeName; - - @FindBy(name = "attributeValue") - WebElement attributeValue; - - @FindBy(css = "input[type=\"submit\"]") - WebElement submit; - - public Form(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - public Form attributeName(String text) { - this.attributeName.sendKeys(text); - return this; - } - - public Form attributeValue(String text) { - this.attributeValue.sendKeys(text); - return this; - } - - public T submit(Class page) { - this.submit.click(); - return PageFactory.initElements(HomePage.this.driver, page); - } - } - - public static class Attribute { - @FindBy(xpath = ".//td[1]") - WebElement attributeName; - - @FindBy(xpath = ".//td[2]") - WebElement attributeValue; - - public Attribute(SearchContext context) { - PageFactory.initElements(new DefaultElementLocatorFactory(context), this); - } - - /** - * @return the attributeName - */ - public String getAttributeName() { - return this.attributeName.getText(); - } - - /** - * @return the attributeValue - */ - public String getAttributeValue() { - return this.attributeValue.getText(); - } - } - -} diff --git a/samples/xml/gemfire-p2p/src/main/java/sample/SessionServlet.java b/samples/xml/gemfire-p2p/src/main/java/sample/SessionServlet.java deleted file mode 100644 index f37983be..00000000 --- a/samples/xml/gemfire-p2p/src/main/java/sample/SessionServlet.java +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package sample; - -import java.io.IOException; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServlet; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -// tag::class[] -public class SessionServlet extends HttpServlet { - - @Override - protected void doPost(HttpServletRequest request, HttpServletResponse response) - throws ServletException, IOException { - String attributeName = request.getParameter("attributeName"); - String attributeValue = request.getParameter("attributeValue"); - request.getSession().setAttribute(attributeName, attributeValue); - response.sendRedirect(request.getContextPath() + "/"); - } - - private static final long serialVersionUID = 2878267318695777395L; -} -// end::class[] diff --git a/samples/xml/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF b/samples/xml/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF deleted file mode 100644 index e69de29b..00000000 diff --git a/samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/spring/session.xml b/samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/spring/session.xml deleted file mode 100644 index 2e408ab0..00000000 --- a/samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/spring/session.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - - - GemFireP2PHttpSessionXmlSample - 0 - ${sample.httpsession.gemfire.log-level:warning} - true - true - - - - - - - diff --git a/samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml b/samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml deleted file mode 100644 index fd09adf2..00000000 --- a/samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - contextConfigLocation - - /WEB-INF/spring/*.xml - - - - - - - springSessionRepositoryFilter - org.springframework.web.filter.DelegatingFilterProxy - - - springSessionRepositoryFilter - /* - REQUEST - ERROR - - - - - - - - org.springframework.web.context.ContextLoaderListener - - - - - - session - sample.SessionServlet - - - - session - /session - - - - index.jsp - - diff --git a/samples/xml/gemfire-p2p/src/main/webapp/index.jsp b/samples/xml/gemfire-p2p/src/main/webapp/index.jsp deleted file mode 100644 index 2398c072..00000000 --- a/samples/xml/gemfire-p2p/src/main/webapp/index.jsp +++ /dev/null @@ -1,50 +0,0 @@ -<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> -<%@ taglib prefix="wj" uri="http://www.webjars.org/tags" %> - - - - Session Attributes - - "> - - - -
-

Description

-

This application demonstrates how to use a GemFire 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

- -
- - - - - -
- -
- - - - - - - - - - - - - - - - -
Attribute NameAttribute Value
-
- - diff --git a/spring-session-data-gemfire/spring-session-data-gemfire.gradle b/spring-session-data-gemfire/spring-session-data-gemfire.gradle deleted file mode 100644 index 004be669..00000000 --- a/spring-session-data-gemfire/spring-session-data-gemfire.gradle +++ /dev/null @@ -1,11 +0,0 @@ -apply plugin: 'io.spring.convention.spring-pom' - -description = "Aggregator for Spring Session and Spring Data GemFire" - -dependencies { - compile project(':spring-session') - compile("org.springframework.data:spring-data-gemfire") { - exclude group: "org.slf4j", module: 'slf4j-api' - exclude group: "org.slf4j", module: 'jcl-over-slf4j' - } -} diff --git a/spring-session/spring-session.gradle b/spring-session/spring-session.gradle index 5db2c240..9957540f 100644 --- a/spring-session/spring-session.gradle +++ b/spring-session/spring-session.gradle @@ -10,7 +10,6 @@ dependencies { optional "org.springframework:spring-messaging" optional "org.springframework:spring-web" optional "org.springframework:spring-websocket" - optional "org.springframework.data:spring-data-gemfire" optional "org.springframework.data:spring-data-mongodb" optional "org.springframework.data:spring-data-redis" optional "org.springframework.security:spring-security-core" @@ -27,7 +26,6 @@ dependencies { integrationTestCompile "org.hsqldb:hsqldb" integrationTestCompile "de.flapdoodle.embed:de.flapdoodle.embed.mongo" - integrationTestRuntime "org.springframework.shell:spring-shell" testCompile "junit:junit" testCompile "org.mockito:mockito-core" diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java deleted file mode 100644 index ac0e23f8..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/AbstractGemFireIntegrationTests.java +++ /dev/null @@ -1,460 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.io.File; -import java.io.IOException; -import java.net.Socket; -import java.util.ArrayList; -import java.util.List; -import java.util.Set; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.CacheClosedException; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.ExpirationAttributes; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientCacheFactory; -import org.apache.geode.cache.query.Index; -import org.apache.geode.cache.server.CacheServer; - -import org.junit.Before; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.ApplicationListener; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.session.events.AbstractSessionEvent; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * {@link AbstractGemFireIntegrationTests} is an abstract base class encapsulating common functionality - * for writing Spring Session GemFire integration tests. - * - * @author John Blum - * @since 1.1.0 - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.GemFireCache - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.client.ClientCache - * @see org.apache.geode.cache.query.Index - * @see org.apache.geode.cache.server.CacheServer - * @see org.springframework.session.ExpiringSession - */ -public abstract class AbstractGemFireIntegrationTests { - - protected static final boolean DEFAULT_ENABLE_QUERY_DEBUGGING = false; - - protected static final boolean GEMFIRE_QUERY_DEBUG = Boolean.getBoolean("spring.session.data.gemfire.query.debug"); - - protected static final int DEFAULT_GEMFIRE_SERVER_PORT = CacheServer.DEFAULT_PORT; - - protected static final long DEFAULT_WAIT_DURATION = TimeUnit.SECONDS.toMillis(20); - protected static final long DEFAULT_WAIT_INTERVAL = 500L; - - protected static final File WORKING_DIRECTORY = new File(System.getProperty("user.dir")); - - protected static final String DEFAULT_PROCESS_CONTROL_FILENAME = "process.ctl"; - - protected static final String GEMFIRE_LOG_FILE_NAME = - System.getProperty("spring.session.data.gemfire.log-file", "server.log"); - - protected static final String GEMFIRE_LOG_LEVEL = - System.getProperty("spring.session.data.gemfire.log-level", "error"); - - @Autowired - protected Cache gemfireCache; - - @Autowired - protected GemFireOperationsSessionRepository gemfireSessionRepository; - - @Before - public void setup() { - System.setProperty("gemfire.Query.VERBOSE", String.valueOf(isQueryDebuggingEnabled())); - } - - /* (non-Javadoc) */ - protected static File createDirectory(String pathname) { - File directory = new File(WORKING_DIRECTORY, pathname); - - assertThat(directory.isDirectory() || directory.mkdirs()) - .as(String.format("Failed to create directory (%1$s)", directory)).isTrue(); - - directory.deleteOnExit(); - - return directory; - } - - /* (non-Javadoc) */ - protected static List createJavaProcessCommandLine(Class type, String... args) { - List commandLine = new ArrayList(); - - String javaHome = System.getProperty("java.home"); - String javaExe = new File(new File(javaHome, "bin"), "java").getAbsolutePath(); - - commandLine.add(javaExe); - commandLine.add("-server"); - commandLine.add("-ea"); - commandLine.add(String.format("-Dgemfire.log-file=%1$s", GEMFIRE_LOG_FILE_NAME)); - commandLine.add(String.format("-Dgemfire.log-level=%1$s", GEMFIRE_LOG_LEVEL)); - commandLine.add(String.format("-Dgemfire.Query.VERBOSE=%1$s", GEMFIRE_QUERY_DEBUG)); - commandLine.addAll(extractJvmArguments(args)); - commandLine.add("-classpath"); - commandLine.add(System.getProperty("java.class.path")); - commandLine.add(type.getName()); - commandLine.addAll(extractProgramArguments(args)); - - // System.err.printf("Java process command-line is (%1$s)%n", commandLine); - - return commandLine; - } - - /* (non-Javadoc) */ - protected static List extractJvmArguments(final String... args) { - List jvmArgs = new ArrayList(args.length); - - for (String arg : args) { - if (arg.startsWith("-")) { - jvmArgs.add(arg); - } - } - - return jvmArgs; - } - - /* (non-Javadoc) */ - protected static List extractProgramArguments(final String... args) { - List jvmArgs = new ArrayList(args.length); - - for (String arg : args) { - if (!arg.startsWith("-")) { - jvmArgs.add(arg); - } - } - - return jvmArgs; - } - - /* (non-Javadoc) */ - protected static Process run(Class type, File directory, String... args) throws IOException { - return new ProcessBuilder().command(createJavaProcessCommandLine(type, args)).directory(directory).start(); - } - - /* (non-Javadoc) */ - protected static boolean waitForCacheServerToStart(CacheServer cacheServer) { - return waitForCacheServerToStart(cacheServer, DEFAULT_WAIT_DURATION); - } - - /* (non-Javadoc) */ - protected static boolean waitForCacheServerToStart(CacheServer cacheServer, long duration) { - return waitForCacheServerToStart(cacheServer.getBindAddress(), cacheServer.getPort(), duration); - } - - /* (non-Javadoc) */ - protected static boolean waitForCacheServerToStart(String host, int port) { - return waitForCacheServerToStart(host, port, DEFAULT_WAIT_DURATION); - } - - /* (non-Javadoc) */ - protected static boolean waitForCacheServerToStart(final String host, final int port, long duration) { - return waitOnCondition(new Condition() { - AtomicBoolean connected = new AtomicBoolean(false); - - public boolean evaluate() { - Socket socket = null; - - try { - if (!connected.get()) { - socket = new Socket(host, port); - connected.set(true); - } - } - catch (IOException ignore) { - } - finally { - GemFireUtils.close(socket); - } - - return connected.get(); - } - }, duration); - } - - // NOTE this method would not be necessary except Spring Sessions' build does not fork - // the test JVM - // for every test class. - /* (non-Javadoc) */ - protected static boolean waitForClientCacheToClose() { - return waitForClientCacheToClose(DEFAULT_WAIT_DURATION); - } - - /* (non-Javadoc) */ - protected static boolean waitForClientCacheToClose(long duration) { - try { - final ClientCache clientCache = ClientCacheFactory.getAnyInstance(); - - clientCache.close(); - - waitOnCondition(new Condition() { - public boolean evaluate() { - return clientCache.isClosed(); - } - }, duration); - - return clientCache.isClosed(); - } - catch (CacheClosedException ignore) { - return true; - } - - } - - /* (non-Javadoc) */ - protected static boolean waitForProcessToStart(Process process, File directory) { - return waitForProcessToStart(process, directory, DEFAULT_WAIT_DURATION); - } - - /* (non-Javadoc) */ - @SuppressWarnings("all") - protected static boolean waitForProcessToStart(Process process, File directory, long duration) { - final File processControl = new File(directory, DEFAULT_PROCESS_CONTROL_FILENAME); - - waitOnCondition(new Condition() { - public boolean evaluate() { - return processControl.isFile(); - } - }, duration); - - return process.isAlive(); - } - - /* (non-Javadoc) */ - protected static int waitForProcessToStop(Process process, File directory) { - return waitForProcessToStop(process, directory, DEFAULT_WAIT_DURATION); - } - - /* (non-Javadoc) */ - protected static int waitForProcessToStop(Process process, File directory, long duration) { - long timeout = (System.currentTimeMillis() + duration); - - try { - while (process.isAlive() && System.currentTimeMillis() < timeout) { - if (process.waitFor(DEFAULT_WAIT_INTERVAL, TimeUnit.MILLISECONDS)) { - return process.exitValue(); - } - } - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - return (process.isAlive() ? -1 : process.exitValue()); - } - - /* (non-Javadoc) */ - protected static boolean waitOnCondition(Condition condition) { - return waitOnCondition(condition, DEFAULT_WAIT_DURATION); - } - - /* (non-Javadoc) */ - @SuppressWarnings("all") - protected static boolean waitOnCondition(Condition condition, long duration) { - long timeout = (System.currentTimeMillis() + duration); - - try { - while (!condition.evaluate() && System.currentTimeMillis() < timeout) { - synchronized (condition) { - TimeUnit.MILLISECONDS.timedWait(condition, DEFAULT_WAIT_INTERVAL); - } - } - } - catch (InterruptedException e) { - Thread.currentThread().interrupt(); - } - - return condition.evaluate(); - } - - /* (non-Javadoc) */ - protected static File writeProcessControlFile(File path) throws IOException { - assertThat(path != null && path.isDirectory()).isTrue(); - - File processControl = new File(path, DEFAULT_PROCESS_CONTROL_FILENAME); - - assertThat(processControl.createNewFile()).isTrue(); - - processControl.deleteOnExit(); - - return processControl; - } - - /* (non-Javadoc) */ - protected void assertValidSession(ExpiringSession session) { - assertThat(session).isNotNull(); - assertThat(session.getId()).isNotEmpty(); - assertThat(session.isExpired()).isFalse(); - } - - /* (non-Javadoc) */ - protected void assertRegion(Region actualRegion, String expectedName, DataPolicy expectedDataPolicy) { - assertThat(actualRegion).isNotNull(); - assertThat(actualRegion.getName()).isEqualTo(expectedName); - assertThat(actualRegion.getFullPath()).isEqualTo(GemFireUtils.toRegionPath(expectedName)); - assertThat(actualRegion.getAttributes()).isNotNull(); - assertThat(actualRegion.getAttributes().getDataPolicy()).isEqualTo(expectedDataPolicy); - } - - /* (non-Javadoc) */ - protected void assertIndex(Index index, String expectedExpression, String expectedFromClause) { - assertThat(index).isNotNull(); - assertThat(index.getIndexedExpression()).isEqualTo(expectedExpression); - assertThat(index.getFromClause()).isEqualTo(expectedFromClause); - } - - /* (non-Javadoc) */ - protected void assertEntryIdleTimeout(Region region, ExpirationAction expectedAction, int expectedTimeout) { - assertEntryIdleTimeout(region.getAttributes().getEntryIdleTimeout(), expectedAction, expectedTimeout); - } - - /* (non-Javadoc) */ - protected void assertEntryIdleTimeout(ExpirationAttributes actualExpirationAttributes, - ExpirationAction expectedAction, int expectedTimeout) { - - assertThat(actualExpirationAttributes).isNotNull(); - assertThat(actualExpirationAttributes.getAction()).isEqualTo(expectedAction); - assertThat(actualExpirationAttributes.getTimeout()).isEqualTo(expectedTimeout); - } - - /* (non-Javadoc) */ - protected boolean enableQueryDebugging() { - return DEFAULT_ENABLE_QUERY_DEBUGGING; - } - - /* (non-Javadoc) */ - protected boolean isQueryDebuggingEnabled() { - return (GEMFIRE_QUERY_DEBUG || enableQueryDebugging()); - } - - /* (non-Javadoc) */ - protected List listRegions(GemFireCache gemfireCache) { - Set> regions = gemfireCache.rootRegions(); - - List regionList = new ArrayList(regions.size()); - - for (Region region : regions) { - regionList.add(region.getFullPath()); - } - - return regionList; - } - - /* (non-Javadoc) */ - @SuppressWarnings("unchecked") - protected T createSession() { - T expiringSession = (T) this.gemfireSessionRepository.createSession(); - assertThat(expiringSession).isNotNull(); - return expiringSession; - } - - /* (non-Javadoc) */ - @SuppressWarnings("unchecked") - protected T createSession(String principalName) { - GemFireOperationsSessionRepository.GemFireSession session = createSession(); - session.setPrincipalName(principalName); - return (T) session; - } - - /* (non-Javadoc) */ - protected T delete(T session) { - this.gemfireSessionRepository.delete(session); - return session; - } - - /* (non-Javadoc) */ - protected T expire(T session) { - session.setLastAccessedTime(0L); - return session; - } - - /* (non-Javadoc) */ - @SuppressWarnings("unchecked") - protected T get(String sessionId) { - return (T) this.gemfireSessionRepository.getSession(sessionId); - } - - /* (non-Javadoc) */ - protected T save(T session) { - this.gemfireSessionRepository.save(session); - return session; - } - - /* (non-Javadoc) */ - protected T touch(T session) { - session.setLastAccessedTime(System.currentTimeMillis()); - return session; - } - - /** - * The SessionEventListener class is a Spring {@link ApplicationListener} listening - * for Spring HTTP Session application events. - * - * @see org.springframework.context.ApplicationListener - * @see org.springframework.session.events.AbstractSessionEvent - */ - public static class SessionEventListener implements ApplicationListener { - - private volatile AbstractSessionEvent sessionEvent; - - /* (non-Javadoc) */ - @SuppressWarnings("unchecked") - public T getSessionEvent() { - T sessionEvent = (T) this.sessionEvent; - this.sessionEvent = null; - return sessionEvent; - } - - /* (non-Javadoc) */ - public void onApplicationEvent(AbstractSessionEvent event) { - this.sessionEvent = event; - } - - /* (non-Javadoc) */ - public T waitForSessionEvent(long duration) { - waitOnCondition(new Condition() { - public boolean evaluate() { - return (SessionEventListener.this.sessionEvent != null); - } - }, duration); - - return getSessionEvent(); - } - } - - /** - * The Condition interface defines a logical condition that must be satisfied before - * it is safe to proceed. - */ - protected interface Condition { - boolean evaluate(); - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java deleted file mode 100644 index b1c0db16..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerGemFireOperationsSessionRepositoryIntegrationTests.java +++ /dev/null @@ -1,374 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.io.File; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientRegionShortcut; - -import org.junit.After; -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.data.gemfire.client.ClientCacheFactoryBean; -import org.springframework.data.gemfire.client.PoolFactoryBean; -import org.springframework.data.gemfire.server.CacheServerFactoryBean; -import org.springframework.data.gemfire.support.ConnectionEndpoint; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.session.events.AbstractSessionEvent; -import org.springframework.session.events.SessionCreatedEvent; -import org.springframework.session.events.SessionDeletedEvent; -import org.springframework.session.events.SessionExpiredEvent; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.util.FileSystemUtils; -import org.springframework.util.SocketUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests to test the functionality of GemFire-backed Spring Sessions using - * the GemFire client-server topology. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.springframework.context.ConfigurableApplicationContext - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests - * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @see org.springframework.test.annotation.DirtiesContext - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringRunner - * @see org.springframework.test.context.web.WebAppConfiguration - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.client.ClientCache - * @see org.apache.geode.cache.client.Pool - * @see org.apache.geode.cache.server.CacheServer - */ -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = - ClientServerGemFireOperationsSessionRepositoryIntegrationTests.SpringSessionDataGemFireClientConfiguration.class) -@DirtiesContext -@WebAppConfiguration -public class ClientServerGemFireOperationsSessionRepositoryIntegrationTests - extends AbstractGemFireIntegrationTests { - - private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1; - - private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); - - private static File processWorkingDirectory; - - private static Process gemfireServer; - - private static final String SPRING_SESSION_GEMFIRE_REGION_NAME = "TestClientServerSessions"; - - @Autowired - private SessionEventListener sessionEventListener; - - @BeforeClass - public static void startGemFireServer() throws IOException { - long t0 = System.currentTimeMillis(); - - int port = SocketUtils.findAvailableTcpPort(); - - System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n", - SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port); - - System.setProperty("spring.session.data.gemfire.port", String.valueOf(port)); - - String processWorkingDirectoryPathname = - String.format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date())); - - processWorkingDirectory = createDirectory(processWorkingDirectoryPathname); - - gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory, - String.format("-Dspring.session.data.gemfire.port=%1$d", port)); - - assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)) - .isTrue(); - - System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0); - } - - @AfterClass - public static void stopGemFireServer() { - if (gemfireServer != null) { - gemfireServer.destroy(); - System.err.printf("GemFire Server [exit code = %1$d]%n", - waitForProcessToStop(gemfireServer, processWorkingDirectory)); - } - - if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) { - FileSystemUtils.deleteRecursively(processWorkingDirectory); - } - - assertThat(waitForClientCacheToClose(DEFAULT_WAIT_DURATION)).isTrue(); - } - - @Before - public void setup() { - assertThat(GemFireUtils.isClient(gemfireCache)).isTrue(); - - Region springSessionGemFireRegion = - gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME); - - assertThat(springSessionGemFireRegion).isNotNull(); - - RegionAttributes springSessionGemFireRegionAttributes = - springSessionGemFireRegion.getAttributes(); - - assertThat(springSessionGemFireRegionAttributes).isNotNull(); - assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.NORMAL); - } - - @After - public void tearDown() { - this.sessionEventListener.getSessionEvent(); - } - - @Test - public void createSessionFiresSessionCreatedEvent() { - long beforeOrAtCreationTime = System.currentTimeMillis(); - - ExpiringSession expectedSession = save(createSession()); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - - ExpiringSession createdSession = sessionEvent.getSession(); - - assertThat(createdSession.getId()).isEqualTo(expectedSession.getId()); - assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime()); - assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - - createdSession.setAttribute("attrOne", 1); - - assertThat(save(touch(createdSession)).getAttribute("attrOne")).isEqualTo(1); - - sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isNull(); - - this.gemfireSessionRepository.delete(expectedSession.getId()); - } - - @Test - public void getExistingNonExpiredSessionBeforeAndAfterExpiration() { - ExpiringSession expectedSession = save(touch(createSession())); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - assertThat(sessionEvent.getSession()).isEqualTo(expectedSession); - assertThat(this.sessionEventListener.getSessionEvent()).isNull(); - - ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(savedSession).isEqualTo(expectedSession); - - sessionEvent = this.sessionEventListener.waitForSessionEvent( - TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1)); - - assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId()); - - ExpiringSession expiredSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(expiredSession).isNull(); - } - - @Test - public void deleteExistingNonExpiredSessionFiresSessionDeletedEventAndReturnsNullOnGet() { - ExpiringSession expectedSession = save(touch(createSession())); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - assertThat(sessionEvent.getSession()).isEqualTo(expectedSession); - - this.gemfireSessionRepository.delete(expectedSession.getId()); - - sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId()); - - ExpiringSession deletedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(deletedSession).isNull(); - } - - @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, - clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY, - maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class SpringSessionDataGemFireClientConfiguration { - - @Bean - static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - return gemfireProperties; - } - - @Bean - ClientCacheFactoryBean gemfireCache() { - ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean(); - - clientCacheFactory.setClose(true); - clientCacheFactory.setProperties(gemfireProperties()); - - return clientCacheFactory; - } - - @Bean - PoolFactoryBean gemfirePool( - @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - PoolFactoryBean poolFactory = new PoolFactoryBean(); - - poolFactory.setKeepAlive(false); - poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5)); - poolFactory.setReadTimeout(2000); // 2 seconds - poolFactory.setRetryAttempts(1); - poolFactory.setSubscriptionEnabled(true); - - poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint( - SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))); - - return poolFactory; - } - - @Bean - public SessionEventListener sessionEventListener() { - return new SessionEventListener(); - } - - // used for debugging purposes - @SuppressWarnings("resource") - public static void main(String[] args) { - ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext( - SpringSessionDataGemFireClientConfiguration.class); - - applicationContext.registerShutdownHook(); - - ClientCache clientCache = applicationContext.getBean(ClientCache.class); - - for (InetSocketAddress server : clientCache.getCurrentServers()) { - System.err.printf("GemFire Server [host: %1$s, port: %2$d]%n", - server.getHostName(), server.getPort()); - } - } - } - - @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, - maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class SpringSessionDataGemFireServerConfiguration { - - static final String SERVER_HOSTNAME = "localhost"; - - @Bean - static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", name()); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - - return gemfireProperties; - } - - String name() { - return ClientServerGemFireOperationsSessionRepositoryIntegrationTests.class.getName(); - } - - @Bean - CacheFactoryBean gemfireCache() { - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, - @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean(); - - cacheServerFactory.setCache(gemfireCache); - cacheServerFactory.setAutoStartup(true); - cacheServerFactory.setBindAddress(SERVER_HOSTNAME); - cacheServerFactory.setPort(port); - - return cacheServerFactory; - } - - @SuppressWarnings("resource") - public static void main(String[] args) throws IOException { - AnnotationConfigApplicationContext context = - new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class); - - context.registerShutdownHook(); - - writeProcessControlFile(WORKING_DIRECTORY); - } - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerHttpSessionAttributesDeltaIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerHttpSessionAttributesDeltaIntegrationTests.java deleted file mode 100644 index f4f95efa..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerHttpSessionAttributesDeltaIntegrationTests.java +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.io.File; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.client.ClientCache; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.data.gemfire.client.ClientCacheFactoryBean; -import org.springframework.data.gemfire.client.PoolFactoryBean; -import org.springframework.data.gemfire.server.CacheServerFactoryBean; -import org.springframework.data.gemfire.support.ConnectionEndpoint; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.FileSystemUtils; -import org.springframework.util.SocketUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests testing the addition/removal of HTTP Session Attributes - * and the proper persistence of the HTTP Session state in a GemFire cache - * across a client/server topology. - * - * @author John Blum - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.springframework.context.ConfigurableApplicationContext - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests - * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringRunner - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.client.ClientCache - * @since 1.3.1 - */ -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = - ClientServerHttpSessionAttributesDeltaIntegrationTests.SpringSessionDataGemFireClientConfiguration.class) -public class ClientServerHttpSessionAttributesDeltaIntegrationTests extends AbstractGemFireIntegrationTests { - - private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1; - - private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); - - private static File processWorkingDirectory; - - private static Process gemfireServer; - - @BeforeClass - public static void startGemFireServer() throws IOException { - long t0 = System.currentTimeMillis(); - - int port = SocketUtils.findAvailableTcpPort(); - - System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n", - SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port); - - System.setProperty("spring.session.data.gemfire.port", String.valueOf(port)); - - String processWorkingDirectoryPathname = - String.format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date())); - - processWorkingDirectory = createDirectory(processWorkingDirectoryPathname); - - gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory, - String.format("-Dspring.session.data.gemfire.port=%1$d", port)); - - assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)) - .isTrue(); - - System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0); - } - - @AfterClass - public static void stopGemFireServer() { - if (gemfireServer != null) { - gemfireServer.destroy(); - System.err.printf("GemFire Server [exit code = %1$d]%n", - waitForProcessToStop(gemfireServer, processWorkingDirectory)); - } - - if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) { - FileSystemUtils.deleteRecursively(processWorkingDirectory); - } - - assertThat(waitForClientCacheToClose(DEFAULT_WAIT_DURATION)).isTrue(); - } - - @Test - public void sessionCreationAndAccessIsSuccessful() { - ExpiringSession session = save(touch(createSession())); - - assertThat(session).isNotNull(); - assertThat(session.isExpired()).isFalse(); - - session.setAttribute("attrOne", 1); - session.setAttribute("attrTwo", 2); - - save(touch(session)); - - ExpiringSession loadedSession = get(session.getId()); - - assertThat(loadedSession).isNotNull(); - assertThat(loadedSession.isExpired()).isFalse(); - assertThat(loadedSession).isNotSameAs(session); - assertThat(loadedSession.getId()).isEqualTo(session.getId()); - assertThat(loadedSession.getAttribute("attrOne")).isEqualTo(1); - assertThat(loadedSession.getAttribute("attrTwo")).isEqualTo(2); - - loadedSession.removeAttribute("attrTwo"); - - assertThat(loadedSession.getAttributeNames()).doesNotContain("attrTwo"); - assertThat(loadedSession.getAttributeNames()).hasSize(1); - - save(touch(loadedSession)); - - ExpiringSession reloadedSession = get(loadedSession.getId()); - - assertThat(reloadedSession).isNotNull(); - assertThat(reloadedSession.isExpired()).isFalse(); - assertThat(reloadedSession).isNotSameAs(loadedSession); - assertThat(reloadedSession.getId()).isEqualTo(loadedSession.getId()); - assertThat(reloadedSession.getAttributeNames()).hasSize(1); - assertThat(reloadedSession.getAttributeNames()).doesNotContain("attrTwo"); - assertThat(reloadedSession.getAttribute("attrOne")).isEqualTo(1); - } - - @EnableGemFireHttpSession - static class SpringSessionDataGemFireClientConfiguration { - - @Bean - static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - return gemfireProperties; - } - - @Bean - ClientCacheFactoryBean gemfireCache() { - ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean(); - - clientCacheFactory.setClose(true); - clientCacheFactory.setProperties(gemfireProperties()); - - return clientCacheFactory; - } - - @Bean - PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:" - + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - PoolFactoryBean poolFactory = new PoolFactoryBean(); - - poolFactory.setKeepAlive(false); - poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5)); - poolFactory.setReadTimeout(2000); // 2 seconds - poolFactory.setRetryAttempts(1); - poolFactory.setSubscriptionEnabled(true); - - poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint( - SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))); - - return poolFactory; - } - - // used for debugging purposes - @SuppressWarnings("resource") - public static void main(String[] args) { - ConfigurableApplicationContext applicationContext = - new AnnotationConfigApplicationContext(SpringSessionDataGemFireClientConfiguration.class); - - applicationContext.registerShutdownHook(); - - ClientCache clientCache = applicationContext.getBean(ClientCache.class); - - for (InetSocketAddress server : clientCache.getCurrentServers()) { - System.err.printf("GemFire Server [host: %1$s, port: %2$d]%n", - server.getHostName(), server.getPort()); - } - } - } - - @EnableGemFireHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class SpringSessionDataGemFireServerConfiguration { - - static final String SERVER_HOSTNAME = "localhost"; - - @Bean - static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", name()); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - - return gemfireProperties; - } - - String name() { - return ClientServerHttpSessionAttributesDeltaIntegrationTests.class.getName(); - } - - @Bean - CacheFactoryBean gemfireCache() { - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, - @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean(); - - cacheServerFactory.setCache(gemfireCache); - cacheServerFactory.setAutoStartup(true); - cacheServerFactory.setBindAddress(SERVER_HOSTNAME); - cacheServerFactory.setPort(port); - - return cacheServerFactory; - } - - @SuppressWarnings("resource") - public static void main(String[] args) throws IOException { - AnnotationConfigApplicationContext context = - new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class); - - context.registerShutdownHook(); - - writeProcessControlFile(WORKING_DIRECTORY); - } - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerProxyRegionSessionOperationsIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerProxyRegionSessionOperationsIntegrationTests.java deleted file mode 100644 index 1310085b..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/ClientServerProxyRegionSessionOperationsIntegrationTests.java +++ /dev/null @@ -1,309 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.io.File; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Collections; -import java.util.Date; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.client.ClientCache; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.data.gemfire.client.ClientCacheFactoryBean; -import org.springframework.data.gemfire.client.PoolFactoryBean; -import org.springframework.data.gemfire.server.CacheServerFactoryBean; -import org.springframework.data.gemfire.support.ConnectionEndpoint; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.session.events.AbstractSessionEvent; -import org.springframework.session.events.SessionCreatedEvent; -import org.springframework.session.events.SessionDeletedEvent; -import org.springframework.session.events.SessionExpiredEvent; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.FileSystemUtils; -import org.springframework.util.SocketUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * The ClientServerProxyRegionSessionOperationsIntegrationTests class... - * - * @author John Blum - * @since 1.0.0 - */ -@RunWith(SpringRunner.class) -@ContextConfiguration(classes = - ClientServerProxyRegionSessionOperationsIntegrationTests.SpringSessionDataGemFireClientConfiguration.class) -public class ClientServerProxyRegionSessionOperationsIntegrationTests extends AbstractGemFireIntegrationTests { - - private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1; - - private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); - - private static File processWorkingDirectory; - - private static Process gemfireServer; - - @Autowired - private SessionEventListener sessionEventListener; - - @BeforeClass - public static void startGemFireServer() throws IOException { - long t0 = System.currentTimeMillis(); - - int port = SocketUtils.findAvailableTcpPort(); - - System.err.printf("Starting a GemFire Server running on host [%1$s] listening on port [%2$d]%n", - SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port); - - System.setProperty("spring.session.data.gemfire.port", String.valueOf(port)); - - String processWorkingDirectoryPathname = - String.format("gemfire-client-server-tests-%1$s", TIMESTAMP.format(new Date())); - - processWorkingDirectory = createDirectory(processWorkingDirectoryPathname); - - gemfireServer = run(SpringSessionDataGemFireServerConfiguration.class, processWorkingDirectory, - String.format("-Dspring.session.data.gemfire.port=%1$d", port)); - - assertThat(waitForCacheServerToStart(SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port)) - .isTrue(); - - System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0); - } - - @AfterClass - public static void stopGemFireServer() { - if (gemfireServer != null) { - gemfireServer.destroy(); - System.err.printf("GemFire Server [exit code = %1$d]%n", - waitForProcessToStop(gemfireServer, processWorkingDirectory)); - } - - if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) { - FileSystemUtils.deleteRecursively(processWorkingDirectory); - } - - assertThat(waitForClientCacheToClose(DEFAULT_WAIT_DURATION)).isTrue(); - } - - @Test - public void createReadUpdateExpireRecreateDeleteRecreateSessionResultsCorrectSessionCreatedEvents() { - ExpiringSession session = save(touch(createSession())); - - assertValidSession(session); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId()); - - // GET - ExpiringSession loadedSession = get(session.getId()); - - assertThat(loadedSession).isNotNull(); - assertThat(loadedSession.getId()).isEqualTo(session.getId()); - assertThat(loadedSession.getCreationTime()).isEqualTo(session.getCreationTime()); - assertThat(loadedSession.getLastAccessedTime()).isGreaterThanOrEqualTo((session.getLastAccessedTime())); - - sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isNull(); - - loadedSession.setAttribute("attrOne", 1); - loadedSession.setAttribute("attrTwo", 2); - - // UPDATE - save(touch(loadedSession)); - - sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isNull(); - - // EXPIRE - sessionEvent = this.sessionEventListener.waitForSessionEvent( - TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1)); - - assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId()); - - // RECREATE - save(touch(session)); - - sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId()); - - // DELETE - delete(session); - - sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId()); - - // RECREATE - save(touch(session)); - - sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(session.getId()); - } - - @EnableGemFireHttpSession - static class SpringSessionDataGemFireClientConfiguration { - - @Bean - static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - return gemfireProperties; - } - - @Bean - ClientCacheFactoryBean gemfireCache() { - ClientCacheFactoryBean clientCacheFactory = new ClientCacheFactoryBean(); - - clientCacheFactory.setClose(true); - clientCacheFactory.setProperties(gemfireProperties()); - - return clientCacheFactory; - } - - @Bean - PoolFactoryBean gemfirePool(@Value("${spring.session.data.gemfire.port:" - + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - PoolFactoryBean poolFactory = new PoolFactoryBean(); - - poolFactory.setKeepAlive(false); - poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5)); - poolFactory.setReadTimeout(2000); // 2 seconds - poolFactory.setRetryAttempts(1); - poolFactory.setSubscriptionEnabled(true); - - poolFactory.setServers(Collections.singletonList(new ConnectionEndpoint( - SpringSessionDataGemFireServerConfiguration.SERVER_HOSTNAME, port))); - - return poolFactory; - } - - @Bean - public SessionEventListener sessionEventListener() { - return new SessionEventListener(); - } - - // used for debugging purposes - @SuppressWarnings("resource") - public static void main(String[] args) { - ConfigurableApplicationContext applicationContext = - new AnnotationConfigApplicationContext(SpringSessionDataGemFireClientConfiguration.class); - - applicationContext.registerShutdownHook(); - - ClientCache clientCache = applicationContext.getBean(ClientCache.class); - - for (InetSocketAddress server : clientCache.getCurrentServers()) { - System.err.printf("GemFire Server [host: %1$s, port: %2$d]%n", - server.getHostName(), server.getPort()); - } - } - } - - @EnableGemFireHttpSession(maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class SpringSessionDataGemFireServerConfiguration { - - static final String SERVER_HOSTNAME = "localhost"; - - @Bean - static PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", name()); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - - return gemfireProperties; - } - - String name() { - return ClientServerProxyRegionSessionOperationsIntegrationTests.class.getName(); - } - - @Bean - CacheFactoryBean gemfireCache() { - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, - @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean(); - - cacheServerFactory.setCache(gemfireCache); - cacheServerFactory.setAutoStartup(true); - cacheServerFactory.setBindAddress(SERVER_HOSTNAME); - cacheServerFactory.setPort(port); - - return cacheServerFactory; - } - - @SuppressWarnings("resource") - public static void main(String[] args) throws IOException { - AnnotationConfigApplicationContext context = - new AnnotationConfigApplicationContext(SpringSessionDataGemFireServerConfiguration.class); - - context.registerShutdownHook(); - - writeProcessControlFile(WORKING_DIRECTORY); - } - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryIntegrationTests.java deleted file mode 100644 index 32dec376..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryIntegrationTests.java +++ /dev/null @@ -1,459 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Properties; -import java.util.UUID; - -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.query.Query; -import org.apache.geode.cache.query.QueryService; -import org.apache.geode.cache.query.SelectResults; -import org.apache.geode.pdx.PdxReader; -import org.apache.geode.pdx.PdxSerializable; -import org.apache.geode.pdx.PdxWriter; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; -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.FindByIndexNameSessionRepository; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test to test the {@code findByPrincipalName} query method - * on {@link GemFireOperationsSessionRepository}. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests - * @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository - * @see org.springframework.test.annotation.DirtiesContext - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner - * @see org.springframework.test.context.web.WebAppConfiguration - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.Region - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -@DirtiesContext -@WebAppConfiguration -public class GemFireOperationsSessionRepositoryIntegrationTests extends AbstractGemFireIntegrationTests { - - private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 300; - - private static final String GEMFIRE_LOG_LEVEL = "warning"; - private static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; - private static final String SPRING_SESSION_GEMFIRE_REGION_NAME = "TestPartitionedSessions"; - - SecurityContext context; - - SecurityContext changedContext; - - @Before - public void setup() { - this.context = SecurityContextHolder.createEmptyContext(); - this.context.setAuthentication( - new UsernamePasswordAuthenticationToken("username-" + UUID.randomUUID(), - "na", AuthorityUtils.createAuthorityList("ROLE_USER"))); - - this.changedContext = SecurityContextHolder.createEmptyContext(); - this.changedContext.setAuthentication(new UsernamePasswordAuthenticationToken( - "changedContext-" + UUID.randomUUID(), "na", - AuthorityUtils.createAuthorityList("ROLE_USER"))); - - assertThat(this.gemfireCache).isNotNull(); - assertThat(this.gemfireSessionRepository).isNotNull(); - assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds()) - .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - - Region sessionRegion = this.gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME); - - assertRegion(sessionRegion, SPRING_SESSION_GEMFIRE_REGION_NAME, DataPolicy.PARTITION); - assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE, MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - protected Map doFindByIndexNameAndIndexValue( - String indexName, String indexValue) { - - return this.gemfireSessionRepository.findByIndexNameAndIndexValue(indexName, - indexValue); - } - - protected Map doFindByPrincipalName(String principalName) { - return doFindByIndexNameAndIndexValue(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, - principalName); - } - - @SuppressWarnings({ "unchecked" }) - protected Map doFindByPrincipalName(String regionName, - String principalName) { - try { - Region region = this.gemfireCache.getRegion(regionName); - - assertThat(region).isNotNull(); - - QueryService queryService = region.getRegionService().getQueryService(); - - String queryString = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, - region.getFullPath()); - - Query query = queryService.newQuery(queryString); - - SelectResults results = - (SelectResults) query.execute(new Object[] { principalName }); - - Map sessions = new HashMap(results.size()); - - for (ExpiringSession session : results.asList()) { - sessions.put(session.getId(), session); - } - - return sessions; - } - catch (Exception e) { - throw new RuntimeException(e); - } - } - - @Override - protected boolean enableQueryDebugging() { - return true; - } - - protected ExpiringSession setAttribute(ExpiringSession session, String attributeName, - Object attributeValue) { - - session.setAttribute(attributeName, attributeValue); - - return session; - } - - @Test - public void findSessionsByIndexedSessionAttributeNameValues() { - ExpiringSession johnBlumSession = save(touch(setAttribute( - createSession("johnBlum"), "vip", "yes"))); - ExpiringSession robWinchSession = save(touch(setAttribute( - createSession("robWinch"), "vip", "yes"))); - ExpiringSession jonDoeSession = save(touch(setAttribute( - createSession("jonDoe"), "vip", "no"))); - ExpiringSession pieDoeSession = save(touch(setAttribute( - createSession("pieDoe"), "viper", "true"))); - ExpiringSession sourDoeSession = save(touch(createSession("sourDoe"))); - - assertThat(this.get(johnBlumSession.getId())).isEqualTo(johnBlumSession); - assertThat(johnBlumSession.getAttribute("vip")).isEqualTo("yes"); - assertThat(this.get(robWinchSession.getId())).isEqualTo(robWinchSession); - assertThat(robWinchSession.getAttribute("vip")).isEqualTo("yes"); - assertThat(this.get(jonDoeSession.getId())).isEqualTo(jonDoeSession); - assertThat(jonDoeSession.getAttribute("vip")).isEqualTo("no"); - assertThat(this.get(pieDoeSession.getId())).isEqualTo(pieDoeSession); - assertThat(pieDoeSession.getAttributeNames().contains("vip")).isFalse(); - assertThat(this.get(sourDoeSession.getId())).isEqualTo(sourDoeSession); - assertThat(sourDoeSession.getAttributeNames().contains("vip")).isFalse(); - - Map vipSessions = doFindByIndexNameAndIndexValue("vip", "yes"); - - assertThat(vipSessions).isNotNull(); - assertThat(vipSessions.size()).isEqualTo(2); - assertThat(vipSessions.get(johnBlumSession.getId())).isEqualTo(johnBlumSession); - assertThat(vipSessions.get(robWinchSession.getId())).isEqualTo(robWinchSession); - assertThat(vipSessions.containsKey(jonDoeSession.getId())); - assertThat(vipSessions.containsKey(pieDoeSession.getId())); - assertThat(vipSessions.containsKey(sourDoeSession.getId())); - - Map nonVipSessions = doFindByIndexNameAndIndexValue( - "vip", "no"); - - assertThat(nonVipSessions).isNotNull(); - assertThat(nonVipSessions.size()).isEqualTo(1); - assertThat(nonVipSessions.get(jonDoeSession.getId())).isEqualTo(jonDoeSession); - assertThat(nonVipSessions.containsKey(johnBlumSession.getId())); - assertThat(nonVipSessions.containsKey(robWinchSession.getId())); - assertThat(nonVipSessions.containsKey(pieDoeSession.getId())); - assertThat(nonVipSessions.containsKey(sourDoeSession.getId())); - - Map noSessions = doFindByIndexNameAndIndexValue( - "nonExistingAttribute", "test"); - - assertThat(noSessions).isNotNull(); - assertThat(noSessions.isEmpty()).isTrue(); - } - - @Test - public void findSessionsByPrincipalName() { - ExpiringSession sessionOne = save(touch(createSession("robWinch"))); - ExpiringSession sessionTwo = save(touch(createSession("johnBlum"))); - ExpiringSession sessionThree = save(touch(createSession("robWinch"))); - ExpiringSession sessionFour = save(touch(createSession("johnBlum"))); - ExpiringSession sessionFive = save(touch(createSession("robWinch"))); - - assertThat(this.get(sessionOne.getId())).isEqualTo(sessionOne); - assertThat(this.get(sessionTwo.getId())).isEqualTo(sessionTwo); - assertThat(this.get(sessionThree.getId())).isEqualTo(sessionThree); - assertThat(this.get(sessionFour.getId())).isEqualTo(sessionFour); - assertThat(this.get(sessionFive.getId())).isEqualTo(sessionFive); - - Map johnBlumSessions = doFindByPrincipalName("johnBlum"); - - assertThat(johnBlumSessions).isNotNull(); - assertThat(johnBlumSessions.size()).isEqualTo(2); - assertThat(johnBlumSessions.containsKey(sessionOne.getId())).isFalse(); - assertThat(johnBlumSessions.containsKey(sessionThree.getId())).isFalse(); - assertThat(johnBlumSessions.containsKey(sessionFive.getId())).isFalse(); - assertThat(johnBlumSessions.get(sessionTwo.getId())).isEqualTo(sessionTwo); - assertThat(johnBlumSessions.get(sessionFour.getId())).isEqualTo(sessionFour); - - Map robWinchSessions = doFindByPrincipalName("robWinch"); - - assertThat(robWinchSessions).isNotNull(); - assertThat(robWinchSessions.size()).isEqualTo(3); - assertThat(robWinchSessions.containsKey(sessionTwo.getId())).isFalse(); - assertThat(robWinchSessions.containsKey(sessionFour.getId())).isFalse(); - assertThat(robWinchSessions.get(sessionOne.getId())).isEqualTo(sessionOne); - assertThat(robWinchSessions.get(sessionThree.getId())).isEqualTo(sessionThree); - assertThat(robWinchSessions.get(sessionFive.getId())).isEqualTo(sessionFive); - } - - @Test - public void findSessionsBySecurityPrincipalName() { - ExpiringSession toSave = this.gemfireSessionRepository.createSession(); - - toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context); - - save(toSave); - - Map findByPrincipalName = doFindByPrincipalName(getSecurityName()); - - assertThat(findByPrincipalName).hasSize(1); - assertThat(findByPrincipalName.keySet()).containsOnly(toSave.getId()); - } - - @Test - public void findSessionsByChangedSecurityPrincipalName() { - ExpiringSession toSave = this.gemfireSessionRepository.createSession(); - - toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.context); - - save(toSave); - - toSave.setAttribute(SPRING_SECURITY_CONTEXT, this.changedContext); - - save(toSave); - - Map findByPrincipalName = doFindByPrincipalName(getSecurityName()); - - assertThat(findByPrincipalName).isEmpty(); - - findByPrincipalName = doFindByPrincipalName(getChangedSecurityName()); - - assertThat(findByPrincipalName).hasSize(1); - } - - @Test - public void findsNoSessionsByNonExistingPrincipal() { - Map nonExistingPrincipalSessions = - doFindByPrincipalName("nonExistingPrincipalName"); - - assertThat(nonExistingPrincipalSessions).isNotNull(); - assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue(); - } - - @Test - public void findsNoSessionsAfterPrincipalIsRemoved() { - String username = "doesNotFindAfterPrincipalRemoved"; - ExpiringSession session = save(touch(createSession(username))); - - session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, null); - - save(session); - - Map nonExistingPrincipalSessions = doFindByPrincipalName(username); - - assertThat(nonExistingPrincipalSessions).isNotNull(); - assertThat(nonExistingPrincipalSessions.isEmpty()).isTrue(); - } - - @Test - public void saveAndReadSessionWithAttributes() { - ExpiringSession expectedSession = this.gemfireSessionRepository.createSession(); - - assertThat(expectedSession).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class); - - ((AbstractGemFireOperationsSessionRepository.GemFireSession) expectedSession).setPrincipalName("jblum"); - - List expectedAttributeNames = Arrays.asList("booleanAttribute", "numericAttribute", "stringAttribute", - "personAttribute"); - - Person jonDoe = new Person("Jon", "Doe"); - - expectedSession.setAttribute(expectedAttributeNames.get(0), true); - expectedSession.setAttribute(expectedAttributeNames.get(1), Math.PI); - expectedSession.setAttribute(expectedAttributeNames.get(2), "test"); - expectedSession.setAttribute(expectedAttributeNames.get(3), jonDoe); - - this.gemfireSessionRepository.save(touch(expectedSession)); - - ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(savedSession).isEqualTo(expectedSession); - assertThat(savedSession).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class); - assertThat(((AbstractGemFireOperationsSessionRepository.GemFireSession) savedSession).getPrincipalName()) - .isEqualTo("jblum"); - - assertThat(savedSession.getAttributeNames().containsAll(expectedAttributeNames)) - .as(String.format("Expected (%1$s); but was (%2$s)", expectedAttributeNames, savedSession.getAttributeNames())) - .isTrue(); - - assertThat(savedSession.getAttribute(expectedAttributeNames.get(0))).isTrue(); - assertThat(savedSession.getAttribute(expectedAttributeNames.get(1))).isEqualTo(Math.PI); - assertThat(savedSession.getAttribute(expectedAttributeNames.get(2))).isEqualTo("test"); - assertThat(savedSession.getAttribute(expectedAttributeNames.get(3))).isEqualTo(jonDoe); - } - - private String getSecurityName() { - return this.context.getAuthentication().getName(); - } - - private String getChangedSecurityName() { - return this.changedContext.getAuthentication().getName(); - } - - @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class SpringSessionGemFireConfiguration { - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", GemFireOperationsSessionRepositoryIntegrationTests.class.getName()); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - - return gemfireProperties; - } - - @Bean - CacheFactoryBean gemfireCache() { - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - } - - public static class Person implements Comparable, PdxSerializable { - - private String firstName; - private String lastName; - - public Person() { - } - - public Person(String firstName, String lastName) { - this.firstName = validate(firstName); - this.lastName = validate(lastName); - } - - private String validate(String value) { - Assert.hasText(value, String.format("The String value (%1$s) must be specified!", value)); - return value; - } - - public String getFirstName() { - return this.firstName; - } - - public String getLastName() { - return this.lastName; - } - - public String getName() { - return String.format("%1$s %2$s", getFirstName(), getLastName()); - } - - public void toData(PdxWriter pdxWriter) { - pdxWriter.writeString("firstName", getFirstName()); - pdxWriter.writeString("lastName", getLastName()); - } - - public void fromData(final PdxReader pdxReader) { - this.firstName = pdxReader.readString("firstName"); - this.lastName = pdxReader.readString("lastName"); - } - - @SuppressWarnings("all") - public int compareTo(final Person person) { - int compareValue = getLastName().compareTo(person.getLastName()); - return (compareValue != 0 ? compareValue - : getFirstName().compareTo(person.getFirstName())); - } - - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof Person)) { - return false; - } - - Person that = (Person) obj; - - return ObjectUtils.nullSafeEquals(this.getFirstName(), that.getFirstName()) - && ObjectUtils.nullSafeEquals(this.getLastName(), that.getLastName()); - } - - @Override - public int hashCode() { - int hashValue = 17; - hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getFirstName()); - hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getLastName()); - return hashValue; - } - - @Override - public String toString() { - return getName(); - } - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests.java deleted file mode 100644 index 91204e6c..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests.java +++ /dev/null @@ -1,344 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.io.File; -import java.io.IOException; -import java.net.InetSocketAddress; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.Date; -import java.util.Properties; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.client.ClientCache; - -import org.junit.AfterClass; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.AnnotationConfigApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.data.gemfire.client.ClientCacheFactoryBean; -import org.springframework.data.gemfire.client.PoolFactoryBean; -import org.springframework.data.gemfire.server.CacheServerFactoryBean; -import org.springframework.data.gemfire.support.ConnectionEndpoint; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.session.events.AbstractSessionEvent; -import org.springframework.session.events.SessionCreatedEvent; -import org.springframework.session.events.SessionExpiredEvent; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; -import org.springframework.util.FileSystemUtils; -import org.springframework.util.SocketUtils; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test to test the functionality of a GemFire cache client in a Spring Session application - * using a specifically named GemFire {@link org.apache.geode.cache.client.Pool} configured with - * the 'poolName' attribute in the Spring Session Data GemFire {@link EnableGemFireHttpSession} annotation. - * - * @author John Blum - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests - * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @see org.springframework.test.annotation.DirtiesContext - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner - * @see org.springframework.test.context.web.WebAppConfiguration - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.client.ClientCache - * @see org.apache.geode.cache.client.Pool - * @see org.apache.geode.cache.server.CacheServer - * @since 1.3.0 - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration(classes = MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests - .SpringSessionGemFireClientConfiguration.class) -@DirtiesContext -@WebAppConfiguration -public class MultiPoolClientServerGemFireOperationsSessionRepositoryIntegrationTests - extends AbstractGemFireIntegrationTests { - - private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1; - - private static final DateFormat TIMESTAMP = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss"); - - private static File processWorkingDirectory; - - private static Process gemfireServer; - - private static final String SPRING_SESSION_GEMFIRE_REGION_NAME = "TestMultiPoolClientServerSessions"; - - @Autowired - private SessionEventListener sessionEventListener; - - @BeforeClass - public static void startGemFireServer() throws IOException { - final long t0 = System.currentTimeMillis(); - - final int port = SocketUtils.findAvailableTcpPort(); - - System.err.printf("Starting a GemFire Server on [%1$s] listening on port [%2$d]%n", - SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port); - - System.setProperty("spring.session.data.gemfire.port", String.valueOf(port)); - - String processWorkingDirectoryPathname = String.format("gemfire-multipool-client-server-tests-%1$s", - TIMESTAMP.format(new Date())); - - processWorkingDirectory = createDirectory(processWorkingDirectoryPathname); - - gemfireServer = run(SpringSessionGemFireServerConfiguration.class, processWorkingDirectory, - String.format("-Dspring.session.data.gemfire.port=%1$d", port)); - - assertThat(waitForCacheServerToStart(SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)).isTrue(); - - System.err.printf("GemFire Server [startup time = %1$d ms]%n", System.currentTimeMillis() - t0); - } - - @AfterClass - public static void stopGemFireServerAndDeleteArtifacts() { - if (gemfireServer != null) { - gemfireServer.destroyForcibly(); - System.err.printf("GemFire Server [exit code = %1$d]%n", - waitForProcessToStop(gemfireServer, processWorkingDirectory)); - } - - if (Boolean.valueOf(System.getProperty("spring.session.data.gemfire.fork.clean", Boolean.TRUE.toString()))) { - FileSystemUtils.deleteRecursively(processWorkingDirectory); - } - - assertThat(waitForClientCacheToClose(DEFAULT_WAIT_DURATION)).isTrue(); - } - - @Before - public void setup() { - assertThat(GemFireUtils.isClient(gemfireCache)).isTrue(); - - Region springSessionGemFireRegion = - gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME); - - assertThat(springSessionGemFireRegion).isNotNull(); - - RegionAttributes springSessionGemFireRegionAttributes = - springSessionGemFireRegion.getAttributes(); - - assertThat(springSessionGemFireRegionAttributes).isNotNull(); - assertThat(springSessionGemFireRegionAttributes.getDataPolicy()).isEqualTo(DataPolicy.EMPTY); - } - - protected static ConnectionEndpoint newConnectionEndpoint(String host, int port) { - return new ConnectionEndpoint(host, port); - } - - @Test - public void getExistingNonExpiredSessionBeforeAndAfterExpiration() { - ExpiringSession expectedSession = save(touch(createSession())); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.waitForSessionEvent(500); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - assertThat(sessionEvent.getSession()).isEqualTo(expectedSession); - assertThat(this.sessionEventListener.getSessionEvent()).isNull(); - - ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(savedSession).isEqualTo(expectedSession); - - this.sessionEventListener.getSessionEvent(); - - sessionEvent = this.sessionEventListener.waitForSessionEvent( - TimeUnit.SECONDS.toMillis(MAX_INACTIVE_INTERVAL_IN_SECONDS + 1)); - - assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSession.getId()); - - ExpiringSession expiredSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(expiredSession).isNull(); - } - - @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, poolName = "serverPool", - maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class SpringSessionGemFireClientConfiguration { - - @Bean - PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - @Bean - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("name", name()); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - return gemfireProperties; - } - - String name() { - return SpringSessionGemFireClientConfiguration.class.getName(); - } - - @Bean - ClientCacheFactoryBean gemfireCache() { - ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setPoolName("gemfirePool"); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - PoolFactoryBean gemfirePool() { - PoolFactoryBean poolFactory = new PoolFactoryBean(); - - poolFactory.setFreeConnectionTimeout(5000); // 5 seconds - poolFactory.setKeepAlive(false); - poolFactory.setMinConnections(0); - poolFactory.setReadTimeout(500); - - // deliberately set to a non-existing GemFire (Cache) Server - poolFactory.addServers(newConnectionEndpoint("localhost", 53135)); - - return poolFactory; - } - - @Bean - PoolFactoryBean serverPool(@Value("${spring.session.data.gemfire.port:" - + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - PoolFactoryBean poolFactory = new PoolFactoryBean(); - - poolFactory.setFreeConnectionTimeout(5000); // 5 seconds - poolFactory.setKeepAlive(false); - poolFactory.setMaxConnections(SpringSessionGemFireServerConfiguration.MAX_CONNECTIONS); - poolFactory.setPingInterval(TimeUnit.SECONDS.toMillis(5)); - poolFactory.setReadTimeout(2000); // 2 seconds - poolFactory.setRetryAttempts(1); - poolFactory.setSubscriptionEnabled(true); - poolFactory.setThreadLocalConnections(false); - - poolFactory.addServers(newConnectionEndpoint( - SpringSessionGemFireServerConfiguration.SERVER_HOSTNAME, port)); - - return poolFactory; - } - - @Bean - public AbstractGemFireIntegrationTests.SessionEventListener sessionEventListener() { - return new AbstractGemFireIntegrationTests.SessionEventListener(); - } - - // used for debugging purposes - @SuppressWarnings("resource") - public static void main(final String[] args) { - ConfigurableApplicationContext applicationContext = new AnnotationConfigApplicationContext( - SpringSessionGemFireClientConfiguration.class); - - applicationContext.registerShutdownHook(); - - ClientCache clientCache = applicationContext.getBean(ClientCache.class); - - for (InetSocketAddress server : clientCache.getCurrentServers()) { - System.err.printf("GemFire Server [host: %1$s, port: %2$d]%n", - server.getHostName(), server.getPort()); - } - } - } - - @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS) - static class SpringSessionGemFireServerConfiguration { - - static final int MAX_CONNECTIONS = 50; - static final String SERVER_HOSTNAME = "localhost"; - - @Bean - PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer() { - return new PropertySourcesPlaceholderConfigurer(); - } - - @Bean - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", name()); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-file", "server.log"); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - - return gemfireProperties; - } - - String name() { - return SpringSessionGemFireServerConfiguration.class.getName(); - } - - @Bean - CacheFactoryBean gemfireCache() { - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - CacheServerFactoryBean gemfireCacheServer(Cache gemfireCache, - @Value("${spring.session.data.gemfire.port:" + DEFAULT_GEMFIRE_SERVER_PORT + "}") int port) { - - CacheServerFactoryBean cacheServerFactory = new CacheServerFactoryBean(); - - cacheServerFactory.setAutoStartup(true); - cacheServerFactory.setBindAddress(SERVER_HOSTNAME); - cacheServerFactory.setCache(gemfireCache); - cacheServerFactory.setMaxConnections(MAX_CONNECTIONS); - cacheServerFactory.setPort(port); - - return cacheServerFactory; - } - - @SuppressWarnings("resource") - public static void main(final String[] args) throws IOException { - AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext( - SpringSessionGemFireServerConfiguration.class); - context.registerShutdownHook(); - writeProcessControlFile(WORKING_DIRECTORY); - } - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSessionEventsIntegrationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSessionEventsIntegrationTests.java deleted file mode 100644 index ecc67880..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSessionEventsIntegrationTests.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http; - -import java.util.Properties; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionShortcut; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.session.events.AbstractSessionEvent; -import org.springframework.session.events.SessionCreatedEvent; -import org.springframework.session.events.SessionDeletedEvent; -import org.springframework.session.events.SessionExpiredEvent; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * The EnableGemFireHttpSessionEventsIntegrationTests class is a test suite of test cases - * testing the Session Event functionality and behavior of the - * GemFireOperationsSessionRepository and GemFire's configuration. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests - * @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository - * @see org.springframework.session.events.SessionCreatedEvent - * @see org.springframework.session.events.SessionDeletedEvent - * @see org.springframework.session.events.SessionExpiredEvent - * @see org.springframework.test.annotation.DirtiesContext - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner - * @see org.springframework.test.context.web.WebAppConfiguration - * @see org.apache.geode.cache.Region - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -@DirtiesContext -@WebAppConfiguration -public class EnableGemFireHttpSessionEventsIntegrationTests extends AbstractGemFireIntegrationTests { - - private static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 1; - - private static final String GEMFIRE_LOG_LEVEL = "warning"; - private static final String SPRING_SESSION_GEMFIRE_REGION_NAME = "TestReplicatedSessions"; - - @Autowired - private SessionEventListener sessionEventListener; - - @Before - public void setup() { - assertThat(GemFireUtils.isPeer(this.gemfireCache)).isTrue(); - assertThat(this.gemfireSessionRepository).isNotNull(); - assertThat(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds()) - .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - assertThat(this.sessionEventListener).isNotNull(); - - Region sessionRegion = this.gemfireCache.getRegion(SPRING_SESSION_GEMFIRE_REGION_NAME); - - assertRegion(sessionRegion, SPRING_SESSION_GEMFIRE_REGION_NAME, DataPolicy.REPLICATE); - assertEntryIdleTimeout(sessionRegion, ExpirationAction.INVALIDATE, MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - @After - public void tearDown() { - this.sessionEventListener.getSessionEvent(); - } - - @Test - public void sessionCreatedEvent() { - final long beforeOrAtCreationTime = System.currentTimeMillis(); - - ExpiringSession expectedSession = save(createSession()); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.getSessionEvent(); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - - ExpiringSession createdSession = sessionEvent.getSession(); - - assertThat(createdSession).isEqualTo(expectedSession); - assertThat(createdSession.getId()).isNotNull(); - assertThat(createdSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(createdSession.getLastAccessedTime()).isEqualTo(createdSession.getCreationTime()); - assertThat(createdSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - assertThat(createdSession.isExpired()).isFalse(); - } - - @Test - public void getExistingNonExpiredSession() { - ExpiringSession expectedSession = save(touch(createSession())); - - assertThat(expectedSession.isExpired()).isFalse(); - - // NOTE though unlikely, a possible race condition exists between save and get... - ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(savedSession).isEqualTo(expectedSession); - } - - @Test - public void getExistingExpiredSession() { - ExpiringSession expectedSession = save(expire(createSession())); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.getSessionEvent(); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - - ExpiringSession createdSession = sessionEvent.getSession(); - - assertThat(createdSession).isEqualTo(expectedSession); - assertThat(createdSession.isExpired()).isTrue(); - assertThat(this.gemfireSessionRepository.getSession(createdSession.getId())).isNull(); - } - - @Test - public void getNonExistingSession() { - assertThat(this.gemfireSessionRepository.getSession(UUID.randomUUID().toString())).isNull(); - } - - @Test - public void deleteExistingNonExpiredSession() { - ExpiringSession expectedSession = save(touch(createSession())); - ExpiringSession savedSession = this.gemfireSessionRepository.getSession(expectedSession.getId()); - - assertThat(savedSession).isEqualTo(expectedSession); - assertThat(savedSession.isExpired()).isFalse(); - - this.gemfireSessionRepository.delete(savedSession.getId()); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.getSessionEvent(); - - assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class); - assertThat(sessionEvent.getSessionId()).isEqualTo(savedSession.getId()); - - ExpiringSession deletedSession = sessionEvent.getSession(); - - assertThat(deletedSession).isEqualTo(savedSession); - assertThat(this.gemfireSessionRepository.getSession(deletedSession.getId())).isNull(); - } - - @Test - public void deleteExistingExpiredSession() { - ExpiringSession expectedSession = save(createSession()); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.getSessionEvent(); - - assertThat(sessionEvent).isInstanceOf(SessionCreatedEvent.class); - - ExpiringSession createdSession = sessionEvent.getSession(); - - assertThat(createdSession).isEqualTo(expectedSession); - - sessionEvent = this.sessionEventListener.waitForSessionEvent( - TimeUnit.SECONDS.toMillis(this.gemfireSessionRepository.getMaxInactiveIntervalInSeconds() + 1)); - - assertThat(sessionEvent).isInstanceOf(SessionExpiredEvent.class); - - ExpiringSession expiredSession = sessionEvent.getSession(); - - assertThat(expiredSession).isEqualTo(createdSession); - assertThat(expiredSession.isExpired()).isTrue(); - - this.gemfireSessionRepository.delete(expectedSession.getId()); - - sessionEvent = this.sessionEventListener.getSessionEvent(); - - assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(expiredSession.getId()); - assertThat(this.gemfireSessionRepository.getSession(sessionEvent.getSessionId())).isNull(); - } - - @Test - public void deleteNonExistingSession() { - String expectedSessionId = UUID.randomUUID().toString(); - - assertThat(this.gemfireSessionRepository.getSession(expectedSessionId)).isNull(); - - this.gemfireSessionRepository.delete(expectedSessionId); - - AbstractSessionEvent sessionEvent = this.sessionEventListener.getSessionEvent(); - - assertThat(sessionEvent).isInstanceOf(SessionDeletedEvent.class); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId); - } - - @EnableGemFireHttpSession(regionName = SPRING_SESSION_GEMFIRE_REGION_NAME, maxInactiveIntervalInSeconds = MAX_INACTIVE_INTERVAL_IN_SECONDS, serverRegionShortcut = RegionShortcut.REPLICATE) - static class SpringSessionGemFireConfiguration { - - @Bean - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - - gemfireProperties.setProperty("name", - EnableGemFireHttpSessionEventsIntegrationTests.class.getName()); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-level", GEMFIRE_LOG_LEVEL); - - return gemfireProperties; - } - - @Bean - CacheFactoryBean gemfireCache() { - CacheFactoryBean gemfireCache = new CacheFactoryBean(); - - gemfireCache.setClose(true); - gemfireCache.setProperties(gemfireProperties()); - - return gemfireCache; - } - - @Bean - SessionEventListener sessionEventListener() { - return new SessionEventListener(); - } - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionJavaConfigurationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionJavaConfigurationTests.java deleted file mode 100644 index 41d30252..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionJavaConfigurationTests.java +++ /dev/null @@ -1,148 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http; - -import java.util.Properties; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.query.Index; -import org.apache.geode.cache.query.QueryService; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.annotation.Bean; -import org.springframework.data.gemfire.CacheFactoryBean; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test to test the configuration of Spring Session backed by GemFire - * using Java-based configuration meta-data. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests - * @see org.springframework.test.annotation.DirtiesContext - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner - * @see org.springframework.test.context.web.WebAppConfiguration - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.Region - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -@DirtiesContext -@WebAppConfiguration -public class GemFireHttpSessionJavaConfigurationTests extends AbstractGemFireIntegrationTests { - - @Autowired - private Cache gemfireCache; - - protected Region assertCacheAndRegion(Cache gemfireCache, - String regionName, DataPolicy dataPolicy) { - - assertThat(GemFireUtils.isPeer(gemfireCache)).isTrue(); - - Region region = gemfireCache.getRegion(regionName); - - assertRegion(region, regionName, dataPolicy); - - return region; - } - - @Test - public void gemfireCacheConfigurationIsValid() { - Region example = - assertCacheAndRegion(this.gemfireCache, "JavaExample", DataPolicy.REPLICATE); - - assertEntryIdleTimeout(example, ExpirationAction.INVALIDATE, 900); - } - - @Test - public void verifyGemFireExampleCacheRegionPrincipalNameIndexWasCreatedSuccessfully() { - Region example = - assertCacheAndRegion(this.gemfireCache, "JavaExample", DataPolicy.REPLICATE); - - QueryService queryService = example.getRegionService().getQueryService(); - - assertThat(queryService).isNotNull(); - - Index principalNameIndex = queryService.getIndex(example, "principalNameIndex"); - - assertIndex(principalNameIndex, "principalName", example.getFullPath()); - } - - @Test - public void verifyGemFireExampleCacheRegionSessionAttributesIndexWasNotCreated() { - Region example = - assertCacheAndRegion(this.gemfireCache, "JavaExample", DataPolicy.REPLICATE); - - QueryService queryService = example.getRegionService().getQueryService(); - - assertThat(queryService).isNotNull(); - - Index sessionAttributesIndex = queryService.getIndex(example, "sessionAttributesIndex"); - - assertThat(sessionAttributesIndex).isNull(); - } - - @EnableGemFireHttpSession(indexableSessionAttributes = {}, maxInactiveIntervalInSeconds = 900, - regionName = "JavaExample", serverRegionShortcut = RegionShortcut.REPLICATE) - public static class GemFireConfiguration { - - Properties gemfireProperties() { - Properties gemfireProperties = new Properties(); - gemfireProperties.setProperty("name", applicationName()); - gemfireProperties.setProperty("mcast-port", "0"); - gemfireProperties.setProperty("log-level", logLevel()); - return gemfireProperties; - } - - String applicationName() { - return GemFireHttpSessionJavaConfigurationTests.class.getName(); - } - - String logLevel() { - return "warning"; - } - - @Bean - CacheFactoryBean gemfireCache() { - CacheFactoryBean cacheFactory = new CacheFactoryBean(); - - cacheFactory.setClose(true); - cacheFactory.setProperties(gemfireProperties()); - - return cacheFactory; - } - } -} diff --git a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests.java b/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests.java deleted file mode 100644 index 80f2e782..00000000 --- a/spring-session/src/integration-test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.query.Index; -import org.apache.geode.cache.query.QueryService; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.test.annotation.DirtiesContext; -import org.springframework.test.context.ContextConfiguration; -import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; -import org.springframework.test.context.web.WebAppConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Test suite of test cases testing the configuration of Spring Session backed by GemFire - * using XML configuration meta-data. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests - * @see org.springframework.test.annotation.DirtiesContext - * @see org.springframework.test.context.ContextConfiguration - * @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner - * @see org.springframework.test.context.web.WebAppConfiguration - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.Region - */ -@RunWith(SpringJUnit4ClassRunner.class) -@ContextConfiguration -@DirtiesContext -@WebAppConfiguration -public class GemFireHttpSessionXmlConfigurationTests extends AbstractGemFireIntegrationTests { - - @Autowired - private Cache gemfireCache; - - protected Region assertCacheAndRegion(Cache gemfireCache, - String regionName, DataPolicy dataPolicy) { - - assertThat(GemFireUtils.isPeer(gemfireCache)).isTrue(); - - Region region = gemfireCache.getRegion(regionName); - - assertRegion(region, regionName, dataPolicy); - - return region; - } - - @Test - public void gemfireCacheConfigurationIsValid() { - Region example = - assertCacheAndRegion(this.gemfireCache, "XmlExample", DataPolicy.NORMAL); - - assertEntryIdleTimeout(example, ExpirationAction.INVALIDATE, 3600); - } - - @Test - public void verifyGemFireExampleCacheRegionPrincipalNameIndexWasCreatedSuccessfully() { - Region example = - assertCacheAndRegion(this.gemfireCache, "XmlExample", DataPolicy.NORMAL); - - QueryService queryService = example.getRegionService().getQueryService(); - - assertThat(queryService).isNotNull(); - - Index principalNameIndex = queryService.getIndex(example, "principalNameIndex"); - - assertIndex(principalNameIndex, "principalName", example.getFullPath()); - } - - @Test - public void verifyGemFireExampleCacheRegionSessionAttributesIndexWasCreatedSuccessfully() { - Region example = - assertCacheAndRegion(this.gemfireCache, "XmlExample", DataPolicy.NORMAL); - - QueryService queryService = example.getRegionService().getQueryService(); - - assertThat(queryService).isNotNull(); - - Index sessionAttributesIndex = queryService.getIndex(example, "sessionAttributesIndex"); - - assertIndex(sessionAttributesIndex, "s.attributes['one', 'two', 'three']", - String.format("%1$s s", example.getFullPath())); - } -} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java deleted file mode 100644 index b9296fd0..00000000 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepository.java +++ /dev/null @@ -1,956 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.io.DataInput; -import java.io.DataOutput; -import java.io.IOException; -import java.text.DateFormat; -import java.text.SimpleDateFormat; -import java.util.AbstractMap; -import java.util.AbstractSet; -import java.util.Collections; -import java.util.Date; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Iterator; -import java.util.Map; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.TimeUnit; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.apache.geode.DataSerializable; -import org.apache.geode.DataSerializer; -import org.apache.geode.Delta; -import org.apache.geode.Instantiator; -import org.apache.geode.InvalidDeltaException; -import org.apache.geode.cache.EntryEvent; -import org.apache.geode.cache.Operation; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.util.CacheListenerAdapter; -import org.apache.geode.internal.concurrent.ConcurrentHashSet; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.data.gemfire.GemfireAccessor; -import org.springframework.data.gemfire.GemfireOperations; -import org.springframework.expression.Expression; -import org.springframework.expression.spel.standard.SpelExpressionParser; -import org.springframework.session.ExpiringSession; -import org.springframework.session.FindByIndexNameSessionRepository; -import org.springframework.session.Session; -import org.springframework.session.SessionRepository; -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.session.events.SessionCreatedEvent; -import org.springframework.session.events.SessionDeletedEvent; -import org.springframework.session.events.SessionDestroyedEvent; -import org.springframework.session.events.SessionExpiredEvent; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.util.StringUtils; - -/** - * {@link AbstractGemFireOperationsSessionRepository} is an abstract base class encapsulating functionality - * common to all implementations that support {@link SessionRepository} operations backed by GemFire. - * - * @author John Blum - * @since 1.1.0 - * @see org.apache.geode.DataSerializable - * @see org.apache.geode.DataSerializer - * @see org.apache.geode.Delta - * @see org.apache.geode.Instantiator - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.util.CacheListenerAdapter - * @see org.springframework.beans.factory.InitializingBean - * @see org.springframework.context.ApplicationEventPublisher - * @see org.springframework.context.ApplicationEventPublisherAware - * @see org.springframework.data.gemfire.GemfireOperations - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.Session - * @see org.springframework.session.SessionRepository - * @see org.springframework.session.FindByIndexNameSessionRepository - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession - */ -public abstract class AbstractGemFireOperationsSessionRepository extends CacheListenerAdapter - implements ApplicationEventPublisherAware, FindByIndexNameSessionRepository, InitializingBean { - - private int maxInactiveIntervalInSeconds = GemFireHttpSessionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS; - - private ApplicationEventPublisher applicationEventPublisher = new ApplicationEventPublisher() { - public void publishEvent(ApplicationEvent event) { - } - - public void publishEvent(Object event) { - } - }; - - private final Set cachedSessionIds = new ConcurrentHashSet(); - - private final GemfireOperations template; - - protected final Log logger = newLogger(); - - private String fullyQualifiedRegionName; - - /** - * Constructs an instance of AbstractGemFireOperationsSessionRepository with a - * required GemfireOperations instance used to perform GemFire data access operations - * and interactions supporting the SessionRepository operations. - * - * @param template the GemfireOperations instance used to interact with GemFire. - * @see org.springframework.data.gemfire.GemfireOperations - */ - public AbstractGemFireOperationsSessionRepository(GemfireOperations template) { - Assert.notNull(template, "GemfireOperations must not be null"); - this.template = template; - } - - /** - * Used for testing purposes only to override the Log implementation with a mock. - * - * @return an instance of Log constructed from Apache commons-logging LogFactory. - * @see org.apache.commons.logging.LogFactory#getLog(Class) - */ - Log newLogger() { - return LogFactory.getLog(getClass()); - } - - /** - * Sets the ApplicationEventPublisher used to publish Session events corresponding to - * GemFire cache events. - * - * @param applicationEventPublisher the Spring ApplicationEventPublisher used to - * publish Session-based events. - * @see org.springframework.context.ApplicationEventPublisher - */ - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - Assert.notNull(applicationEventPublisher, "ApplicationEventPublisher must not be null"); - this.applicationEventPublisher = applicationEventPublisher; - } - - /** - * Gets the ApplicationEventPublisher used to publish Session events corresponding to - * GemFire cache events. - * - * @return the Spring ApplicationEventPublisher used to publish Session-based events. - * @see org.springframework.context.ApplicationEventPublisher - */ - protected ApplicationEventPublisher getApplicationEventPublisher() { - return this.applicationEventPublisher; - } - - /** - * Gets the fully-qualified name of the GemFire cache {@link Region} used to store and - * manage Session data. - * - * @return a String indicating the fully qualified name of the GemFire cache - * {@link Region} used to store and manage Session data. - */ - protected String getFullyQualifiedRegionName() { - return this.fullyQualifiedRegionName; - } - - /** - * Sets the maximum interval in seconds in which a Session can remain inactive before - * it is considered expired. - * - * @param maxInactiveIntervalInSeconds an integer value specifying the maximum - * interval in seconds that a Session can remain inactive before it is considered - * expired. - */ - public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { - this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; - } - - /** - * Gets the maximum interval in seconds in which a Session can remain inactive before - * it is considered expired. - * - * @return an integer value specifying the maximum interval in seconds that a Session - * can remain inactive before it is considered expired. - */ - public int getMaxInactiveIntervalInSeconds() { - return this.maxInactiveIntervalInSeconds; - } - - /** - * Gets a reference to the GemfireOperations (template) used to perform data access - * operations and other interactions on the GemFire cache {@link Region} backing this - * SessionRepository. - * - * @return a reference to the GemfireOperations used to interact with GemFire. - * @see org.springframework.data.gemfire.GemfireOperations - */ - public GemfireOperations getTemplate() { - return this.template; - } - - /** - * Callback method during Spring bean initialization that will capture the fully-qualified name - * of the GemFire cache {@link Region} used to manage Session state and register this SessionRepository - * as a GemFire {@link org.apache.geode.cache.CacheListener}. - * - * Additionally, this method registers GemFire {@link Instantiator}s for the {@link GemFireSession} - * and {@link GemFireSessionAttributes} types to optimize GemFire's instantiation logic on deserialization - * using the data serialization framework when accessing the {@link Session}'s state stored in GemFire. - * - * @throws Exception if an error occurs during the initialization process. - */ - public void afterPropertiesSet() throws Exception { - GemfireOperations template = getTemplate(); - - Assert.isInstanceOf(GemfireAccessor.class, template); - - Region region = ((GemfireAccessor) template).getRegion(); - - this.fullyQualifiedRegionName = region.getFullPath(); - - region.getAttributesMutator().addCacheListener(this); - - Instantiator.register(GemFireSessionInstantiator.create()); - Instantiator.register(GemFireSessionAttributesInstantiator.create()); - } - - /* (non-Javadoc) */ - boolean isCreate(EntryEvent event) { - return (isCreate(event.getOperation()) && isNotUpdate(event) && isExpiringSessionOrNull(event.getNewValue())); - } - - /* (non-Javadoc) */ - private boolean isCreate(Operation operation) { - return (operation.isCreate() && !Operation.LOCAL_LOAD_CREATE.equals(operation)); - } - - /** - * Used to determine whether the developer is storing (HTTP) Sessions with other, arbitrary application - * domain objects in the same GemFire cache {@link Region}; crazier things have happened! - * - * @param obj {@link Object} to evaluate. - * @return a boolean value indicating whether the {@link Object} from the entry event is indeed - * a {@link ExpiringSession}. - * @see org.springframework.session.ExpiringSession - */ - private boolean isExpiringSessionOrNull(Object obj) { - return (obj instanceof ExpiringSession || obj == null); - } - - /* (non-Javadoc) */ - private boolean isNotUpdate(EntryEvent event) { - return (isNotProxyRegion() || !this.cachedSessionIds.contains(ObjectUtils.nullSafeHashCode(event.getKey()))); - } - - /* (non-Javadoc) */ - private boolean isNotProxyRegion() { - return !isProxyRegion(); - } - - /* (non-Javadoc) */ - private boolean isProxyRegion() { - return GemFireUtils.isProxy(((GemfireAccessor) getTemplate()).getRegion()); - } - - boolean forget(Object sessionId) { - return this.cachedSessionIds.remove(ObjectUtils.nullSafeHashCode(sessionId)); - } - - boolean remember(Object sessionId) { - return (isProxyRegion() && this.cachedSessionIds.add(ObjectUtils.nullSafeHashCode(sessionId))); - } - - /* (non-Javadoc) */ - ExpiringSession toExpiringSession(Object obj) { - return (obj instanceof ExpiringSession ? (ExpiringSession) obj : null); - } - - /** - * Callback method triggered when an entry is created in the GemFire cache {@link Region}. - * - * @param event {@link EntryEvent} containing the details of the cache {@link Region} operation. - * @see org.apache.geode.cache.EntryEvent - * @see #handleCreated(String, ExpiringSession) - */ - @Override - public void afterCreate(EntryEvent event) { - if (isCreate(event)) { - handleCreated(event.getKey().toString(), toExpiringSession(event.getNewValue())); - } - } - - /** - * Callback method triggered when an entry is destroyed in the GemFire cache - * {@link Region}. - * - * @param event an EntryEvent containing the details of the cache operation. - * @see org.apache.geode.cache.EntryEvent - * @see #handleDestroyed(String, ExpiringSession) - */ - @Override - public void afterDestroy(EntryEvent event) { - handleDestroyed(event.getKey().toString(), toExpiringSession(event.getOldValue())); - } - - /** - * Callback method triggered when an entry is invalidated in the GemFire cache - * {@link Region}. - * - * @param event an EntryEvent containing the details of the cache operation. - * @see org.apache.geode.cache.EntryEvent - * @see #handleExpired(String, ExpiringSession) - */ - @Override - public void afterInvalidate(EntryEvent event) { - handleExpired(event.getKey().toString(), toExpiringSession(event.getOldValue())); - } - - /** - * Deletes the given {@link Session} from GemFire. - * - * @param session {@link Session} to delete. - * @return {@literal null}. - * @see org.springframework.session.Session - * @see #delete(String) - */ - protected ExpiringSession delete(Session session) { - delete(session.getId()); - return null; - } - - /** - * Causes Session created events to be published to the Spring application context. - * - * @param sessionId a String indicating the ID of the Session. - * @param session a reference to the Session triggering the event. - * @see org.springframework.session.events.SessionCreatedEvent - * @see org.springframework.session.ExpiringSession - * @see #publishEvent(ApplicationEvent) - */ - protected void handleCreated(String sessionId, ExpiringSession session) { - remember(sessionId); - - publishEvent(session != null ? new SessionCreatedEvent(this, session) - : new SessionCreatedEvent(this, sessionId)); - } - - /** - * Causes Session deleted events to be published to the Spring application context. - * - * @param sessionId a String indicating the ID of the Session. - * @param session a reference to the Session triggering the event. - * @see org.springframework.session.events.SessionDeletedEvent - * @see org.springframework.session.ExpiringSession - * @see #publishEvent(ApplicationEvent) - */ - protected void handleDeleted(String sessionId, ExpiringSession session) { - forget(sessionId); - - publishEvent(session != null ? new SessionDeletedEvent(this, session) - : new SessionDeletedEvent(this, sessionId)); - } - - /** - * Causes Session destroyed events to be published to the Spring application context. - * - * @param sessionId a String indicating the ID of the Session. - * @param session a reference to the Session triggering the event. - * @see org.springframework.session.events.SessionDestroyedEvent - * @see org.springframework.session.ExpiringSession - * @see #publishEvent(ApplicationEvent) - */ - protected void handleDestroyed(String sessionId, ExpiringSession session) { - forget(sessionId); - - publishEvent(session != null ? new SessionDestroyedEvent(this, session) - : new SessionDestroyedEvent(this, sessionId)); - } - - /** - * Causes Session expired events to be published to the Spring application context. - * - * @param sessionId a String indicating the ID of the Session. - * @param session a reference to the Session triggering the event. - * @see org.springframework.session.events.SessionExpiredEvent - * @see org.springframework.session.ExpiringSession - * @see #publishEvent(ApplicationEvent) - */ - protected void handleExpired(String sessionId, ExpiringSession session) { - forget(sessionId); - - publishEvent(session != null ? new SessionExpiredEvent(this, session) - : new SessionExpiredEvent(this, sessionId)); - } - - /** - * Publishes the specified ApplicationEvent to the Spring application context. - * - * @param event the ApplicationEvent to publish. - * @see org.springframework.context.ApplicationEventPublisher#publishEvent(ApplicationEvent) - * @see org.springframework.context.ApplicationEvent - */ - protected void publishEvent(ApplicationEvent event) { - try { - getApplicationEventPublisher().publishEvent(event); - } - catch (Throwable t) { - this.logger.error(String.format("Error occurred publishing event [%s]", event), t); - } - } - - /** - * Updates the {@link ExpiringSession#setLastAccessedTime(long)} property of the {@link ExpiringSession}. - * - * @param {@link Class} sub-type of the {@link ExpiringSession}. - * @param expiringSession {@link ExpiringSession} to touch. - * @return the {@link ExpiringSession}. - * @see org.springframework.session.ExpiringSession#setLastAccessedTime(long) - */ - protected T touch(T expiringSession) { - expiringSession.setLastAccessedTime(System.currentTimeMillis()); - return expiringSession; - } - - /** - * GemFireSession is a GemFire representation model of a Spring {@link ExpiringSession} - * that stores and manages Session state information in GemFire. This class implements - * GemFire's {@link DataSerializable} interface to better handle replication of Session - * state information across the GemFire cluster. - */ - @SuppressWarnings("serial") - public static class GemFireSession implements Comparable, - DataSerializable, Delta, ExpiringSession { - - protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true; - - protected static final DateFormat TO_STRING_DATE_FORMAT = new SimpleDateFormat("YYYY-MM-dd-HH-mm-ss"); - - protected static final String SPRING_SECURITY_CONTEXT = "SPRING_SECURITY_CONTEXT"; - - private transient boolean delta = false; - - private int maxInactiveIntervalInSeconds; - - private long creationTime; - private long lastAccessedTime; - - private transient final GemFireSessionAttributes sessionAttributes = new GemFireSessionAttributes(this); - - private transient final SpelExpressionParser parser = new SpelExpressionParser(); - - private String id; - - /* (non-Javadoc) */ - protected GemFireSession() { - this(UUID.randomUUID().toString()); - } - - /* (non-Javadoc) */ - protected GemFireSession(String id) { - this.id = validateId(id); - this.creationTime = System.currentTimeMillis(); - this.lastAccessedTime = this.creationTime; - } - - /* (non-Javadoc) */ - protected GemFireSession(ExpiringSession session) { - Assert.notNull(session, "The ExpiringSession to copy cannot be null"); - - this.id = session.getId(); - this.creationTime = session.getCreationTime(); - this.lastAccessedTime = session.getLastAccessedTime(); - this.maxInactiveIntervalInSeconds = session.getMaxInactiveIntervalInSeconds(); - this.sessionAttributes.from(session); - } - - /* (non-Javadoc) */ - public static GemFireSession create(int maxInactiveIntervalInSeconds) { - GemFireSession session = new GemFireSession(); - session.setMaxInactiveIntervalInSeconds(maxInactiveIntervalInSeconds); - return session; - } - - public static GemFireSession copy(ExpiringSession session) { - return new GemFireSession(session); - } - - /* (non-Javadoc) */ - public static GemFireSession from(ExpiringSession session) { - return (session instanceof GemFireSession ? (GemFireSession) session : copy(session)); - } - - /* (non-Javadoc) */ - private String validateId(String id) { - Assert.hasText(id, "ID must be specified"); - return id; - } - - /* (non-Javadoc) */ - protected boolean allowJavaSerialization() { - return DEFAULT_ALLOW_JAVA_SERIALIZATION; - } - - /* (non-Javadoc) */ - public synchronized String getId() { - return this.id; - } - - /* (non-Javadoc) */ - public synchronized long getCreationTime() { - return this.creationTime; - } - - /* (non-Javadoc) */ - public void setAttribute(String attributeName, Object attributeValue) { - this.sessionAttributes.setAttribute(attributeName, attributeValue); - } - - /* (non-Javadoc) */ - public void removeAttribute(String attributeName) { - this.sessionAttributes.removeAttribute(attributeName); - } - - /* (non-Javadoc) */ - public T getAttribute(String attributeName) { - return this.sessionAttributes.getAttribute(attributeName); - } - - /* (non-Javadoc) */ - public Set getAttributeNames() { - return this.sessionAttributes.getAttributeNames(); - } - - /* (non-Javadoc) */ - public GemFireSessionAttributes getAttributes() { - return this.sessionAttributes; - } - - /* (non-Javadoc) */ - public synchronized boolean isExpired() { - long lastAccessedTime = getLastAccessedTime(); - long maxInactiveIntervalInSeconds = getMaxInactiveIntervalInSeconds(); - - return (maxInactiveIntervalInSeconds >= 0 - && (idleTimeout(maxInactiveIntervalInSeconds) >= lastAccessedTime)); - } - - /* (non-Javadoc) */ - private long idleTimeout(long maxInactiveIntervalInSeconds) { - return (System.currentTimeMillis() - TimeUnit.SECONDS.toMillis(maxInactiveIntervalInSeconds)); - } - - /* (non-Javadoc) */ - public synchronized void setLastAccessedTime(long lastAccessedTime) { - this.delta |= (this.lastAccessedTime != lastAccessedTime); - this.lastAccessedTime = lastAccessedTime; - } - - /* (non-Javadoc) */ - public synchronized long getLastAccessedTime() { - return this.lastAccessedTime; - } - - /* (non-Javadoc) */ - public synchronized void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { - this.delta |= (this.maxInactiveIntervalInSeconds != maxInactiveIntervalInSeconds); - this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; - } - - /* (non-Javadoc) */ - public synchronized int getMaxInactiveIntervalInSeconds() { - return this.maxInactiveIntervalInSeconds; - } - - /* (non-Javadoc) */ - public synchronized void setPrincipalName(String principalName) { - setAttribute(PRINCIPAL_NAME_INDEX_NAME, principalName); - } - - /* (non-Javadoc) */ - public synchronized String getPrincipalName() { - String principalName = getAttribute(PRINCIPAL_NAME_INDEX_NAME); - - if (principalName == null) { - Object authentication = getAttribute(SPRING_SECURITY_CONTEXT); - - if (authentication != null) { - Expression expression = this.parser.parseExpression("authentication?.name"); - principalName = expression.getValue(authentication, String.class); - } - } - - return principalName; - } - - /* (non-Javadoc) */ - public synchronized void toData(DataOutput out) throws IOException { - out.writeUTF(getId()); - out.writeLong(getCreationTime()); - out.writeLong(getLastAccessedTime()); - out.writeInt(getMaxInactiveIntervalInSeconds()); - - String principalName = getPrincipalName(); - - int length = (StringUtils.hasText(principalName) ? principalName.length() : 0); - - out.writeInt(length); - - if (length > 0) { - out.writeUTF(principalName); - } - - writeObject(this.sessionAttributes, out); - - this.delta = false; - } - - /* (non-Javadoc) */ - void writeObject(Object obj, DataOutput out) throws IOException { - DataSerializer.writeObject(obj, out, allowJavaSerialization()); - } - - /* (non-Javadoc) */ - public synchronized void fromData(DataInput in) throws ClassNotFoundException, IOException { - this.id = in.readUTF(); - this.creationTime = in.readLong(); - setLastAccessedTime(in.readLong()); - setMaxInactiveIntervalInSeconds(in.readInt()); - - int principalNameLength = in.readInt(); - - if (principalNameLength > 0) { - setPrincipalName(in.readUTF()); - } - - this.sessionAttributes.from(this.readObject(in)); - - this.delta = false; - } - - /* (non-Javadoc) */ - T readObject(DataInput in) throws ClassNotFoundException, IOException { - return DataSerializer.readObject(in); - } - - /* (non-Javadoc) */ - public synchronized boolean hasDelta() { - return (this.delta || this.sessionAttributes.hasDelta()); - } - - /* (non-Javadoc) */ - public synchronized void toDelta(DataOutput out) throws IOException { - out.writeLong(getLastAccessedTime()); - out.writeInt(getMaxInactiveIntervalInSeconds()); - this.sessionAttributes.toDelta(out); - this.delta = false; - } - - /* (non-Javadoc) */ - public synchronized void fromDelta(DataInput in) throws IOException { - setLastAccessedTime(in.readLong()); - setMaxInactiveIntervalInSeconds(in.readInt()); - this.sessionAttributes.fromDelta(in); - this.delta = false; - } - - /* (non-Javadoc) */ - @SuppressWarnings("all") - public int compareTo(ExpiringSession session) { - return (Long.valueOf(getCreationTime()).compareTo(session.getCreationTime())); - } - - /* (non-Javadoc) */ - @Override - public boolean equals(final Object obj) { - if (obj == this) { - return true; - } - - if (!(obj instanceof Session)) { - return false; - } - - Session that = (Session) obj; - - return this.getId().equals(that.getId()); - } - - /* (non-Javadoc) */ - @Override - public int hashCode() { - int hashValue = 17; - hashValue = 37 * hashValue + getId().hashCode(); - return hashValue; - } - - /* (non-Javadoc) */ - @Override - public synchronized String toString() { - return String.format("{ @type = %1$s, id = %2$s, creationTime = %3$s, lastAccessedTime = %4$s" - + ", maxInactiveIntervalInSeconds = %5$s, principalName = %6$s }", - getClass().getName(), getId(), toString(getCreationTime()), toString(getLastAccessedTime()), - getMaxInactiveIntervalInSeconds(), getPrincipalName()); - } - - /* (non-Javadoc) */ - private String toString(long timestamp) { - return TO_STRING_DATE_FORMAT.format(new Date(timestamp)); - } - } - - /** - * GemFireSessionInstantiator is a GemFire {@link Instantiator} use to instantiate instances - * of the {@link GemFireSession} object used in GemFire's data serialization framework when - * persisting Session state in GemFire. - */ - public static class GemFireSessionInstantiator extends Instantiator { - - public static GemFireSessionInstantiator create() { - return new GemFireSessionInstantiator(GemFireSession.class, 800813552); - } - - public GemFireSessionInstantiator(Class type, int id) { - super(type, id); - } - - @Override - public DataSerializable newInstance() { - return new GemFireSession(); - } - } - - /** - * The GemFireSessionAttributes class is a container for Session attributes implementing - * both the {@link DataSerializable} and {@link Delta} GemFire interfaces for efficient - * storage and distribution (replication) in GemFire. Additionally, GemFireSessionAttributes - * extends {@link AbstractMap} providing {@link Map}-like behavior since attributes of a Session - * are effectively a name to value mapping. - * - * @see java.util.AbstractMap - * @see org.apache.geode.DataSerializable - * @see org.apache.geode.DataSerializer - * @see org.apache.geode.Delta - */ - @SuppressWarnings("serial") - public static class GemFireSessionAttributes extends AbstractMap - implements DataSerializable, Delta { - - protected static final boolean DEFAULT_ALLOW_JAVA_SERIALIZATION = true; - - private transient final Map sessionAttributes = new HashMap(); - private transient final Map sessionAttributeDeltas = new HashMap(); - - private transient final Object lock; - - /* (non-Javadoc) */ - protected GemFireSessionAttributes() { - this.lock = this; - } - - /* (non-Javadoc) */ - protected GemFireSessionAttributes(Object lock) { - this.lock = (lock != null ? lock : this); - } - - /* (non-Javadoc) */ - public void setAttribute(String attributeName, Object attributeValue) { - synchronized (this.lock) { - if (attributeValue != null) { - if (!attributeValue.equals(this.sessionAttributes.put(attributeName, attributeValue))) { - this.sessionAttributeDeltas.put(attributeName, attributeValue); - } - } - else { - removeAttribute(attributeName); - } - } - } - - /* (non-Javadoc) */ - public void removeAttribute(String attributeName) { - synchronized (this.lock) { - if (this.sessionAttributes.remove(attributeName) != null) { - this.sessionAttributeDeltas.put(attributeName, null); - } - } - } - - /* (non-Javadoc) */ - @SuppressWarnings("unchecked") - public T getAttribute(String attributeName) { - synchronized (this.lock) { - return (T) this.sessionAttributes.get(attributeName); - } - } - - /* (non-Javadoc) */ - public Set getAttributeNames() { - synchronized (this.lock) { - return Collections.unmodifiableSet(new HashSet(this.sessionAttributes.keySet())); - } - } - - /* (non-Javadoc) */ - protected boolean allowJavaSerialization() { - return DEFAULT_ALLOW_JAVA_SERIALIZATION; - } - - /* (non-Javadoc); NOTE: entrySet implementation is not Thread-safe. */ - @Override - @SuppressWarnings("all") - public Set> entrySet() { - return new AbstractSet>() { - @Override - public Iterator> iterator() { - return Collections.unmodifiableMap(GemFireSessionAttributes.this.sessionAttributes) - .entrySet().iterator(); - } - - @Override - public int size() { - return GemFireSessionAttributes.this.sessionAttributes.size(); - } - }; - } - - /* (non-Javadoc) */ - public void from(Session session) { - synchronized (this.lock) { - for (String attributeName : session.getAttributeNames()) { - setAttribute(attributeName, session.getAttribute(attributeName)); - } - } - } - - /* (non-Javadoc) */ - public void from(GemFireSessionAttributes sessionAttributes) { - synchronized (this.lock) { - for (String attributeName : sessionAttributes.getAttributeNames()) { - setAttribute(attributeName, sessionAttributes.getAttribute(attributeName)); - } - } - } - - /* (non-Javadoc) */ - public void toData(DataOutput out) throws IOException { - synchronized (this.lock) { - Set attributeNames = getAttributeNames(); - - out.writeInt(attributeNames.size()); - - for (String attributeName : attributeNames) { - out.writeUTF(attributeName); - writeObject(getAttribute(attributeName), out); - } - } - } - - /* (non-Javadoc) */ - void writeObject(Object obj, DataOutput out) throws IOException { - DataSerializer.writeObject(obj, out, allowJavaSerialization()); - } - - /* (non-Javadoc) */ - public void fromData(DataInput in) throws IOException, ClassNotFoundException { - synchronized (this.lock) { - for (int count = in.readInt(); count > 0; count--) { - setAttribute(in.readUTF(), readObject(in)); - } - - this.sessionAttributeDeltas.clear(); - } - } - - /* (non-Javadoc) */ - T readObject(DataInput in) throws ClassNotFoundException, IOException { - return DataSerializer.readObject(in); - } - - /* (non-Javadoc) */ - public boolean hasDelta() { - synchronized (this.lock) { - return !this.sessionAttributeDeltas.isEmpty(); - } - } - - /* (non-Javadoc) */ - public void toDelta(DataOutput out) throws IOException { - synchronized (this.lock) { - out.writeInt(this.sessionAttributeDeltas.size()); - - for (Map.Entry entry : this.sessionAttributeDeltas.entrySet()) { - out.writeUTF(entry.getKey()); - writeObject(entry.getValue(), out); - } - - this.sessionAttributeDeltas.clear(); - } - } - - /* (non-Javadoc) */ - public void fromDelta(DataInput in) throws InvalidDeltaException, IOException { - synchronized (this.lock) { - try { - int count = in.readInt(); - - Map deltas = new HashMap(count); - - while (count-- > 0) { - deltas.put(in.readUTF(), readObject(in)); - } - - for (Map.Entry entry : deltas.entrySet()) { - setAttribute(entry.getKey(), entry.getValue()); - this.sessionAttributeDeltas.remove(entry.getKey()); - } - } - catch (ClassNotFoundException e) { - throw new InvalidDeltaException("class type in data not found", e); - } - } - } - - @Override - public String toString() { - return this.sessionAttributes.toString(); - } - } - - /** - * GemFireSessionAttributesInstantiator is a GemFire {@link Instantiator} use to instantiate instances - * of the {@link GemFireSessionAttributes} object used in GemFire's data serialization framework when - * persisting Session attributes state in GemFire. - */ - public static class GemFireSessionAttributesInstantiator extends Instantiator { - - public static GemFireSessionAttributesInstantiator create() { - return new GemFireSessionAttributesInstantiator(GemFireSessionAttributes.class, 800828008); - } - - public GemFireSessionAttributesInstantiator(Class type, int id) { - super(type, id); - } - - @Override - public DataSerializable newInstance() { - return new GemFireSessionAttributes(); - } - } -} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java deleted file mode 100644 index 7fedc180..00000000 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepository.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.geode.cache.query.SelectResults; - -import org.springframework.data.gemfire.GemfireOperations; -import org.springframework.session.ExpiringSession; -import org.springframework.session.SessionRepository; - -/** - * The {@link GemFireOperationsSessionRepository} class is a Spring {@link SessionRepository} implementation - * that interfaces with and uses GemFire to back and store Spring Sessions. - * - * @author John Blum - * @since 1.1.0 - * @see org.springframework.data.gemfire.GemfireOperations - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository - */ -public class GemFireOperationsSessionRepository extends AbstractGemFireOperationsSessionRepository { - - // GemFire OQL query used to lookup Sessions by arbitrary attributes. - protected static final String FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY = "SELECT s FROM %1$s s WHERE s.attributes['%2$s'] = $1"; - - // GemFire OQL query used to look up Sessions by principal name. - protected static final String FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY = "SELECT s FROM %1$s s WHERE s.principalName = $1"; - - /** - * Constructs an instance of GemFireOperationsSessionRepository initialized with the - * required GemfireOperations object used to perform data access operations to manage - * Session state. - * - * @param template the GemfireOperations object used to access and manage Session - * state in GemFire. - * @see org.springframework.data.gemfire.GemfireOperations - */ - public GemFireOperationsSessionRepository(GemfireOperations template) { - super(template); - } - - /** - * Looks up all available Sessions with the particular attribute indexed by name - * having the given value. - * - * @param indexName name of the indexed Session attribute. (e.g. - * {@link org.springframework.session.FindByIndexNameSessionRepository#PRINCIPAL_NAME_INDEX_NAME} - * ). - * @param indexValue value of the indexed Session attribute to search on (e.g. - * username). - * @return a mapping of Session ID to Session instances. - * @see org.springframework.session.ExpiringSession - * @see java.util.Map - * @see #prepareQuery(String) - */ - public Map findByIndexNameAndIndexValue(String indexName, String indexValue) { - SelectResults results = getTemplate().find(prepareQuery(indexName), indexValue); - - Map sessions = new HashMap(results.size()); - - for (ExpiringSession session : results.asList()) { - sessions.put(session.getId(), session); - } - - return sessions; - } - - /** - * Prepares the appropriate GemFire OQL query based on the indexed Session attribute - * name. - * - * @param indexName a String indicating the name of the indexed Session attribute. - * @return an appropriate GemFire OQL statement for querying on a particular indexed - * Session attribute. - */ - protected String prepareQuery(String indexName) { - return (PRINCIPAL_NAME_INDEX_NAME.equals(indexName) - ? String.format(FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, getFullyQualifiedRegionName()) - : String.format(FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY, getFullyQualifiedRegionName(), indexName)); - } - - /** - * Constructs a new {@link ExpiringSession} instance backed by GemFire. - * - * @return an instance of {@link ExpiringSession} backed by GemFire. - * @see AbstractGemFireOperationsSessionRepository.GemFireSession#create(int) - * @see org.springframework.session.ExpiringSession - * @see #getMaxInactiveIntervalInSeconds() - */ - public ExpiringSession createSession() { - return GemFireSession.create(getMaxInactiveIntervalInSeconds()); - } - - /** - * Gets a copy of an existing, non-expired {@link ExpiringSession} by ID. If the - * Session is expired, then it is deleted. - * - * @param sessionId a String indicating the ID of the Session to get. - * @return an existing {@link ExpiringSession} by ID or null if not Session exists. - * @see AbstractGemFireOperationsSessionRepository.GemFireSession#from(ExpiringSession) - * @see org.springframework.session.ExpiringSession - * @see #delete(String) - */ - public ExpiringSession getSession(String sessionId) { - ExpiringSession storedSession = getTemplate().get(sessionId); - - if (storedSession != null) { - storedSession = storedSession.isExpired() - ? delete(storedSession) - : touch(GemFireSession.from(storedSession)); - } - - return storedSession; - } - - /** - * Saves the specified {@link ExpiringSession} to GemFire. - * - * @param session the {@link ExpiringSession} to save. - * @see org.springframework.data.gemfire.GemfireOperations#put(Object, Object) - * @see org.springframework.session.ExpiringSession - */ - public void save(ExpiringSession session) { - getTemplate().put(session.getId(), GemFireSession.from(session)); - } - - /** - * Deletes (removes) any existing {@link ExpiringSession} from GemFire. This operation - * also results in a SessionDeletedEvent. - * - * @param sessionId a String indicating the ID of the Session to remove from GemFire. - * @see org.springframework.data.gemfire.GemfireOperations#remove(Object) - * @see #handleDeleted(String, ExpiringSession) - */ - public void delete(String sessionId) { - handleDeleted(sessionId, getTemplate().remove(sessionId)); - } -} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java deleted file mode 100644 index bdbb8e64..00000000 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.client.ClientRegionShortcut; - -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * Add this annotation to a Spring {@code @Configuration} class to expose the SessionRepositoryFilter - * as a bean named "springSessionRepositoryFilter" and backed by Pivotal GemFire or Apache Geode. - * - * In order to leverage the annotation, a single Pivotal GemFire/Apache Geode - * {@link org.apache.geode.cache.Cache} - * or {@link org.apache.geode.cache.client.ClientCache} instance must be provided. - * - * For example: - * - *
- * 
- * {@literal @Configuration}
- * {@literal @EnableGemFireHttpSession}
- * public class GemFirePeerCacheHttpSessionConfiguration {
- *
- *     {@literal @Bean}
- *     public Properties gemfireProperties() {
- *       Properties gemfireProperties = new Properties();
- *       gemfireProperties.setProperty("name", "ExamplePeer");
- *       gemfireProperties.setProperty("mcast-port", "0");
- *       gemfireProperties.setProperty("log-level", "warning");
- *       return gemfireProperties;
- *     }
- *
- *     {@literal @Bean}
- *     public CacheFactoryBean gemfireCache() throws Exception {
- *       CacheFactoryBean cache  = new CacheFactoryBean();
- *       cache.setProperties(gemfireProperties());
- *       return cache;
- *     }
- * }
- *  
- * - * Alternatively, Spring Session can be configured to use Pivotal GemFire (Apache Geode) as a client - * using a dedicated GemFire Server cluster and a {@link org.apache.geode.cache.client.ClientCache}. - * - * For example: - * - * - * {@literal @Configuration} - * {@literal @EnableGemFireHttpSession} - * public class GemFireClientCacheHttpSessionConfiguration { - * - * {@literal @Bean} - * public Properties gemfireProperties() { - * Properties gemfireProperties = new Properties(); - * gemfireProperties.setProperty("name", "ExampleClient"); - * gemfireProperties.setProperty("log-level", "warning"); - * return gemfireProperties; - * } - * - * {@literal @Bean} - * public ClientCacheFactoryBean gemfireCache() throws Exception { - * ClientCacheFactoryBean clientCache = new ClientCacheFactoryBean(); - * clientCache.setClose(true) - * clientCache.setProperties(gemfireProperties()); - * return clientCache; - * } - * - * {@literal @Bean} - * public PoolFactoryBean gemfirePool() { - * PoolFactoryBean pool = new PoolFactoryBean(); - * pool.addServer(new ConnectionEndpoint("serverHost", 40404); - * return pool; - * } - * } - * - * - * More advanced configurations can extend {@link GemFireHttpSessionConfiguration} instead. - * - * @author John Blum - * @see org.springframework.session.config.annotation.web.http.EnableSpringHttpSession - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @since 1.1.0 - */ -@Documented -@Retention(RetentionPolicy.RUNTIME) -@Target(ElementType.TYPE) -@Configuration -@Import(GemFireHttpSessionConfiguration.class) -public @interface EnableGemFireHttpSession { - - /** - * Defines the GemFire ClientCache Region DataPolicy. - * - * @return a ClientRegionShortcut used to specify and configure the ClientCache Region - * DataPolicy. - * @see org.apache.geode.cache.client.ClientRegionShortcut - */ - ClientRegionShortcut clientRegionShortcut() default ClientRegionShortcut.PROXY; - - /** - * Identifies the Session attributes by name that should be indexed for query - * operations. For instance, find all Sessions in GemFire having attribute A defined - * with value X. - * - * @return an array of Strings identifying the names of Session attributes to index. - */ - String[] indexableSessionAttributes() default {}; - - /** - * Defines the maximum interval in seconds that a Session can remain inactive before - * it is considered expired. Defaults to 1800 seconds, or 30 minutes. - * - * @return an integer value defining the maximum inactive interval in seconds for - * declaring a Session expired. - */ - int maxInactiveIntervalInSeconds() default 1800; - - /** - * Specifies the name of the specific GemFire {@link org.apache.geode.cache.client.Pool} used - * by the Spring Session Data GemFire client Region ('ClusteredSpringSessions') when performing - * cache operations. This is attribute is only used in the client/server topology. - * - * @return the name of the GemFire {@link org.apache.geode.cache.client.Pool} to be used - * by the client Region used to manage (HTTP) Sessions. - * @see org.springframework.data.gemfire.config.xml.GemfireConstants#DEFAULT_GEMFIRE_POOL_NAME - */ - String poolName() default GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME; - - /** - * Defines the name of the GemFire (Client)Cache Region used to store Sessions. - * - * @return a String specifying the name of the GemFire (Client)Cache Region used to - * store Sessions. - * @see org.apache.geode.cache.Region#getName() - */ - String regionName() default "ClusteredSpringSessions"; - - /** - * Defines the GemFire, Peer Cache Region DataPolicy. - * - * @return a RegionShortcut used to specify and configure the Peer Cache Region - * DataPolicy. - * @see org.apache.geode.cache.RegionShortcut - */ - RegionShortcut serverRegionShortcut() default RegionShortcut.PARTITION; - -} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java deleted file mode 100644 index 8635aa81..00000000 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfiguration.java +++ /dev/null @@ -1,487 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http; - -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.ExpirationAttributes; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.apache.geode.cache.client.Pool; - -import org.springframework.beans.factory.BeanClassLoaderAware; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.DependsOn; -import org.springframework.context.annotation.ImportAware; -import org.springframework.core.annotation.AnnotationAttributes; -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.data.gemfire.GemfireOperations; -import org.springframework.data.gemfire.GemfireTemplate; -import org.springframework.data.gemfire.IndexFactoryBean; -import org.springframework.data.gemfire.IndexType; -import org.springframework.data.gemfire.RegionAttributesFactoryBean; -import org.springframework.data.gemfire.config.xml.GemfireConstants; -import org.springframework.session.ExpiringSession; -import org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration; -import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository.GemFireSession; -import org.springframework.session.data.gemfire.GemFireOperationsSessionRepository; -import org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean; -import org.springframework.session.data.gemfire.config.annotation.web.http.support.SessionAttributesIndexFactoryBean; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.util.StringUtils; - -/** - * The {@link GemFireHttpSessionConfiguration} class is a Spring {@link Configuration @Configuration} class - * used to configure and initialize Pivotal GemFire (or Apache Geode) as a clustered, replicated - * {@link javax.servlet.http.HttpSession} provider implementation in Spring {@link ExpiringSession}. - * - * @author John Blum - * @see org.apache.geode.cache.GemFireCache - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.client.Pool - * @see org.springframework.beans.factory.BeanClassLoaderAware - * @see org.springframework.context.annotation.Bean - * @see org.springframework.context.annotation.Configuration - * @see org.springframework.context.annotation.ImportAware - * @see org.springframework.data.gemfire.GemfireOperations - * @see org.springframework.data.gemfire.GemfireTemplate - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.config.annotation.web.http.SpringHttpSessionConfiguration - * @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository - * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession - * @since 1.1.0 - */ -@Configuration -public class GemFireHttpSessionConfiguration extends SpringHttpSessionConfiguration - implements BeanClassLoaderAware, ImportAware { - - /** - * The default maximum interval in seconds in which a Session can remain inactive - * before it is considered expired. - */ - public static final int DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS = (int) TimeUnit.MINUTES.toSeconds(30); - - protected static final Class SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT = Object.class; - protected static final Class SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT = GemFireSession.class; - - /** - * The default {@link ClientRegionShortcut} used to configure the GemFire ClientCache - * Region that will store Spring Sessions. - */ - public static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = ClientRegionShortcut.PROXY; - - /** - * The default {@link RegionShortcut} used to configure the GemFire Cache Region that - * will store Spring Sessions. - */ - public static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = RegionShortcut.PARTITION; - - /** - * Name of the GemFire {@link Pool} used by the client Region for managing Session state information. - */ - public static final String DEFAULT_GEMFIRE_POOL_NAME = GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME; - - /** - * The default name of the Gemfire (Client)Cache Region used to store Sessions. - */ - public static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME = "ClusteredSpringSessions"; - - /** - * The default names of all Session attributes that should be indexed by GemFire. - */ - public static final String[] DEFAULT_INDEXABLE_SESSION_ATTRIBUTES = {}; - - private int maxInactiveIntervalInSeconds = DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS; - - private ClassLoader beanClassLoader; - - private ClientRegionShortcut clientRegionShortcut = DEFAULT_CLIENT_REGION_SHORTCUT; - - private RegionShortcut serverRegionShortcut = DEFAULT_SERVER_REGION_SHORTCUT; - - private String poolName = DEFAULT_GEMFIRE_POOL_NAME; - - private String springSessionGemFireRegionName = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME; - - private String[] indexableSessionAttributes = DEFAULT_INDEXABLE_SESSION_ATTRIBUTES; - - /** - * Sets a reference to the {@link ClassLoader} used to load bean definition class - * types in a Spring context. - * - * @param beanClassLoader the ClassLoader used by the Spring container to load bean - * class types. - * @see org.springframework.beans.factory.BeanClassLoaderAware#setBeanClassLoader(ClassLoader) - * @see java.lang.ClassLoader - */ - public void setBeanClassLoader(ClassLoader beanClassLoader) { - this.beanClassLoader = beanClassLoader; - } - - /** - * Gets a reference to the {@link ClassLoader} used to load bean definition class - * types in a Spring context. - * - * @return the ClassLoader used by the Spring container to load bean class types. - * @see java.lang.ClassLoader - */ - protected ClassLoader getBeanClassLoader() { - return this.beanClassLoader; - } - - /** - * Sets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache - * Region that will store Spring Sessions. - * - * @param shortcut the ClientRegionShortcut used to configure the GemFire ClientCache - * Region. - * @see org.apache.geode.cache.client.ClientRegionShortcut - */ - public void setClientRegionShortcut(ClientRegionShortcut shortcut) { - this.clientRegionShortcut = shortcut; - } - - /** - * Gets the {@link ClientRegionShortcut} used to configure the GemFire ClientCache - * Region that will store Spring Sessions. Defaults to - * {@link ClientRegionShortcut#PROXY}. - * - * @return the ClientRegionShortcut used to configure the GemFire ClientCache Region. - * @see org.apache.geode.cache.client.ClientRegionShortcut - * @see EnableGemFireHttpSession#clientRegionShortcut() - */ - protected ClientRegionShortcut getClientRegionShortcut() { - return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT); - } - - /** - * Sets the names of all Session attributes that should be indexed by GemFire. - * - * @param indexableSessionAttributes an array of Strings indicating the names of all - * Session attributes for which an Index will be created by GemFire. - */ - public void setIndexableSessionAttributes(String[] indexableSessionAttributes) { - this.indexableSessionAttributes = indexableSessionAttributes; - } - - /** - * Get the names of all Session attributes that should be indexed by GemFire. - * - * @return an array of Strings indicating the names of all Session attributes for - * which an Index will be created by GemFire. Defaults to an empty String array if - * unspecified. - * @see EnableGemFireHttpSession#indexableSessionAttributes() - */ - protected String[] getIndexableSessionAttributes() { - return (this.indexableSessionAttributes != null ? this.indexableSessionAttributes - : DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); - } - - /** - * Sets the maximum interval in seconds in which a Session can remain inactive before - * it is considered expired. - * - * @param maxInactiveIntervalInSeconds an integer value specifying the maximum - * interval in seconds that a Session can remain inactive before it is considered - * expired. - */ - public void setMaxInactiveIntervalInSeconds(int maxInactiveIntervalInSeconds) { - this.maxInactiveIntervalInSeconds = maxInactiveIntervalInSeconds; - } - - /** - * Gets the maximum interval in seconds in which a Session can remain inactive before - * it is considered expired. - * - * @return an integer value specifying the maximum interval in seconds that a Session - * can remain inactive before it is considered expired. - * @see EnableGemFireHttpSession#maxInactiveIntervalInSeconds() - */ - protected int getMaxInactiveIntervalInSeconds() { - return this.maxInactiveIntervalInSeconds; - } - - /** - * Sets the name of the GemFire {@link Pool} used by the client Region for managing Sessions - * during cache operations involving the server. - * - * @param poolName the name of a GemFire {@link Pool}. - * @see Pool#getName() - */ - public void setPoolName(String poolName) { - this.poolName = poolName; - } - - /** - * Returns the name of the GemFire {@link Pool} used by the client Region for managing Sessions - * during cache operations involving the server. - * - * @return the name of a GemFire {@link Pool}. - * @see Pool#getName() - */ - protected String getPoolName() { - return (StringUtils.hasText(this.poolName) ? this.poolName : DEFAULT_GEMFIRE_POOL_NAME); - } - - /** - * Sets the {@link RegionShortcut} used to configure the GemFire Cache Region that - * will store Spring Sessions. - * - * @param shortcut the RegionShortcut used to configure the GemFire Cache Region. - * @see org.apache.geode.cache.RegionShortcut - */ - public void setServerRegionShortcut(RegionShortcut shortcut) { - this.serverRegionShortcut = shortcut; - } - - /** - * Gets the {@link RegionShortcut} used to configure the GemFire Cache Region that - * will store Spring Sessions. Defaults to {@link RegionShortcut#PARTITION}. - * - * @return the RegionShortcut used to configure the GemFire Cache Region. - * @see org.apache.geode.cache.RegionShortcut - * @see EnableGemFireHttpSession#serverRegionShortcut() - */ - protected RegionShortcut getServerRegionShortcut() { - return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT); - } - - /** - * Sets the name of the Gemfire (Client)Cache Region used to store Sessions. - * - * @param springSessionGemFireRegionName a String specifying the name of the GemFire - * (Client)Cache Region used to store the Session. - */ - public void setSpringSessionGemFireRegionName(String springSessionGemFireRegionName) { - this.springSessionGemFireRegionName = springSessionGemFireRegionName; - } - - /** - * Gets the name of the Gemfire (Client)Cache Region used to store Sessions. Defaults - * to 'ClusteredSpringSessions'. - * - * @return a String specifying the name of the GemFire (Client)Cache Region used to - * store the Session. - * @see org.apache.geode.cache.Region#getName() - * @see EnableGemFireHttpSession#regionName() - */ - protected String getSpringSessionGemFireRegionName() { - return (StringUtils.hasText(this.springSessionGemFireRegionName) ? this.springSessionGemFireRegionName - : DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - } - - /** - * Callback with the {@link AnnotationMetadata} of the class containing @Import - * annotation that imported this @Configuration class. - * - * @param importMetadata the AnnotationMetadata of the class importing - * this @Configuration class. - */ - public void setImportMetadata(AnnotationMetadata importMetadata) { - AnnotationAttributes enableGemFireHttpSessionAnnotationAttributes = - AnnotationAttributes.fromMap(importMetadata.getAnnotationAttributes( - EnableGemFireHttpSession.class.getName())); - - setClientRegionShortcut(ClientRegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes - .getEnum("clientRegionShortcut"))); - - setIndexableSessionAttributes(enableGemFireHttpSessionAnnotationAttributes - .getStringArray("indexableSessionAttributes")); - - setMaxInactiveIntervalInSeconds(enableGemFireHttpSessionAnnotationAttributes - .getNumber("maxInactiveIntervalInSeconds").intValue()); - - setPoolName(enableGemFireHttpSessionAnnotationAttributes.getString("poolName")); - - setServerRegionShortcut(RegionShortcut.class.cast(enableGemFireHttpSessionAnnotationAttributes - .getEnum("serverRegionShortcut"))); - - setSpringSessionGemFireRegionName(enableGemFireHttpSessionAnnotationAttributes - .getString("regionName")); - } - - /** - * Defines the Spring SessionRepository bean used to interact with GemFire as a Spring - * Session provider. - * - * @param gemfireOperations an instance of {@link GemfireOperations} used to manage - * Spring Sessions in GemFire. - * @return a GemFireOperationsSessionRepository for managing (clustering/replicating) - * Sessions using GemFire. - */ - @Bean - public GemFireOperationsSessionRepository sessionRepository( - @Qualifier("sessionRegionTemplate") GemfireOperations gemfireOperations) { - - GemFireOperationsSessionRepository sessionRepository = - new GemFireOperationsSessionRepository(gemfireOperations); - - sessionRepository.setMaxInactiveIntervalInSeconds(getMaxInactiveIntervalInSeconds()); - - return sessionRepository; - } - - /** - * Defines a Spring GemfireTemplate bean used to interact with GemFire's (Client)Cache - * {@link Region} storing Sessions. - * - * @param gemFireCache reference to the single GemFire cache instance used by the - * {@link GemfireTemplate} to perform GemFire cache data access operations. - * @return a {@link GemfireTemplate} used to interact with GemFire's (Client)Cache - * {@link Region} storing Sessions. - * @see org.springframework.data.gemfire.GemfireTemplate - * @see org.apache.geode.cache.Region - */ - @Bean - @DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME) - public GemfireTemplate sessionRegionTemplate(GemFireCache gemFireCache) { - return new GemfireTemplate(gemFireCache.getRegion(getSpringSessionGemFireRegionName())); - } - - /** - * Defines a Spring GemFire {@link org.apache.geode.cache.Cache} {@link Region} - * bean used to store and manage Sessions using either a client-server or peer-to-peer - * (p2p) topology. - * - * @param gemfireCache a reference to the GemFire - * {@link org.apache.geode.cache.Cache}. - * @param sessionRegionAttributes the GemFire {@link RegionAttributes} used to - * configure the {@link Region}. - * @return a {@link GemFireCacheTypeAwareRegionFactoryBean} used to configure and - * initialize a GemFire Cache {@link Region} for storing and managing Sessions. - * @see #getClientRegionShortcut() - * @see #getSpringSessionGemFireRegionName() - * @see #getServerRegionShortcut() - */ - @Bean(name = DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME) - public GemFireCacheTypeAwareRegionFactoryBean sessionRegion(GemFireCache gemfireCache, - @Qualifier("sessionRegionAttributes") RegionAttributes sessionRegionAttributes) { - - GemFireCacheTypeAwareRegionFactoryBean sessionRegion = - new GemFireCacheTypeAwareRegionFactoryBean(); - - sessionRegion.setClientRegionShortcut(getClientRegionShortcut()); - sessionRegion.setGemfireCache(gemfireCache); - sessionRegion.setPoolName(getPoolName()); - sessionRegion.setRegionAttributes(sessionRegionAttributes); - sessionRegion.setRegionName(getSpringSessionGemFireRegionName()); - sessionRegion.setServerRegionShortcut(getServerRegionShortcut()); - - return sessionRegion; - } - - /** - * Defines a Spring GemFire {@link RegionAttributes} bean used to configure and - * initialize the GemFire cache {@link Region} storing Sessions. Expiration is also - * configured for the {@link Region} on the basis that the GemFire cache - * {@link Region} is a not a proxy, on either the client or server. - * - * @param gemfireCache a reference to the GemFire cache. - * @return an instance of {@link RegionAttributes} used to configure and initialize - * the GemFire cache {@link Region} for storing and managing Sessions. - * @see org.springframework.data.gemfire.RegionAttributesFactoryBean - * @see org.apache.geode.cache.GemFireCache - * @see org.apache.geode.cache.PartitionAttributes - * @see #isExpirationAllowed(GemFireCache) - */ - @Bean - @SuppressWarnings({ "unchecked", "deprecation" }) - public RegionAttributesFactoryBean sessionRegionAttributes(GemFireCache gemfireCache) { - RegionAttributesFactoryBean regionAttributes = new RegionAttributesFactoryBean(); - - regionAttributes.setKeyConstraint(SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT); - regionAttributes.setValueConstraint(SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT); - - if (isExpirationAllowed(gemfireCache)) { - regionAttributes.setStatisticsEnabled(true); - regionAttributes.setEntryIdleTimeout( - new ExpirationAttributes(Math.max(getMaxInactiveIntervalInSeconds(), 0), ExpirationAction.INVALIDATE)); - } - - return regionAttributes; - } - - /** - * Determines whether expiration configuration is allowed to be set on the GemFire - * cache {@link Region} used to store and manage Sessions. - * - * @param gemfireCache a reference to the GemFire cache. - * @return a boolean indicating if a {@link Region} can be configured for Region entry - * idle-timeout expiration. - * @see GemFireUtils#isClient(GemFireCache) - * @see GemFireUtils#isProxy(ClientRegionShortcut) - * @see GemFireUtils#isProxy(RegionShortcut) - */ - boolean isExpirationAllowed(GemFireCache gemfireCache) { - return !(GemFireUtils.isClient(gemfireCache) ? GemFireUtils.isProxy(getClientRegionShortcut()) - : GemFireUtils.isProxy(getServerRegionShortcut())); - } - - /** - * Defines a GemFire Index bean on the GemFire cache {@link Region} storing and managing Sessions, - * specifically on the 'principalName' property for quick lookup of Sessions by 'principalName'. - * - * @param gemfireCache a reference to the GemFire cache. - * @return a {@link IndexFactoryBean} to create an GemFire Index on the 'principalName' property - * for Sessions stored in the GemFire cache {@link Region}. - * @see org.springframework.data.gemfire.IndexFactoryBean - * @see org.apache.geode.cache.GemFireCache - */ - @Bean - @DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME) - public IndexFactoryBean principalNameIndex(GemFireCache gemfireCache) { - IndexFactoryBean index = new IndexFactoryBean(); - - index.setCache(gemfireCache); - index.setName("principalNameIndex"); - index.setExpression("principalName"); - index.setFrom(GemFireUtils.toRegionPath(getSpringSessionGemFireRegionName())); - index.setOverride(true); - index.setType(IndexType.HASH); - - return index; - } - - /** - * Defines a GemFire Index bean on the GemFire cache {@link Region} storing and managing Sessions, - * specifically on all Session attributes for quick lookup and queries on Session attribute names - * with a given value. - * - * @param gemfireCache a reference to the GemFire cache. - * @return a {@link IndexFactoryBean} to create an GemFire Index on attributes of Sessions - * stored in the GemFire cache {@link Region}. - * @see org.springframework.data.gemfire.IndexFactoryBean - * @see org.apache.geode.cache.GemFireCache - */ - @Bean - @DependsOn(DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME) - public SessionAttributesIndexFactoryBean sessionAttributesIndex(GemFireCache gemfireCache) { - SessionAttributesIndexFactoryBean sessionAttributesIndex = new SessionAttributesIndexFactoryBean(); - - sessionAttributesIndex.setGemFireCache(gemfireCache); - sessionAttributesIndex.setIndexableSessionAttributes(getIndexableSessionAttributes()); - sessionAttributesIndex.setRegionName(getSpringSessionGemFireRegionName()); - - return sessionAttributesIndex; - } -} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java deleted file mode 100644 index 1d18bcb4..00000000 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBean.java +++ /dev/null @@ -1,384 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http.support; - -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.InterestResultPolicy; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.apache.geode.cache.client.Pool; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.data.gemfire.GenericRegionFactoryBean; -import org.springframework.data.gemfire.client.ClientRegionFactoryBean; -import org.springframework.data.gemfire.client.Interest; -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * The {@link GemFireCacheTypeAwareRegionFactoryBean} class is a Spring {@link FactoryBean} - * used to construct, configure and initialize the GemFire cache {@link Region} used to - * store and manage Session state. - * - * @param the type of keys - * @param the type of values - * @author John Blum - * @since 1.1.0 - * @see org.springframework.data.gemfire.GenericRegionFactoryBean - * @see org.springframework.beans.factory.BeanFactoryAware - * @see org.springframework.beans.factory.FactoryBean - * @see org.springframework.beans.factory.InitializingBean - */ -public class GemFireCacheTypeAwareRegionFactoryBean - implements BeanFactoryAware, FactoryBean>, InitializingBean { - - protected static final ClientRegionShortcut DEFAULT_CLIENT_REGION_SHORTCUT = - GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT; - - protected static final RegionShortcut DEFAULT_SERVER_REGION_SHORTCUT = - GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT; - - protected static final String DEFAULT_GEMFIRE_POOL_NAME = - GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME; - - protected static final String DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME = - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME; - - private BeanFactory beanFactory; - - private ClientRegionShortcut clientRegionShortcut; - - private GemFireCache gemfireCache; - - private Region region; - - private RegionAttributes regionAttributes; - - private RegionShortcut serverRegionShortcut; - - private String poolName; - private String regionName; - - /** - * Post-construction initialization callback to create, configure and initialize the - * GemFire cache {@link Region} used to store, replicate (distribute) and manage - * Session state. This method intelligently handles both client-server and - * peer-to-peer (p2p) GemFire supported distributed system topologies. - * - * @throws Exception if the initialization of the GemFire cache {@link Region} fails. - * @see org.springframework.session.data.gemfire.support.GemFireUtils#isClient(GemFireCache) - * @see #getGemfireCache() - * @see #newClientRegion(GemFireCache) - * @see #newServerRegion(GemFireCache) - */ - public void afterPropertiesSet() throws Exception { - GemFireCache gemfireCache = getGemfireCache(); - - this.region = (GemFireUtils.isClient(gemfireCache) ? newClientRegion(gemfireCache) - : newServerRegion(gemfireCache)); - } - - /** - * Constructs a GemFire cache {@link Region} using a peer-to-peer (p2p) GemFire - * topology to store and manage Session state in a GemFire server cluster accessible - * from a GemFire cache client. - * - * @param gemfireCache a reference to the GemFire - * {@link org.apache.geode.cache.Cache}. - * @return a peer-to-peer-based GemFire cache {@link Region} to store and manage - * Session state. - * @throws Exception if the instantiation, configuration and initialization of the - * GemFire cache {@link Region} fails. - * @see org.springframework.data.gemfire.GenericRegionFactoryBean - * @see org.apache.geode.cache.GemFireCache - * @see org.apache.geode.cache.Region - * @see #getRegionAttributes() - * @see #getRegionName() - * @see #getServerRegionShortcut() - */ - protected Region newServerRegion(GemFireCache gemfireCache) throws Exception { - GenericRegionFactoryBean serverRegion = new GenericRegionFactoryBean(); - - serverRegion.setAttributes(getRegionAttributes()); - serverRegion.setCache(gemfireCache); - serverRegion.setRegionName(getRegionName()); - serverRegion.setShortcut(getServerRegionShortcut()); - serverRegion.afterPropertiesSet(); - - return serverRegion.getObject(); - } - - /** - * Constructs a GemFire cache {@link Region} using the client-server GemFire topology - * to store and manage Session state in a GemFire server cluster accessible from a - * GemFire cache client. - * - * @param gemfireCache a reference to the GemFire - * {@link org.apache.geode.cache.Cache}. - * @return a client-server-based GemFire cache {@link Region} to store and manage - * Session state. - * @throws Exception if the instantiation, configuration and initialization of the - * GemFire cache {@link Region} fails. - * @see org.springframework.data.gemfire.client.ClientRegionFactoryBean - * @see org.apache.geode.cache.GemFireCache - * @see org.apache.geode.cache.Region - * @see #getClientRegionShortcut() - * @see #getRegionAttributes() - * @see #getRegionName() - * @see #registerInterests(boolean) - */ - protected Region newClientRegion(GemFireCache gemfireCache) throws Exception { - ClientRegionFactoryBean clientRegion = new ClientRegionFactoryBean(); - - ClientRegionShortcut shortcut = getClientRegionShortcut(); - - clientRegion.setAttributes(getRegionAttributes()); - clientRegion.setBeanFactory(getBeanFactory()); - clientRegion.setCache(gemfireCache); - clientRegion.setInterests(registerInterests(!GemFireUtils.isLocal(shortcut))); - clientRegion.setPoolName(getPoolName()); - clientRegion.setRegionName(getRegionName()); - clientRegion.setShortcut(shortcut); - clientRegion.afterPropertiesSet(); - - return clientRegion.getObject(); - } - - /** - * Decides whether interests will be registered for all keys. Interests is only registered on - * a client and typically only when the client is a (CACHING) PROXY to the server (i.e. non-LOCAL only). - * - * @param register a boolean value indicating whether interests should be registered. - * @return an array of Interests KEY/VALUE registrations. - * @see org.springframework.data.gemfire.client.Interest - */ - @SuppressWarnings("unchecked") - protected Interest[] registerInterests(boolean register) { - return (!register ? new Interest[0] : new Interest[] { - new Interest("ALL_KEYS", InterestResultPolicy.KEYS) - }); - } - - /** - * Returns a reference to the constructed GemFire cache {@link Region} used to store - * and manage Session state. - * - * @return the {@link Region} used to store and manage Session state. - * @throws Exception if the {@link Region} reference cannot be obtained. - * @see org.apache.geode.cache.Region - */ - public Region getObject() throws Exception { - return this.region; - } - - /** - * Returns the specific type of GemFire cache {@link Region} this factory creates when - * initialized or Region.class when uninitialized. - * - * @return the GemFire cache {@link Region} class type constructed by this factory. - * @see org.apache.geode.cache.Region - * @see java.lang.Class - */ - public Class getObjectType() { - return (this.region != null ? this.region.getClass() : Region.class); - } - - /** - * Returns true indicating the GemFire cache {@link Region} created by this factory is - * the sole instance. - * - * @return true to indicate the GemFire cache {@link Region} storing and managing - * Sessions is a Singleton. - */ - public boolean isSingleton() { - return true; - } - - /** - * Sets a reference to the Spring {@link BeanFactory} responsible for - * creating GemFire components. - * - * @param beanFactory reference to the Spring {@link BeanFactory} - * @throws IllegalArgumentException if the {@link BeanFactory} reference is null. - * @see org.springframework.beans.factory.BeanFactory - */ - public void setBeanFactory(BeanFactory beanFactory) { - Assert.notNull(beanFactory, "BeanFactory must not be null"); - this.beanFactory = beanFactory; - } - - /** - * Gets a reference to the Spring {@link BeanFactory} responsible for - * creating GemFire components. - * - * @return a reference to the Spring {@link BeanFactory} - * @throws IllegalStateException if the {@link BeanFactory} reference - * is null. - * @see org.springframework.beans.factory.BeanFactory - */ - protected BeanFactory getBeanFactory() { - Assert.state(this.beanFactory != null, "A reference to the BeanFactory was not properly configured"); - return this.beanFactory; - } - - /** - * Sets the {@link Region} data policy used by the GemFire cache client to manage - * Session state. - * - * @param clientRegionShortcut a {@link ClientRegionShortcut} to specify the client - * {@link Region} data management policy. - * @see org.apache.geode.cache.client.ClientRegionShortcut - */ - public void setClientRegionShortcut(ClientRegionShortcut clientRegionShortcut) { - this.clientRegionShortcut = clientRegionShortcut; - } - - /** - * Returns the {@link Region} data policy used by the GemFire cache client to manage - * Session state. Defaults to {@link ClientRegionShortcut#PROXY}. - * - * @return a {@link ClientRegionShortcut} specifying the client {@link Region} data - * management policy. - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration#DEFAULT_CLIENT_REGION_SHORTCUT - * @see org.apache.geode.cache.client.ClientRegionShortcut - */ - protected ClientRegionShortcut getClientRegionShortcut() { - return (this.clientRegionShortcut != null ? this.clientRegionShortcut : DEFAULT_CLIENT_REGION_SHORTCUT); - } - - /** - * Sets a reference to the GemFire cache used to construct the appropriate - * {@link Region}. - * - * @param gemfireCache a reference to the GemFire cache. - * @throws IllegalArgumentException if the {@link GemFireCache} reference is null. - */ - public void setGemfireCache(GemFireCache gemfireCache) { - Assert.notNull(gemfireCache, "GemFireCache must not be null"); - this.gemfireCache = gemfireCache; - } - - /** - * Returns a reference to the GemFire cache used to construct the appropriate - * {@link Region}. - * - * @return a reference to the GemFire cache. - * @throws IllegalStateException if the {@link GemFireCache} reference is null. - */ - protected GemFireCache getGemfireCache() { - Assert.state(this.gemfireCache != null, "A reference to the GemFireCache was not properly configured"); - return this.gemfireCache; - } - - /** - * Sets the name of the GemFire {@link Pool} used by the client Region for managing Sessions - * during cache operations involving the server. - * - * @param poolName the name of a GemFire {@link Pool}. - * @see Pool#getName() - */ - public void setPoolName(final String poolName) { - this.poolName = poolName; - } - - /** - * Returns the name of the GemFire {@link Pool} used by the client Region for managing Sessions - * during cache operations involving the server. - * - * @return the name of a GemFire {@link Pool}. - * @see Pool#getName() - */ - protected String getPoolName() { - return (StringUtils.hasText(this.poolName) ? this.poolName : DEFAULT_GEMFIRE_POOL_NAME); - } - - /** - * Sets the GemFire {@link RegionAttributes} used to configure the GemFire cache - * {@link Region} used to store and manage Session state. - * - * @param regionAttributes the GemFire {@link RegionAttributes} used to configure the - * GemFire cache {@link Region}. - * @see org.apache.geode.cache.RegionAttributes - */ - public void setRegionAttributes(RegionAttributes regionAttributes) { - this.regionAttributes = regionAttributes; - } - - /** - * Returns the GemFire {@link RegionAttributes} used to configure the GemFire cache - * {@link Region} used to store and manage Session state. - * - * @return the GemFire {@link RegionAttributes} used to configure the GemFire cache - * {@link Region}. - * @see org.apache.geode.cache.RegionAttributes - */ - protected RegionAttributes getRegionAttributes() { - return this.regionAttributes; - } - - /** - * Sets the name of the GemFire cache {@link Region} use to store and manage Session - * state. - * - * @param regionName a String specifying the name of the GemFire cache {@link Region}. - */ - public void setRegionName(final String regionName) { - this.regionName = regionName; - } - - /** - * Returns the configured name of the GemFire cache {@link Region} use to store and - * manage Session state. Defaults to "ClusteredSpringSessions" - * - * @return a String specifying the name of the GemFire cache {@link Region}. - * @see org.apache.geode.cache.Region#getName() - */ - protected String getRegionName() { - return (StringUtils.hasText(this.regionName) ? this.regionName : DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - } - - /** - * Sets the {@link Region} data policy used by the GemFire peer cache to manage - * Session state. - * - * @param serverRegionShortcut a {@link RegionShortcut} to specify the peer - * {@link Region} data management policy. - * @see org.apache.geode.cache.RegionShortcut - */ - public void setServerRegionShortcut(RegionShortcut serverRegionShortcut) { - this.serverRegionShortcut = serverRegionShortcut; - } - - /** - * Returns the {@link Region} data policy used by the GemFire peer cache to manage - * Session state. Defaults to {@link RegionShortcut#PARTITION}. - * - * @return a {@link RegionShortcut} specifying the peer {@link Region} data management - * policy. - * @see org.apache.geode.cache.RegionShortcut - */ - protected RegionShortcut getServerRegionShortcut() { - return (this.serverRegionShortcut != null ? this.serverRegionShortcut : DEFAULT_SERVER_REGION_SHORTCUT); - } -} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBean.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBean.java deleted file mode 100644 index dc59c3b5..00000000 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBean.java +++ /dev/null @@ -1,175 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http.support; - -import javax.servlet.http.HttpSession; - -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.query.Index; - -import org.springframework.beans.BeansException; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanFactoryAware; -import org.springframework.beans.factory.BeanNameAware; -import org.springframework.beans.factory.FactoryBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.data.gemfire.IndexFactoryBean; -import org.springframework.session.data.gemfire.support.GemFireUtils; -import org.springframework.util.ObjectUtils; - -/** - * The SessionAttributesIndexFactoryBean class is a Spring {@link FactoryBean} that creates a GemFire {@link Index} - * on the session attributes of the {@link HttpSession} object. - * - * @author John Blum - * @since 1.3.0 - * @see org.springframework.beans.factory.BeanFactoryAware - * @see org.springframework.beans.factory.BeanNameAware - * @see org.springframework.beans.factory.FactoryBean - * @see org.springframework.beans.factory.InitializingBean - * @see org.apache.geode.cache.query.Index - */ -public class SessionAttributesIndexFactoryBean implements FactoryBean, - InitializingBean, BeanFactoryAware, BeanNameAware { - - protected static final String[] DEFAULT_INDEXABLE_SESSION_ATTRIBUTES = {}; - - private BeanFactory beanFactory; - - private GemFireCache gemfireCache; - - private Index sessionAttributesIndex; - - private String beanName; - private String regionName; - - private String[] indexableSessionAttributes; - - /* (non-Javadoc) */ - public void afterPropertiesSet() throws Exception { - if (isIndexableSessionAttributesConfigured()) { - this.sessionAttributesIndex = newIndex(); - } - } - - /** - * Determines whether any indexable Session attributes were configured for this {@link FactoryBean}. - * - * @return a boolean value indicating whether any indexable Session attributes were configured - * for this {@link FactoryBean} - * @see #setIndexableSessionAttributes(String[]) - */ - protected boolean isIndexableSessionAttributesConfigured() { - return !ObjectUtils.isEmpty(this.indexableSessionAttributes); - } - - /** - * Constructs a GemFire {@link Index} over the attributes of the {@link HttpSession}. - * - * @return a GemFire {@link Index} over the {@link HttpSession} attributes. - * @throws Exception if an error occurs while initializing the GemFire {@link Index}. - * @see org.springframework.data.gemfire.IndexFactoryBean - */ - protected Index newIndex() throws Exception { - IndexFactoryBean indexFactory = new IndexFactoryBean(); - - indexFactory.setBeanFactory(this.beanFactory); - indexFactory.setBeanName(this.beanName); - indexFactory.setCache(this.gemfireCache); - indexFactory.setName("sessionAttributesIndex"); - indexFactory.setExpression(String.format("s.attributes[%1$s]", - getIndexableSessionAttributesAsGemFireIndexExpression())); - indexFactory.setFrom(String.format("%1$s s", GemFireUtils.toRegionPath(this.regionName))); - indexFactory.setOverride(true); - indexFactory.afterPropertiesSet(); - - return indexFactory.getObject(); - } - - /** - * Gets the names of all Session attributes that will be indexed by GemFire as single, comma-delimited - * String value constituting the Index expression of the Index definition. - * - * @return a String composed of all the named Session attributes for which GemFire - * will create an Index as an Index definition expression. If the indexable Session - * attributes were not configured, then the wildcard ("*") is returned. - * @see org.apache.geode.cache.query.Index#getIndexedExpression() - */ - protected String getIndexableSessionAttributesAsGemFireIndexExpression() { - StringBuilder builder = new StringBuilder(); - - for (String sessionAttribute : getIndexableSessionAttributes()) { - builder.append(builder.length() > 0 ? ", " : ""); - builder.append(String.format("'%s'", sessionAttribute)); - } - - String indexExpression = builder.toString(); - - return (indexExpression.isEmpty() ? "*" : indexExpression); - } - - /* (non-Javadoc) */ - public Index getObject() throws Exception { - return this.sessionAttributesIndex; - } - - /* (non-Javadoc) */ - public Class getObjectType() { - return (this.sessionAttributesIndex != null ? this.sessionAttributesIndex.getClass() : Index.class); - } - - /* (non-Javadoc) */ - public boolean isSingleton() { - return true; - } - - /* (non-Javadoc) */ - public void setBeanFactory(BeanFactory beanFactory) throws BeansException { - this.beanFactory = beanFactory; - } - - /* (non-Javadoc) */ - public void setBeanName(String beanName) { - this.beanName = beanName; - } - - /* (non-Javadoc) */ - public void setGemFireCache(GemFireCache gemfireCache) { - this.gemfireCache = gemfireCache; - } - - /* (non-Javadoc) */ - public void setIndexableSessionAttributes(String[] indexableSessionAttributes) { - this.indexableSessionAttributes = indexableSessionAttributes; - } - - /* (non-Javadoc) */ - protected String[] getIndexableSessionAttributes() { - return (this.indexableSessionAttributes != null ? this.indexableSessionAttributes - : DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); - } - - /* (non-Javadoc) */ - public void setRegionName(String regionName) { - this.regionName = regionName; - } - - /* (non-Javadoc) */ - protected String getRegionName() { - return this.regionName; - } -} diff --git a/spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java b/spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java deleted file mode 100644 index cd54af0c..00000000 --- a/spring-session/src/main/java/org/springframework/session/data/gemfire/support/GemFireUtils.java +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.support; - -import java.io.Closeable; -import java.io.IOException; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.apache.geode.internal.cache.GemFireCacheImpl; - -/** - * GemFireUtils is an abstract, extensible utility class for working with GemFire types - * and functionality and is used by Spring Session's GemFire adapter support classes. - * - * @author John Blum - * @since 1.1.0 - */ -public abstract class GemFireUtils { - - /** - * Null-safe method to close the given {@link Closeable} object. - * - * @param obj the {@link Closeable} object to close. - * @return true if the {@link Closeable} object is not null and was successfully - * closed, otherwise return false. - * @see java.io.Closeable - */ - public static boolean close(Closeable obj) { - if (obj != null) { - try { - obj.close(); - return true; - } - catch (IOException ignore) { - } - } - - return false; - } - - /** - * Determines whether the GemFire cache is a client. - * - * @param gemFireCache a reference to the GemFire cache. - * @return a boolean value indicating whether the GemFire cache is a client. - * @see org.apache.geode.cache.client.ClientCache - * @see org.apache.geode.cache.GemFireCache - */ - public static boolean isClient(GemFireCache gemFireCache) { - boolean client = (gemFireCache instanceof ClientCache); - client &= (!(gemFireCache instanceof GemFireCacheImpl) || ((GemFireCacheImpl) gemFireCache).isClient()); - return client; - } - - /** - * Determines whether the GemFire cache is a peer. - * - * @param gemFireCache a reference to the GemFire cache. - * @return a boolean value indicating whether the GemFire cache is a peer. - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.GemFireCache - */ - public static boolean isPeer(GemFireCache gemFireCache) { - return (gemFireCache instanceof Cache && !isClient(gemFireCache)); - } - - /** - * Determines whether the given {@link ClientRegionShortcut} is local only. - * - * @param shortcut the ClientRegionShortcut to evaluate. - * @return a boolean value indicating if the {@link ClientRegionShortcut} is local or - * not. - * @see org.apache.geode.cache.client.ClientRegionShortcut - */ - public static boolean isLocal(ClientRegionShortcut shortcut) { - switch (shortcut) { - case LOCAL: - case LOCAL_HEAP_LRU: - case LOCAL_OVERFLOW: - case LOCAL_PERSISTENT: - case LOCAL_PERSISTENT_OVERFLOW: - return true; - default: - return false; - } - } - - /** - * Determines whether the client {@link ClientRegionShortcut} is a proxy-based - * shortcut. NOTE: "proxy"-based Regions keep no local state. - * - * @param shortcut the client {@link ClientRegionShortcut} to evaluate. - * @return a boolean value indicating whether the client {@link ClientRegionShortcut} - * refers to a proxy-based shortcut. - * @see org.apache.geode.cache.client.ClientRegionShortcut - */ - public static boolean isProxy(ClientRegionShortcut shortcut) { - switch (shortcut) { - case PROXY: - return true; - default: - return false; - } - } - - /** - * Determines whether the given {@link Region} is a PROXY, which would be indicated by the {@link Region} - * having a {@link DataPolicy} of {@link DataPolicy#EMPTY}. - * - * @param region {@link Region} to evaluate. - * @return a boolean value indicating whether the {@link Region} is a PROXY. - * @see org.apache.geode.cache.DataPolicy - * @see org.apache.geode.cache.Region - */ - public static boolean isProxy(Region region) { - return DataPolicy.EMPTY.equals(region.getAttributes().getDataPolicy()); - } - - /** - * Determines whether the peer {@link RegionShortcut} is a proxy-based shortcut. NOTE: - * "proxy"-based Regions keep no local state. - * - * @param shortcut the peer {@link RegionShortcut} to evaluate. - * @return a boolean value indicating whether the peer {@link RegionShortcut} refers - * to a proxy-based shortcut. - * @see org.apache.geode.cache.RegionShortcut - */ - public static boolean isProxy(RegionShortcut shortcut) { - switch (shortcut) { - case PARTITION_PROXY: - case PARTITION_PROXY_REDUNDANT: - case REPLICATE_PROXY: - return true; - default: - return false; - } - } - - /** - * Converts a {@link Region} name to a {@link Region} path. - * - * @param regionName a String specifying the name of the {@link Region}. - * @return a String path for the given {@link Region} by name. - * @see org.apache.geode.cache.Region#getFullPath() - * @see org.apache.geode.cache.Region#getName() - */ - public static String toRegionPath(String regionName) { - return String.format("%1$s%2$s", Region.SEPARATOR, regionName); - } -} diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepositoryTest.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepositoryTest.java deleted file mode 100644 index a2fc8d4b..00000000 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/AbstractGemFireOperationsSessionRepositoryTest.java +++ /dev/null @@ -1,1909 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.io.ByteArrayInputStream; -import java.io.ByteArrayOutputStream; -import java.io.DataInput; -import java.io.DataInputStream; -import java.io.DataOutput; -import java.io.DataOutputStream; -import java.io.IOException; -import java.util.Arrays; -import java.util.Collections; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; -import java.util.concurrent.TimeUnit; - -import edu.umd.cs.mtc.MultithreadedTestCase; -import edu.umd.cs.mtc.TestFramework; - -import org.apache.commons.logging.Log; -import org.apache.geode.cache.AttributesMutator; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.EntryEvent; -import org.apache.geode.cache.Operation; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.gemfire.GemfireOperations; -import org.springframework.data.gemfire.GemfireTemplate; -import org.springframework.session.ExpiringSession; -import org.springframework.session.FindByIndexNameSessionRepository; -import org.springframework.session.Session; -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; -import org.springframework.session.events.AbstractSessionEvent; -import org.springframework.session.events.SessionCreatedEvent; -import org.springframework.session.events.SessionDeletedEvent; -import org.springframework.session.events.SessionDestroyedEvent; -import org.springframework.session.events.SessionExpiredEvent; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyLong; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.willAnswer; -import static org.mockito.BDDMockito.willThrow; -import static org.mockito.Mockito.doNothing; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.never; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.spy; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * Unit tests for {@link AbstractGemFireOperationsSessionRepository}. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.mockito.Mock - * @see org.mockito.Mockito - * @see org.mockito.junit.MockitoJUnitRunner - * @see org.mockito.Spy - * @see org.springframework.data.gemfire.GemfireOperations - * @see org.springframework.session.ExpiringSession - * @see org.springframework.session.Session - * @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @see org.apache.geode.cache.Region - * @see edu.umd.cs.mtc.MultithreadedTestCase - * @see edu.umd.cs.mtc.TestFramework - */ -@RunWith(MockitoJUnitRunner.class) -public class AbstractGemFireOperationsSessionRepositoryTest { - - protected static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600; - - private AbstractGemFireOperationsSessionRepository sessionRepository; - - @Mock - private ExpiringSession mockExpiringSession; - - @Mock - private Log mockLog; - - @Before - public void setup() { - this.sessionRepository = spy(new TestGemFireOperationsSessionRepository(new GemfireTemplate()) { - @Override - Log newLogger() { - return AbstractGemFireOperationsSessionRepositoryTest.this.mockLog; - } - }); - } - - protected static Set asSet(E... elements) { - Set set = new HashSet(elements.length); - Collections.addAll(set, elements); - return set; - } - - @SuppressWarnings("unchecked") - protected EntryEvent mockEntryEvent(Operation operation, K key, V oldValue, V newValue) { - EntryEvent mockEntryEvent = mock(EntryEvent.class); - - given(mockEntryEvent.getOperation()).willReturn(operation); - given(mockEntryEvent.getKey()).willReturn(key); - given(mockEntryEvent.getOldValue()).willReturn(oldValue); - given(mockEntryEvent.getNewValue()).willReturn(newValue); - - return mockEntryEvent; - } - - @SuppressWarnings("unchecked") - protected Region mockRegion(String name, DataPolicy dataPolicy) { - Region mockRegion = mock(Region.class, name); - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - given(mockRegion.getAttributes()).willReturn(mockRegionAttributes); - given(mockRegionAttributes.getDataPolicy()).willReturn(dataPolicy); - - return mockRegion; - } - - protected ExpiringSession mockSession(String sessionId, long creationAndLastAccessedTime, - int maxInactiveIntervalInSeconds) { - - return mockSession(sessionId, creationAndLastAccessedTime, creationAndLastAccessedTime, - maxInactiveIntervalInSeconds); - } - - protected ExpiringSession mockSession(String sessionId, long creationTime, long lastAccessedTime, - int maxInactiveIntervalInSeconds) { - - ExpiringSession mockSession = mock(ExpiringSession.class, sessionId); - - given(mockSession.getId()).willReturn(sessionId); - given(mockSession.getCreationTime()).willReturn(creationTime); - given(mockSession.getLastAccessedTime()).willReturn(lastAccessedTime); - given(mockSession.getMaxInactiveIntervalInSeconds()).willReturn(maxInactiveIntervalInSeconds); - - return mockSession; - } - - protected AbstractGemFireOperationsSessionRepository withRegion( - AbstractGemFireOperationsSessionRepository sessionRepository, Region region) { - - ((GemfireTemplate) sessionRepository.getTemplate()).setRegion(region); - - return sessionRepository; - } - - @Test(expected = IllegalArgumentException.class) - public void constructGemFireOperationsSessionRepositoryWithNullTemplate() { - try { - new TestGemFireOperationsSessionRepository(null); - } - catch (IllegalArgumentException expected) { - assertThat(expected).hasMessage("GemfireOperations must not be null"); - assertThat(expected).hasNoCause(); - - throw expected; - } - } - - @Test - @SuppressWarnings("unchecked") - public void gemfireOperationsSessionRepositoryIsProperlyConstructedAndInitialized() throws Exception { - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - AttributesMutator mockAttributesMutator = mock(AttributesMutator.class); - Region mockRegion = mock(Region.class); - - given(mockRegion.getFullPath()).willReturn("/Example"); - given(mockRegion.getAttributesMutator()).willReturn(mockAttributesMutator); - - GemfireTemplate template = new GemfireTemplate(mockRegion); - - AbstractGemFireOperationsSessionRepository sessionRepository = - new TestGemFireOperationsSessionRepository(template); - - ApplicationEventPublisher applicationEventPublisher = sessionRepository.getApplicationEventPublisher(); - - assertThat(applicationEventPublisher).isNotNull(); - assertThat(sessionRepository.getFullyQualifiedRegionName()).isNull(); - assertThat(sessionRepository.getMaxInactiveIntervalInSeconds()) - .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS); - assertThat(sessionRepository.getTemplate()).isSameAs(template); - - sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - sessionRepository.setMaxInactiveIntervalInSeconds(300); - sessionRepository.afterPropertiesSet(); - - assertThat(sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - assertThat(sessionRepository.getFullyQualifiedRegionName()).isEqualTo("/Example"); - assertThat(sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(300); - assertThat(sessionRepository.getTemplate()).isSameAs(template); - - verify(mockRegion, times(1)).getAttributesMutator(); - verify(mockRegion, times(1)).getFullPath(); - verify(mockAttributesMutator, times(1)).addCacheListener(same(sessionRepository)); - } - - @Test - public void maxInactiveIntervalInSecondsAllowsNegativeValuesAndExtremelyLargeValues() { - assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()) - .isEqualTo(GemFireHttpSessionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS); - - this.sessionRepository.setMaxInactiveIntervalInSeconds(-1); - - assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(-1); - - this.sessionRepository.setMaxInactiveIntervalInSeconds(Integer.MIN_VALUE); - - assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(Integer.MIN_VALUE); - - this.sessionRepository.setMaxInactiveIntervalInSeconds(1024000); - - assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(1024000); - - this.sessionRepository.setMaxInactiveIntervalInSeconds(Integer.MAX_VALUE); - - assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(Integer.MAX_VALUE); - } - - @Test - public void isCreateWithCreateOperationReturnsTrue() { - EntryEvent mockEvent = - this.mockEntryEvent(Operation.CREATE, "123", null, - this.mockExpiringSession); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - assertThat(this.sessionRepository.isCreate(mockEvent)).isTrue(); - - verify(mockEvent, times(1)).getOperation(); - verify(mockEvent, times(1)).getKey(); - verify(mockEvent, times(1)).getNewValue(); - verify(mockEvent, never()).getOldValue(); - } - - @Test - public void isCreateWithCreateOperationAndNonProxyRegionReturnsTrue() { - EntryEvent mockEvent = - this.mockEntryEvent(Operation.CREATE, "123", null, null); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.NORMAL)); - - this.sessionRepository.remember("123"); - - assertThat(this.sessionRepository.isCreate(mockEvent)).isTrue(); - - verify(mockEvent, times(1)).getOperation(); - verify(mockEvent, never()).getKey(); - verify(mockEvent, times(1)).getNewValue(); - verify(mockEvent, never()).getOldValue(); - } - - @Test - public void isCreateWithLocalLoadCreateOperationReturnsFalse() { - EntryEvent mockEvent = - this.mockEntryEvent(Operation.LOCAL_LOAD_CREATE, "123", null, - this.mockExpiringSession); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - assertThat(this.sessionRepository.isCreate(mockEvent)).isFalse(); - - verify(mockEvent, times(1)).getOperation(); - verify(mockEvent, never()).getKey(); - verify(mockEvent, never()).getNewValue(); - verify(mockEvent, never()).getOldValue(); - } - - @Test - public void isCreateWithUpdateOperationReturnsFalse() { - EntryEvent mockEvent = - this.mockEntryEvent(Operation.UPDATE, "123", null, - this.mockExpiringSession); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - assertThat(this.sessionRepository.isCreate(mockEvent)).isFalse(); - - verify(mockEvent, times(1)).getOperation(); - verify(mockEvent, never()).getKey(); - verify(mockEvent, never()).getNewValue(); - verify(mockEvent, never()).getOldValue(); - } - - @Test - public void isCreateWithRememberedSessionIdReturnsFalse() { - EntryEvent mockEvent = - this.mockEntryEvent(Operation.CREATE, "123", null, - this.mockExpiringSession); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - this.sessionRepository.remember("123"); - - assertThat(this.sessionRepository.isCreate(mockEvent)).isFalse(); - - verify(mockEvent, times(1)).getOperation(); - verify(mockEvent, times(1)).getKey(); - verify(mockEvent, never()).getNewValue(); - verify(mockEvent, never()).getOldValue(); - } - - @Test - public void isCreateWithTombstoneReturnsFalse() { - EntryEvent mockEvent = - this.mockEntryEvent(Operation.CREATE, "123", null, - new Tombstone()); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - assertThat(this.sessionRepository.isCreate(mockEvent)).isFalse(); - - verify(mockEvent, times(1)).getOperation(); - verify(mockEvent, times(1)).getKey(); - verify(mockEvent, times(1)).getNewValue(); - verify(mockEvent, never()).getOldValue(); - } - - @Test - @SuppressWarnings("unchecked") - public void afterCreateWithSessionPublishesSessionCreatedEvent() { - final String sessionId = "abc123"; - final ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.getId()).willReturn(sessionId); - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionCreatedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isEqualTo(mockSession); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = - this.mockEntryEvent(Operation.CREATE, sessionId, null, mockSession); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterCreate(mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getOperation(); - verify(mockEntryEvent, times(2)).getKey(); - verify(mockEntryEvent, times(2)).getNewValue(); - verify(mockEntryEvent, never()).getOldValue(); - verify(mockSession, times(1)).getId(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionCreatedEvent.class)); - } - - @Test - @SuppressWarnings("unchecked") - public void afterCreateWithSessionIdPublishesSessionCreatedEvent() { - final String sessionId = "abc123"; - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionCreatedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = - this.mockEntryEvent(Operation.CREATE, sessionId, null, null); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterCreate(mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getOperation(); - verify(mockEntryEvent, times(2)).getKey(); - verify(mockEntryEvent, times(2)).getNewValue(); - verify(mockEntryEvent, never()).getOldValue(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionCreatedEvent.class)); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void afterCreateForDestroyOperationDoesNotPublishSessionCreatedEvent() { - Region mockRegion = mockRegion("Example", DataPolicy.EMPTY); - - TestGemFireOperationsSessionRepository sessionRepository = - new TestGemFireOperationsSessionRepository(new GemfireTemplate(mockRegion)) { - @Override - protected void handleCreated(String sessionId, ExpiringSession session) { - fail("handleCreated(..) should not have been called"); - } - }; - - EntryEvent mockEntryEvent = - mockEntryEvent(Operation.DESTROY, null, null, null); - - sessionRepository.afterCreate(mockEntryEvent); - - verify(mockEntryEvent, times(1)).getOperation(); - verify(mockEntryEvent, never()).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, never()).getOldValue(); - } - - @Test - @SuppressWarnings({ "rawtypes", "unchecked" }) - public void afterCreateForModificationDoesNotPublishSessionCreatedEvent() { - Region mockRegion = mockRegion("Example", DataPolicy.EMPTY); - - TestGemFireOperationsSessionRepository sessionRepository = - new TestGemFireOperationsSessionRepository(new GemfireTemplate(mockRegion)) { - @Override - protected void handleCreated(String sessionId, ExpiringSession session) { - fail("handleCreated(..) should not have been called"); - } - }; - - EntryEvent mockEntryEvent = - this.mockEntryEvent(Operation.CREATE, "123", null, null); - - sessionRepository.remember("123"); - sessionRepository.afterCreate(mockEntryEvent); - - verify(mockEntryEvent, times(1)).getOperation(); - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, never()).getOldValue(); - } - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void afterCreateForNonSessionTypeDoesNotPublishSessionCreatedEvent() { - Region mockRegion = mockRegion("Example", DataPolicy.EMPTY); - - TestGemFireOperationsSessionRepository sessionRepository = - new TestGemFireOperationsSessionRepository(new GemfireTemplate(mockRegion)) { - @Override - protected void handleCreated(String sessionId, ExpiringSession session) { - fail("handleCreated(..) should not have been called"); - } - }; - - EntryEvent mockEntryEvent = mockEntryEvent(Operation.CREATE, null, null, new Tombstone()); - - sessionRepository.afterCreate((EntryEvent) mockEntryEvent); - - verify(mockEntryEvent, times(1)).getOperation(); - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, times(1)).getNewValue(); - verify(mockEntryEvent, never()).getOldValue(); - } - - @Test - @SuppressWarnings("unchecked") - public void afterDestroyWithSessionPublishesSessionDestroyedEvent() { - final String sessionId = "def456"; - final ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.getId()).willReturn(sessionId); - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDestroyedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isEqualTo(mockSession); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = - this.mockEntryEvent(Operation.DESTROY, sessionId, mockSession, null); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterDestroy(mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, times(1)).getOldValue(); - verify(mockSession, times(1)).getId(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDestroyedEvent.class)); - } - - @Test - @SuppressWarnings("unchecked") - public void afterDestroyWithSessionIdPublishesSessionDestroyedEvent() { - final String sessionId = "def456"; - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDestroyedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = - this.mockEntryEvent(Operation.DESTROY, sessionId, null, null); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterDestroy(mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, times(1)).getOldValue(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDestroyedEvent.class)); - } - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void afterDestroyWithNonSessionTypePublishesSessionDestroyedEventWithSessionId() { - final String sessionId = "def456"; - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDestroyedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = mockEntryEvent(Operation.DESTROY, sessionId, new Tombstone(), null); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterDestroy((EntryEvent) mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, times(1)).getOldValue(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDestroyedEvent.class)); - } - - @Test - @SuppressWarnings("unchecked") - public void afterInvalidateWithSessionPublishesSessionExpiredEvent() { - final String sessionId = "ghi789"; - final ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.getId()).willReturn(sessionId); - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionExpiredEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isEqualTo(mockSession); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = - this.mockEntryEvent(Operation.INVALIDATE, sessionId, mockSession, null); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterInvalidate(mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, times(1)).getOldValue(); - verify(mockSession, times(1)).getId(); - verify(mockApplicationEventPublisher, times(1)).publishEvent(isA(SessionExpiredEvent.class)); - } - - @Test - @SuppressWarnings("unchecked") - public void afterInvalidateWithSessionIdPublishesSessionExpiredEvent() { - final String sessionId = "ghi789"; - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionExpiredEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = - this.mockEntryEvent(Operation.INVALIDATE, sessionId, null, null); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterInvalidate(mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, times(1)).getOldValue(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionExpiredEvent.class)); - } - - @Test - @SuppressWarnings({ "unchecked", "rawtypes" }) - public void afterInvalidateWithNonSessionTypePublishesSessionExpiredEventWithSessionId() { - final String sessionId = "ghi789"; - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionExpiredEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockEntryEvent = mock(EntryEvent.class); - - given(mockEntryEvent.getKey()).willReturn(sessionId); - given(mockEntryEvent.getOldValue()).willReturn(new Tombstone()); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterInvalidate((EntryEvent) mockEntryEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockEntryEvent, times(1)).getKey(); - verify(mockEntryEvent, never()).getNewValue(); - verify(mockEntryEvent, times(1)).getOldValue(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionExpiredEvent.class)); - } - - @Test - public void sessionCreateCreateExpireRecreatePublishesSessionEventsCreateExpireCreate() { - final String sessionId = "123456789"; - final ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.getId()).willReturn(sessionId); - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - int index = 0; - - Class[] expectedSessionTypes = { - SessionCreatedEvent.class, SessionExpiredEvent.class, SessionCreatedEvent.class - }; - - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(this.expectedSessionTypes[this.index++]); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isEqualTo(mockSession); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - EntryEvent mockCreateEvent = - this.mockEntryEvent(Operation.CREATE, sessionId, null, mockSession); - - EntryEvent mockExpireEvent = - this.mockEntryEvent(Operation.INVALIDATE, sessionId, mockSession, null); - - withRegion(this.sessionRepository, mockRegion("Example", DataPolicy.EMPTY)); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.afterCreate(mockCreateEvent); - this.sessionRepository.afterCreate(mockCreateEvent); - this.sessionRepository.afterInvalidate(mockExpireEvent); - this.sessionRepository.afterCreate(mockCreateEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockCreateEvent, times(3)).getOperation(); - verify(mockCreateEvent, times(5)).getKey(); - verify(mockCreateEvent, times(4)).getNewValue(); - verify(mockCreateEvent, never()).getOldValue(); - verify(mockExpireEvent, never()).getOperation(); - verify(mockExpireEvent, times(1)).getKey(); - verify(mockExpireEvent, never()).getNewValue(); - verify(mockExpireEvent, times(1)).getOldValue(); - verify(mockSession, times(3)).getId(); - verify(mockApplicationEventPublisher, times(2)) - .publishEvent(isA(SessionCreatedEvent.class)); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionExpiredEvent.class)); - } - - @Test - public void deleteSessionCallsDeleteSessionId() { - Session mockSession = mock(Session.class); - - doNothing().when(this.sessionRepository).delete(anyString()); - given(mockSession.getId()).willReturn("2"); - - assertThat(this.sessionRepository.delete(mockSession)).isNull(); - - verify(this.sessionRepository, times(1)).delete(eq("2")); - } - - @Test - public void handleDeletedWithSessionPublishesSessionDeletedEvent() { - final String sessionId = "abc123"; - final ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.getId()).willReturn(sessionId); - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isEqualTo(mockSession); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.handleDeleted(sessionId, mockSession); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockSession, times(1)).getId(); - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDeletedEvent.class)); - } - - @Test - public void handleDeletedWithSessionIdPublishesSessionDeletedEvent() { - final String sessionId = "abc123"; - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willAnswer(new Answer() { - public Void answer(InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isEqualTo(AbstractGemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(sessionId); - - return null; - } - }).given(mockApplicationEventPublisher).publishEvent(isA(ApplicationEvent.class)); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.handleDeleted(sessionId, null); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDeletedEvent.class)); - } - - @Test - public void publishEventHandlesThrowable() { - ApplicationEvent mockApplicationEvent = mock(ApplicationEvent.class); - - ApplicationEventPublisher mockApplicationEventPublisher = mock(ApplicationEventPublisher.class); - - willThrow(new IllegalStateException("test")).given(mockApplicationEventPublisher) - .publishEvent(any(ApplicationEvent.class)); - - this.sessionRepository.setApplicationEventPublisher(mockApplicationEventPublisher); - this.sessionRepository.publishEvent(mockApplicationEvent); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(mockApplicationEventPublisher); - - verify(mockApplicationEventPublisher, times(1)).publishEvent(eq(mockApplicationEvent)); - verify(this.mockLog, times(1)) - .error(eq(String.format("Error occurred publishing event [%s]", mockApplicationEvent)), - isA(IllegalStateException.class)); - } - - @Test - public void touchSetsLastAccessedTime() { - ExpiringSession mockSession = mock(ExpiringSession.class); - - assertThat(this.sessionRepository.touch(mockSession)).isSameAs(mockSession); - - verify(mockSession, times(1)).setLastAccessedTime(anyLong()); - } - - @Test - public void constructGemFireSessionWithDefaultInitialization() { - long beforeOrAtCreationTime = System.currentTimeMillis(); - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession(); - - assertThat(session.getId()).isNotNull(); - assertThat(session.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(0); - assertThat(session.getAttributeNames()).isNotNull(); - assertThat(session.getAttributeNames()).isEmpty(); - } - - @Test - public void constructGemFireSessionWithId() { - long beforeOrAtCreationTime = System.currentTimeMillis(); - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession("1"); - - assertThat(session.getId()).isEqualTo("1"); - assertThat(session.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(0); - assertThat(session.getAttributeNames()).isNotNull(); - assertThat(session.getAttributeNames()).isEmpty(); - } - - @Test(expected = IllegalArgumentException.class) - public void constructGemFireSessionWithUnspecifiedId() { - try { - new AbstractGemFireOperationsSessionRepository.GemFireSession(" "); - } - catch (IllegalArgumentException expected) { - assertThat(expected).hasMessage("ID must be specified"); - assertThat(expected).hasNoCause(); - - throw expected; - } - } - - @Test - public void constructGemFireSessionWithSession() { - long expectedCreationTime = 1L; - long expectedLastAccessTime = 2L; - - ExpiringSession mockSession = - mockSession("2", expectedCreationTime, expectedLastAccessTime, MAX_INACTIVE_INTERVAL_IN_SECONDS); - - Set expectedAttributedNames = asSet("attrOne", "attrTwo"); - - given(mockSession.getAttributeNames()).willReturn(expectedAttributedNames); - given(mockSession.getAttribute(eq("attrOne"))).willReturn("testOne"); - given(mockSession.getAttribute(eq("attrTwo"))).willReturn("testTwo"); - - AbstractGemFireOperationsSessionRepository.GemFireSession gemfireSession = - new AbstractGemFireOperationsSessionRepository.GemFireSession(mockSession); - - assertThat(gemfireSession.getId()).isEqualTo("2"); - assertThat(gemfireSession.getCreationTime()).isEqualTo(expectedCreationTime); - assertThat(gemfireSession.getLastAccessedTime()).isEqualTo(expectedLastAccessTime); - assertThat(gemfireSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - assertThat(gemfireSession.getAttributeNames()).isEqualTo(expectedAttributedNames); - assertThat(gemfireSession.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(gemfireSession.getAttribute("attrTwo")).isEqualTo("testTwo"); - - verify(mockSession, times(1)).getId(); - verify(mockSession, times(1)).getCreationTime(); - verify(mockSession, times(1)).getLastAccessedTime(); - verify(mockSession, times(1)).getMaxInactiveIntervalInSeconds(); - verify(mockSession, times(1)).getAttributeNames(); - verify(mockSession, times(1)).getAttribute(eq("attrOne")); - verify(mockSession, times(1)).getAttribute(eq("attrTwo")); - } - - @Test(expected = IllegalArgumentException.class) - public void constructGemFireSessionWithNullSession() { - try { - new AbstractGemFireOperationsSessionRepository.GemFireSession((ExpiringSession) null); - } - catch (IllegalArgumentException expected) { - assertThat(expected).hasMessage("The ExpiringSession to copy cannot be null"); - assertThat(expected).hasNoCause(); - - throw expected; - } - } - - @Test - public void createNewGemFireSession() { - long beforeOrAtCreationTime = System.currentTimeMillis(); - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - AbstractGemFireOperationsSessionRepository.GemFireSession.create(120); - - assertThat(session).isNotNull(); - assertThat(session.getId()).isNotNull(); - assertThat(session.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(session.getLastAccessedTime()).isEqualTo(session.getCreationTime()); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(120); - assertThat(session.getAttributeNames()).isNotNull(); - assertThat(session.getAttributeNames().isEmpty()).isTrue(); - } - - @Test - public void fromExistingSession() { - long expectedCreationTime = 1L; - long expectedLastAccessedTime = 2L; - - ExpiringSession mockSession = mockSession("4", expectedCreationTime, expectedLastAccessedTime, - MAX_INACTIVE_INTERVAL_IN_SECONDS); - - given(mockSession.getAttributeNames()).willReturn(Collections.emptySet()); - - AbstractGemFireOperationsSessionRepository.GemFireSession gemfireSession = - AbstractGemFireOperationsSessionRepository.GemFireSession.from(mockSession); - - assertThat(gemfireSession).isNotNull(); - assertThat(gemfireSession.getId()).isEqualTo("4"); - assertThat(gemfireSession.getCreationTime()).isEqualTo(expectedCreationTime); - assertThat(gemfireSession.getLastAccessedTime()).isEqualTo(expectedLastAccessedTime); - assertThat(gemfireSession.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - assertThat(gemfireSession.getAttributeNames()).isNotNull(); - assertThat(gemfireSession.getAttributeNames().isEmpty()).isTrue(); - - verify(mockSession, times(1)).getId(); - verify(mockSession, times(1)).getCreationTime(); - verify(mockSession, times(1)).getLastAccessedTime(); - verify(mockSession, times(1)).getMaxInactiveIntervalInSeconds(); - verify(mockSession, times(1)).getAttributeNames(); - verify(mockSession, never()).getAttribute(anyString()); - } - - @Test - public void fromExistingGemFireSessionIsGemFireSession() { - AbstractGemFireOperationsSessionRepository.GemFireSession gemfireSession = - AbstractGemFireOperationsSessionRepository.GemFireSession.create(300); - - AbstractGemFireOperationsSessionRepository.GemFireSession fromGemFireSession = - AbstractGemFireOperationsSessionRepository.GemFireSession.from(gemfireSession); - - assertThat(fromGemFireSession).isSameAs(gemfireSession); - } - - @Test - public void setGetAndRemoveAttribute() { - AbstractGemFireOperationsSessionRepository.GemFireSession session = - AbstractGemFireOperationsSessionRepository.GemFireSession.create(60); - - assertThat(session).isNotNull(); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(60); - assertThat(session.getAttributeNames().isEmpty()).isTrue(); - - session.setAttribute("attrOne", "testOne"); - - assertThat(session.getAttributeNames()).isEqualTo(asSet("attrOne")); - assertThat(session.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(session.getAttribute("attrTwo")).isNull(); - - session.setAttribute("attrTwo", "testTwo"); - - assertThat(session.getAttributeNames()).isEqualTo(asSet("attrOne", "attrTwo")); - assertThat(session.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(session.getAttribute("attrTwo")).isEqualTo("testTwo"); - - session.setAttribute("attrTwo", null); - - assertThat(session.getAttributeNames()).isEqualTo(asSet("attrOne")); - assertThat(session.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(session.getAttribute("attrTwo")).isNull(); - - session.removeAttribute("attrOne"); - - assertThat(session.getAttribute("attrOne")).isNull(); - assertThat(session.getAttribute("attrTwo")).isNull(); - assertThat(session.getAttributeNames().isEmpty()).isTrue(); - } - - @Test - public void isExpiredIsFalseWhenMaxInactiveIntervalIsNegative() { - final int expectedMaxInactiveIntervalInSeconds = -1; - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - AbstractGemFireOperationsSessionRepository.GemFireSession.create(expectedMaxInactiveIntervalInSeconds); - - assertThat(session).isNotNull(); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInactiveIntervalInSeconds); - assertThat(session.isExpired()).isFalse(); - } - - @Test - public void isExpiredIsFalseWhenSessionIsActive() { - final int expectedMaxInactiveIntervalInSeconds = (int) TimeUnit.HOURS.toSeconds(2); - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - AbstractGemFireOperationsSessionRepository.GemFireSession.create(expectedMaxInactiveIntervalInSeconds); - - assertThat(session).isNotNull(); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInactiveIntervalInSeconds); - - final long now = System.currentTimeMillis(); - - session.setLastAccessedTime(now); - - assertThat(session.getLastAccessedTime()).isEqualTo(now); - assertThat(session.isExpired()).isFalse(); - } - - @Test - public void isExpiredIsTrueWhenSessionIsInactive() { - final int expectedMaxInactiveIntervalInSeconds = 60; - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - AbstractGemFireOperationsSessionRepository.GemFireSession.create(expectedMaxInactiveIntervalInSeconds); - - assertThat(session).isNotNull(); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInactiveIntervalInSeconds); - - final long twoHoursAgo = (System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2)); - - session.setLastAccessedTime(twoHoursAgo); - - assertThat(session.getLastAccessedTime()).isEqualTo(twoHoursAgo); - assertThat(session.isExpired()).isTrue(); - } - - @Test - public void setAndGetPrincipalName() { - AbstractGemFireOperationsSessionRepository.GemFireSession session = - AbstractGemFireOperationsSessionRepository.GemFireSession.create(0); - - assertThat(session).isNotNull(); - assertThat(session.getPrincipalName()).isNull(); - - session.setPrincipalName("jblum"); - - assertThat(session.getPrincipalName()).isEqualTo("jblum"); - assertThat(session.getAttributeNames()) - .isEqualTo(asSet(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME)); - assertThat(session.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME)) - .isEqualTo("jblum"); - - session.setAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, "rwinch"); - - assertThat(session.getAttributeNames()) - .isEqualTo(asSet(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME)); - assertThat(session.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME)) - .isEqualTo("rwinch"); - assertThat(session.getPrincipalName()).isEqualTo("rwinch"); - - session.removeAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME); - - assertThat(session.getPrincipalName()).isNull(); - } - - @Test - public void sessionToData() throws Exception { - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession("1") { - @Override - void writeObject(Object obj, DataOutput out) throws IOException { - assertThat(obj) - .isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes.class); - assertThat(out).isNotNull(); - } - }; - - session.setLastAccessedTime(123L); - session.setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS); - session.setPrincipalName("jblum"); - - DataOutput mockDataOutput = mock(DataOutput.class); - - session.toData(mockDataOutput); - - verify(mockDataOutput, times(1)).writeUTF(eq("1")); - verify(mockDataOutput, times(1)).writeLong(eq(session.getCreationTime())); - verify(mockDataOutput, times(1)).writeLong(eq(session.getLastAccessedTime())); - verify(mockDataOutput, times(1)) - .writeInt(eq(session.getMaxInactiveIntervalInSeconds())); - verify(mockDataOutput, times(1)).writeInt(eq("jblum".length())); - verify(mockDataOutput, times(1)).writeUTF(eq(session.getPrincipalName())); - } - - @Test - public void sessionFromData() throws Exception { - long expectedCreationTime = 1L; - long expectedLastAccessedTime = 2L; - - int expectedMaxInactiveIntervalInSeconds = (int) TimeUnit.HOURS.toSeconds(6); - - final String expectedPrincipalName = "jblum"; - - DataInput mockDataInput = mock(DataInput.class); - - given(mockDataInput.readUTF()).willReturn("2").willReturn(expectedPrincipalName); - given(mockDataInput.readLong()).willReturn(expectedCreationTime).willReturn(expectedLastAccessedTime); - given(mockDataInput.readInt()).willReturn(expectedMaxInactiveIntervalInSeconds); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession("1") { - @Override - @SuppressWarnings("unchecked") - T readObject(DataInput in) throws ClassNotFoundException, IOException { - assertThat(in).isNotNull(); - - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes(); - - sessionAttributes.setAttribute("attrOne", "testOne"); - sessionAttributes.setAttribute("attrTwo", "testTwo"); - - return (T) sessionAttributes; - } - }; - - session.fromData(mockDataInput); - - Set expectedAttributeNames = - asSet("attrOne", "attrTwo", FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME); - - assertThat(session.getId()).isEqualTo("2"); - assertThat(session.getCreationTime()).isEqualTo(expectedCreationTime); - assertThat(session.getLastAccessedTime()).isEqualTo(expectedLastAccessedTime); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInactiveIntervalInSeconds); - assertThat(session.getPrincipalName()).isEqualTo(expectedPrincipalName); - assertThat(session.getAttributeNames().size()).isEqualTo(3); - assertThat(session.getAttributeNames().containsAll(expectedAttributeNames)).isTrue(); - assertThat(session.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(session.getAttribute("attrTwo")).isEqualTo("testTwo"); - assertThat(session.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME)) - .isEqualTo(expectedPrincipalName); - - verify(mockDataInput, times(2)).readUTF(); - verify(mockDataInput, times(2)).readLong(); - verify(mockDataInput, times(2)).readInt(); - } - - @Test - public void sessionToDataThenFromDataWhenPrincipalNameIsNullGetsHandledProperly() - throws ClassNotFoundException, IOException { - - final long beforeOrAtCreationTime = System.currentTimeMillis(); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSession expectedSession = - new AbstractGemFireOperationsSessionRepository.GemFireSession("123") { - @Override - void writeObject(Object obj, DataOutput out) throws IOException { - assertThat(obj) - .isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes.class); - assertThat(out).isNotNull(); - } - }; - - assertThat(expectedSession.getId()).isEqualTo("123"); - assertThat(expectedSession.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(expectedSession.getLastAccessedTime()).isGreaterThanOrEqualTo(expectedSession.getCreationTime()); - assertThat(expectedSession.getMaxInactiveIntervalInSeconds()).isEqualTo(0); - assertThat(expectedSession.getPrincipalName()).isNull(); - - ByteArrayOutputStream outBytes = new ByteArrayOutputStream(); - - expectedSession.toData(new DataOutputStream(outBytes)); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSession deserializedSession = - new AbstractGemFireOperationsSessionRepository.GemFireSession("0") { - @Override - @SuppressWarnings("unchecked") - T readObject(DataInput in) throws ClassNotFoundException, IOException { - return (T) new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes(); - } - }; - - deserializedSession.fromData(new DataInputStream(new ByteArrayInputStream(outBytes.toByteArray()))); - - assertThat(deserializedSession).isEqualTo(expectedSession); - assertThat(deserializedSession.getCreationTime()).isEqualTo(expectedSession.getCreationTime()); - assertThat(deserializedSession.getLastAccessedTime()).isEqualTo(expectedSession.getLastAccessedTime()); - assertThat(deserializedSession.getMaxInactiveIntervalInSeconds()) - .isEqualTo(expectedSession.getMaxInactiveIntervalInSeconds()); - assertThat(deserializedSession.getPrincipalName()).isNull(); - } - - @Test - public void hasDeltaWhenNoSessionChangesIsFalse() { - assertThat(new AbstractGemFireOperationsSessionRepository.GemFireSession().hasDelta()).isFalse(); - } - - @Test - public void hasDeltaWhenSessionAttributesChangeIsTrue() { - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession(); - - assertThat(session.hasDelta()).isFalse(); - - session.setAttribute("attrOne", "test"); - - assertThat(session.hasDelta()).isTrue(); - } - - @Test - public void hasDeltaWhenSessionLastAccessedTimeIsUpdatedIsTrue() { - long expectedLastAccessTime = 1L; - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession(); - - assertThat(session.getLastAccessedTime()).isNotEqualTo(expectedLastAccessTime); - assertThat(session.hasDelta()).isFalse(); - - session.setLastAccessedTime(expectedLastAccessTime); - - assertThat(session.getLastAccessedTime()).isEqualTo(expectedLastAccessTime); - assertThat(session.hasDelta()).isTrue(); - - session.setLastAccessedTime(expectedLastAccessTime); - - assertThat(session.getLastAccessedTime()).isEqualTo(expectedLastAccessTime); - assertThat(session.hasDelta()).isTrue(); - } - - @Test - public void hasDeltaWhenSessionMaxInactiveIntervalInSecondsIsUpdatedIsTrue() { - int expectedMaxInactiveIntervalInSeconds = 300; - - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession(); - - assertThat(session.getMaxInactiveIntervalInSeconds()).isNotEqualTo(expectedMaxInactiveIntervalInSeconds); - assertThat(session.hasDelta()).isFalse(); - - session.setMaxInactiveIntervalInSeconds(expectedMaxInactiveIntervalInSeconds); - - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInactiveIntervalInSeconds); - assertThat(session.hasDelta()).isTrue(); - - session.setMaxInactiveIntervalInSeconds(expectedMaxInactiveIntervalInSeconds); - - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(expectedMaxInactiveIntervalInSeconds); - assertThat(session.hasDelta()).isTrue(); - } - - @Test - public void sessionToDelta() throws Exception { - final DataOutput mockDataOutput = mock(DataOutput.class); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession() { - @Override - void writeObject(Object obj, DataOutput out) throws IOException { - assertThat(String.valueOf(obj)).isEqualTo("test"); - assertThat(out).isSameAs(mockDataOutput); - } - }; - - session.setLastAccessedTime(1L); - session.setMaxInactiveIntervalInSeconds(300); - session.setAttribute("attrOne", "test"); - - assertThat(session.hasDelta()).isTrue(); - - session.toDelta(mockDataOutput); - - assertThat(session.hasDelta()).isFalse(); - - verify(mockDataOutput, times(1)).writeLong(eq(1L)); - verify(mockDataOutput, times(1)).writeInt(eq(300)); - verify(mockDataOutput, times(1)).writeInt(eq(1)); - verify(mockDataOutput, times(1)).writeUTF(eq("attrOne")); - } - - @Test - public void sessionFromDelta() throws Exception { - final DataInput mockDataInput = mock(DataInput.class); - - given(mockDataInput.readLong()).willReturn(1L); - given(mockDataInput.readInt()).willReturn(600).willReturn(0); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession() { - @Override - @SuppressWarnings("unchecked") - T readObject(DataInput in) throws ClassNotFoundException, IOException { - assertThat(in).isSameAs(mockDataInput); - return (T) "test"; - } - }; - - session.fromDelta(mockDataInput); - - assertThat(session.hasDelta()).isFalse(); - assertThat(session.getLastAccessedTime()).isEqualTo(1L); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(600); - assertThat(session.getAttributeNames().isEmpty()).isTrue(); - - verify(mockDataInput, times(1)).readLong(); - verify(mockDataInput, times(2)).readInt(); - verify(mockDataInput, never()).readUTF(); - } - - @Test - public void sessionComparisons() { - long twoHoursAgo = (System.currentTimeMillis() - TimeUnit.HOURS.toMillis(2)); - - AbstractGemFireOperationsSessionRepository.GemFireSession sessionOne = - new AbstractGemFireOperationsSessionRepository.GemFireSession( - mockSession("1", twoHoursAgo, MAX_INACTIVE_INTERVAL_IN_SECONDS)); - - AbstractGemFireOperationsSessionRepository.GemFireSession sessionTwo = - new AbstractGemFireOperationsSessionRepository.GemFireSession("2"); - - assertThat(sessionOne.getCreationTime()).isEqualTo(twoHoursAgo); - assertThat(sessionTwo.getCreationTime()).isGreaterThan(twoHoursAgo); - assertThat(sessionOne.compareTo(sessionTwo)).isLessThan(0); - assertThat(sessionOne.compareTo(sessionOne)).isEqualTo(0); - assertThat(sessionTwo.compareTo(sessionOne)).isGreaterThan(0); - } - - @Test - public void sessionEqualsDifferentSessionBasedOnId() { - AbstractGemFireOperationsSessionRepository.GemFireSession sessionOne = - new AbstractGemFireOperationsSessionRepository.GemFireSession("1"); - - sessionOne.setLastAccessedTime(12345L); - sessionOne.setMaxInactiveIntervalInSeconds(120); - sessionOne.setPrincipalName("jblum"); - - AbstractGemFireOperationsSessionRepository.GemFireSession sessionTwo = - new AbstractGemFireOperationsSessionRepository.GemFireSession("1"); - - sessionTwo.setLastAccessedTime(67890L); - sessionTwo.setMaxInactiveIntervalInSeconds(300); - sessionTwo.setPrincipalName("rwinch"); - - assertThat(sessionOne.getId().equals(sessionTwo.getId())).isTrue(); - assertThat(sessionOne.getLastAccessedTime() == sessionTwo.getLastAccessedTime()).isFalse(); - assertThat(sessionOne.getMaxInactiveIntervalInSeconds() == sessionTwo.getMaxInactiveIntervalInSeconds()) - .isFalse(); - assertThat(sessionOne.getPrincipalName().equals(sessionTwo.getPrincipalName())).isFalse(); - assertThat(sessionOne.equals(sessionTwo)).isTrue(); - } - - @Test - public void sessionHashCodeIsNotEqualToStringIdHashCode() { - AbstractGemFireOperationsSessionRepository.GemFireSession session = - new AbstractGemFireOperationsSessionRepository.GemFireSession("1"); - - assertThat(session.getId()).isEqualTo("1"); - assertThat(session.hashCode()).isNotEqualTo("1".hashCode()); - } - - @Test - public void sessionAttributesFromSession() { - Session mockSession = mock(Session.class); - - given(mockSession.getAttributeNames()).willReturn(asSet("attrOne", "attrTwo")); - given(mockSession.getAttribute(eq("attrOne"))).willReturn("testOne"); - given(mockSession.getAttribute(eq("attrTwo"))).willReturn("testTwo"); - - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes(); - - assertThat(sessionAttributes.getAttributeNames().isEmpty()).isTrue(); - - sessionAttributes.from(mockSession); - - assertThat(sessionAttributes.getAttributeNames().size()).isEqualTo(2); - assertThat(sessionAttributes.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue(); - assertThat(sessionAttributes.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(sessionAttributes.getAttribute("attrTwo")).isEqualTo("testTwo"); - - verify(mockSession, times(1)).getAttributeNames(); - verify(mockSession, times(1)).getAttribute(eq("attrOne")); - verify(mockSession, times(1)).getAttribute(eq("attrTwo")); - } - - @Test - public void sessionAttributesFromSessionAttributes() { - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes source = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes(); - - source.setAttribute("attrOne", "testOne"); - source.setAttribute("attrTwo", "testTwo"); - - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes target = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes(); - - assertThat(target.getAttributeNames().isEmpty()).isTrue(); - - target.from(source); - - assertThat(target.getAttributeNames().size()).isEqualTo(2); - assertThat(target.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue(); - assertThat(target.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(target.getAttribute("attrTwo")).isEqualTo("testTwo"); - } - - @Test - public void sessionAttributesToData() throws Exception { - final DataOutput mockDataOutput = mock(DataOutput.class); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() { - private int count = 0; - - @Override - void writeObject(Object obj, DataOutput out) throws IOException { - assertThat(Arrays.asList("testOne", "testTwo").get(count++)).isEqualTo(String.valueOf(obj)); - assertThat(out).isSameAs(mockDataOutput); - } - }; - - sessionAttributes.setAttribute("attrOne", "testOne"); - sessionAttributes.setAttribute("attrTwo", "testTwo"); - - sessionAttributes.toData(mockDataOutput); - - verify(mockDataOutput, times(1)).writeInt(eq(2)); - verify(mockDataOutput, times(1)).writeUTF(eq("attrOne")); - verify(mockDataOutput, times(1)).writeUTF(eq("attrTwo")); - } - - @Test - public void sessionAttributesFromData() throws Exception { - final DataInput mockDataInput = mock(DataInput.class); - - given(mockDataInput.readInt()).willReturn(2); - given(mockDataInput.readUTF()).willReturn("attrOne").willReturn("attrTwo"); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() { - private int count = 0; - - @Override - @SuppressWarnings("unchecked") - T readObject(DataInput in) throws ClassNotFoundException, IOException { - assertThat(in).isSameAs(mockDataInput); - return (T) Arrays.asList("testOne", "testTwo").get(count++); - } - }; - - assertThat(sessionAttributes.getAttributeNames().isEmpty()).isTrue(); - - sessionAttributes.fromData(mockDataInput); - - assertThat(sessionAttributes.getAttributeNames().size()).isEqualTo(2); - assertThat(sessionAttributes.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue(); - assertThat(sessionAttributes.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(sessionAttributes.getAttribute("attrTwo")).isEqualTo("testTwo"); - - verify(mockDataInput, times(1)).readInt(); - verify(mockDataInput, times(2)).readUTF(); - } - - @Test - public void sessionAttributesHasDeltaIsFalse() { - assertThat(new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes().hasDelta()).isFalse(); - } - - @Test - public void sessionAttributesHasDeltaIsTrue() { - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes(); - - assertThat(sessionAttributes.hasDelta()).isFalse(); - - sessionAttributes.setAttribute("attrOne", "testOne"); - - assertThat(sessionAttributes.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(sessionAttributes.hasDelta()).isTrue(); - } - - @Test - public void sessionAttributesToDelta() throws Exception { - final DataOutput mockDataOutput = mock(DataOutput.class); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() { - private int count = 0; - - @Override - void writeObject(Object obj, DataOutput out) throws IOException { - assertThat(Arrays.asList("testOne", "testTwo", "testThree").get(count++)) - .isEqualTo(String.valueOf(obj)); - assertThat(out).isSameAs(mockDataOutput); - } - }; - - sessionAttributes.setAttribute("attrOne", "testOne"); - sessionAttributes.setAttribute("attrTwo", "testTwo"); - - assertThat(sessionAttributes.hasDelta()).isTrue(); - - sessionAttributes.toDelta(mockDataOutput); - - assertThat(sessionAttributes.hasDelta()).isFalse(); - - verify(mockDataOutput, times(1)).writeInt(eq(2)); - verify(mockDataOutput, times(1)).writeUTF("attrOne"); - verify(mockDataOutput, times(1)).writeUTF("attrTwo"); - reset(mockDataOutput); - - sessionAttributes.setAttribute("attrOne", "testOne"); - - assertThat(sessionAttributes.hasDelta()).isFalse(); - - sessionAttributes.toDelta(mockDataOutput); - - verify(mockDataOutput, times(1)).writeInt(eq(0)); - verify(mockDataOutput, never()).writeUTF(any(String.class)); - reset(mockDataOutput); - - sessionAttributes.setAttribute("attrTwo", "testThree"); - - assertThat(sessionAttributes.hasDelta()).isTrue(); - - sessionAttributes.toDelta(mockDataOutput); - - verify(mockDataOutput, times(1)).writeInt(eq(1)); - verify(mockDataOutput, times(1)).writeUTF(eq("attrTwo")); - } - - @Test - public void sessionAttributesFromDelta() throws Exception { - final DataInput mockDataInput = mock(DataInput.class); - - given(mockDataInput.readInt()).willReturn(2); - given(mockDataInput.readUTF()).willReturn("attrOne").willReturn("attrTwo"); - - @SuppressWarnings("serial") - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes() { - private int count = 0; - - @Override - @SuppressWarnings("unchecked") - T readObject(DataInput in) throws ClassNotFoundException, IOException { - assertThat(in).isSameAs(mockDataInput); - return (T) Arrays.asList("testOne", "testTwo", "testThree").get(count++); - } - }; - - sessionAttributes.setAttribute("attrOne", "one"); - sessionAttributes.setAttribute("attrTwo", "two"); - - assertThat(sessionAttributes.getAttributeNames().size()).isEqualTo(2); - assertThat(sessionAttributes.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue(); - assertThat(sessionAttributes.getAttribute("attrOne")).isEqualTo("one"); - assertThat(sessionAttributes.getAttribute("attrTwo")).isEqualTo("two"); - assertThat(sessionAttributes.hasDelta()).isTrue(); - - sessionAttributes.fromDelta(mockDataInput); - - assertThat(sessionAttributes.getAttributeNames().size()).isEqualTo(2); - assertThat(sessionAttributes.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue(); - assertThat(sessionAttributes.getAttribute("attrOne")).isEqualTo("testOne"); - assertThat(sessionAttributes.getAttribute("attrTwo")).isEqualTo("testTwo"); - assertThat(sessionAttributes.hasDelta()).isFalse(); - - verify(mockDataInput, times(1)).readInt(); - verify(mockDataInput, times(2)).readUTF(); - reset(mockDataInput); - - given(mockDataInput.readInt()).willReturn(1); - given(mockDataInput.readUTF()).willReturn("attrTwo"); - - sessionAttributes.setAttribute("attrOne", "one"); - sessionAttributes.setAttribute("attrTwo", "two"); - - assertThat(sessionAttributes.getAttributeNames().size()).isEqualTo(2); - assertThat(sessionAttributes.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue(); - assertThat(sessionAttributes.getAttribute("attrOne")).isEqualTo("one"); - assertThat(sessionAttributes.getAttribute("attrTwo")).isEqualTo("two"); - assertThat(sessionAttributes.hasDelta()).isTrue(); - - sessionAttributes.fromDelta(mockDataInput); - - assertThat(sessionAttributes.getAttributeNames().size()).isEqualTo(2); - assertThat(sessionAttributes.getAttributeNames().containsAll(asSet("attrOne", "attrTwo"))).isTrue(); - assertThat(sessionAttributes.getAttribute("attrOne")).isEqualTo("one"); - assertThat(sessionAttributes.getAttribute("attrTwo")).isEqualTo("testThree"); - assertThat(sessionAttributes.hasDelta()).isTrue(); - - verify(mockDataInput, times(1)).readInt(); - verify(mockDataInput, times(1)).readUTF(); - } - - @Test - public void sessionAttributesEntrySetIteratesAttributeNameValues() { - AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes sessionAttributes = - new AbstractGemFireOperationsSessionRepository.GemFireSessionAttributes(); - - sessionAttributes.setAttribute("keyOne", "valueOne"); - sessionAttributes.setAttribute("keyTwo", "valueTwo"); - - Set> sessionAttributeEntries = sessionAttributes.entrySet(); - - assertThat(sessionAttributeEntries).isNotNull(); - assertThat(sessionAttributeEntries.size()).isEqualTo(2); - - Set expectedNames = asSet("keyOne", "keyTwo"); - Set expectedValues = asSet("valueOne", "valueTwo"); - - for (Map.Entry entry : sessionAttributeEntries) { - expectedNames.remove(entry.getKey()); - expectedValues.remove(entry.getValue()); - } - - assertThat(expectedNames.isEmpty()).isTrue(); - assertThat(expectedValues.isEmpty()).isTrue(); - - sessionAttributes.setAttribute("keyThree", "valueThree"); - - assertThat(sessionAttributeEntries.size()).isEqualTo(3); - - expectedNames = asSet("keyOne", "keyTwo"); - expectedValues = asSet("valueOne", "valueTwo"); - - for (Map.Entry entry : sessionAttributeEntries) { - expectedNames.remove(entry.getKey()); - expectedValues.remove(entry.getValue()); - } - - assertThat(expectedNames.isEmpty()).isTrue(); - assertThat(expectedValues.isEmpty()).isTrue(); - - sessionAttributes.removeAttribute("keyOne"); - sessionAttributes.removeAttribute("keyTwo"); - - assertThat(sessionAttributeEntries.size()).isEqualTo(1); - - Map.Entry entry = sessionAttributeEntries.iterator().next(); - - assertThat(entry.getKey()).isEqualTo("keyThree"); - assertThat(entry.getValue()).isEqualTo("valueThree"); - } - - @Test - public void sessionWithAttributesAreThreadSafe() throws Throwable { - TestFramework.runOnce(new ThreadSafeSessionTest()); - } - - protected static final class ThreadSafeSessionTest extends MultithreadedTestCase { - - private final long beforeOrAtCreationTime = System.currentTimeMillis(); - - private AbstractGemFireOperationsSessionRepository.GemFireSession session; - - private volatile long expectedCreationTime; - - @Override - public void initialize() { - this.session = new AbstractGemFireOperationsSessionRepository.GemFireSession("1"); - - assertThat(this.session).isNotNull(); - assertThat(this.session.getId()).isEqualTo("1"); - assertThat(this.session.getCreationTime()).isGreaterThanOrEqualTo(this.beforeOrAtCreationTime); - assertThat(this.session.getLastAccessedTime()).isEqualTo(this.session.getCreationTime()); - assertThat(this.session.getMaxInactiveIntervalInSeconds()).isEqualTo(0); - assertThat(this.session.getPrincipalName()).isNull(); - assertThat(this.session.getAttributeNames().isEmpty()).isTrue(); - - this.expectedCreationTime = this.session.getCreationTime(); - - this.session.setLastAccessedTime(0L); - this.session.setMaxInactiveIntervalInSeconds(60); - this.session.setPrincipalName("jblum"); - } - - public void thread1() { - assertTick(0); - - Thread.currentThread().setName("HTTP Request Processing Thread 1"); - - assertThat(this.session).isNotNull(); - assertThat(this.session.getId()).isEqualTo("1"); - assertThat(this.session.getCreationTime()).isEqualTo(this.expectedCreationTime); - assertThat(this.session.getLastAccessedTime()).isEqualTo(0L); - assertThat(this.session.getMaxInactiveIntervalInSeconds()).isEqualTo(60); - assertThat(this.session.getPrincipalName()).isEqualTo("jblum"); - assertThat(this.session.getAttributeNames().size()).isEqualTo(1); - assertThat(this.session.getAttribute(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME)) - .isEqualTo("jblum"); - - this.session.setAttribute("tennis", "ping"); - this.session.setAttribute("junk", "test"); - this.session.setLastAccessedTime(1L); - this.session.setMaxInactiveIntervalInSeconds(120); - this.session.setPrincipalName("rwinch"); - - waitForTick(2); - - assertThat(this.session).isNotNull(); - assertThat(this.session.getId()).isEqualTo("1"); - assertThat(this.session.getCreationTime()).isEqualTo(this.expectedCreationTime); - assertThat(this.session.getLastAccessedTime()).isEqualTo(2L); - assertThat(this.session.getMaxInactiveIntervalInSeconds()).isEqualTo(180); - assertThat(this.session.getPrincipalName()).isEqualTo("ogierke"); - assertThat(this.session.getAttributeNames().size()).isEqualTo(3); - assertThat(this.session.getAttributeNames().containsAll(asSet("tennis", "greeting"))).isTrue(); - assertThat(this.session.getAttributeNames().contains("junk")).isFalse(); - assertThat(this.session.getAttribute("junk")).isNull(); - assertThat(this.session.getAttribute("tennis")).isEqualTo("pong"); - assertThat(this.session.getAttribute("greeting")).isEqualTo("hello"); - } - - public void thread2() { - assertTick(0); - - Thread.currentThread().setName("HTTP Request Processing Thread 2"); - - waitForTick(1); - assertTick(1); - - assertThat(this.session).isNotNull(); - assertThat(this.session.getId()).isEqualTo("1"); - assertThat(this.session.getCreationTime()).isEqualTo(this.expectedCreationTime); - assertThat(this.session.getLastAccessedTime()).isEqualTo(1L); - assertThat(this.session.getMaxInactiveIntervalInSeconds()).isEqualTo(120); - assertThat(this.session.getPrincipalName()).isEqualTo("rwinch"); - assertThat(this.session.getAttributeNames().size()).isEqualTo(3); - assertThat(this.session.getAttributeNames().containsAll(asSet("tennis", "junk"))).isTrue(); - assertThat(this.session.getAttribute("junk")).isEqualTo("test"); - assertThat(this.session.getAttribute("tennis")).isEqualTo("ping"); - - this.session.setAttribute("tennis", "pong"); - this.session.setAttribute("greeting", "hello"); - this.session.removeAttribute("junk"); - this.session.setLastAccessedTime(2L); - this.session.setMaxInactiveIntervalInSeconds(180); - this.session.setPrincipalName("ogierke"); - } - - @Override - public void finish() { - this.session = null; - } - } - - static class Tombstone { - } - - static class TestGemFireOperationsSessionRepository extends AbstractGemFireOperationsSessionRepository { - - TestGemFireOperationsSessionRepository(GemfireOperations gemfireOperations) { - super(gemfireOperations); - } - - public ExpiringSession createSession() { - throw new UnsupportedOperationException("Not Implemented"); - } - - public Map findByIndexNameAndIndexValue(String indexName, String indexValue) { - throw new UnsupportedOperationException("Not Implemented"); - } - - public ExpiringSession getSession(String id) { - throw new UnsupportedOperationException("Not Implemented"); - } - - public void save(ExpiringSession session) { - throw new UnsupportedOperationException("Not Implemented"); - } - - public void delete(String id) { - throw new UnsupportedOperationException("Not Implemented"); - } - } -} diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryTest.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryTest.java deleted file mode 100644 index 86fc2860..00000000 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/GemFireOperationsSessionRepositoryTest.java +++ /dev/null @@ -1,436 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire; - -import java.util.Arrays; -import java.util.Collections; -import java.util.Map; -import java.util.concurrent.TimeUnit; - -import org.apache.geode.cache.AttributesMutator; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.query.SelectResults; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.invocation.InvocationOnMock; -import org.mockito.junit.MockitoJUnitRunner; -import org.mockito.stubbing.Answer; - -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.data.gemfire.GemfireAccessor; -import org.springframework.data.gemfire.GemfireOperations; -import org.springframework.session.ExpiringSession; -import org.springframework.session.FindByIndexNameSessionRepository; -import org.springframework.session.events.AbstractSessionEvent; -import org.springframework.session.events.SessionDeletedEvent; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.ArgumentMatchers.isA; -import static org.mockito.ArgumentMatchers.same; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.willAnswer; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * The GemFireOperationsSessionRepositoryTest class is a test suite of test cases testing - * the contract and functionality of the GemFireOperationsSessionRepository class. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.junit.runner.RunWith - * @see org.mockito.Mock - * @see org.mockito.Mockito - * @see org.mockito.junit.MockitoJUnitRunner - * @see org.springframework.data.gemfire.GemfireOperations - * @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository - * @see org.apache.geode.cache.Region - */ -@RunWith(MockitoJUnitRunner.class) -public class GemFireOperationsSessionRepositoryTest { - - protected static final int MAX_INACTIVE_INTERVAL_IN_SECONDS = 600; - - @Mock - private ApplicationEventPublisher mockApplicationEventPublisher; - - @Mock - private AttributesMutator mockAttributesMutator; - - @Mock - private GemfireOperationsAccessor mockTemplate; - - private GemFireOperationsSessionRepository sessionRepository; - - @Mock - private Region mockRegion; - - @Before - public void setup() throws Exception { - given(this.mockRegion.getAttributesMutator()).willReturn(this.mockAttributesMutator); - given(this.mockRegion.getFullPath()).willReturn("/Example"); - given(this.mockTemplate.getRegion()).willReturn(this.mockRegion); - - this.sessionRepository = new GemFireOperationsSessionRepository(this.mockTemplate); - this.sessionRepository.setApplicationEventPublisher(this.mockApplicationEventPublisher); - this.sessionRepository.setMaxInactiveIntervalInSeconds(MAX_INACTIVE_INTERVAL_IN_SECONDS); - this.sessionRepository.afterPropertiesSet(); - - assertThat(this.sessionRepository.getApplicationEventPublisher()).isSameAs(this.mockApplicationEventPublisher); - assertThat(this.sessionRepository.getFullyQualifiedRegionName()).isEqualTo("/Example"); - assertThat(this.sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - @After - public void tearDown() { - verify(this.mockAttributesMutator, times(1)).addCacheListener(same(this.sessionRepository)); - verify(this.mockRegion, times(1)).getFullPath(); - verify(this.mockTemplate, times(1)).getRegion(); - } - - @Test - @SuppressWarnings("unchecked") - public void findByIndexNameValueFindsMatchingSession() { - ExpiringSession mockSession = mock(ExpiringSession.class, "MockSession"); - - given(mockSession.getId()).willReturn("1"); - - SelectResults mockSelectResults = mock(SelectResults.class); - - given(mockSelectResults.asList()).willReturn(Collections.singletonList(mockSession)); - - String indexName = "vip"; - String indexValue = "rwinch"; - - String expectedQql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY, - this.sessionRepository.getFullyQualifiedRegionName(), indexName); - - given(this.mockTemplate.find(eq(expectedQql), eq(indexValue))).willReturn(mockSelectResults); - - Map sessions = - this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue); - - assertThat(sessions).isNotNull(); - assertThat(sessions.size()).isEqualTo(1); - assertThat(sessions.get("1")).isEqualTo(mockSession); - - verify(this.mockTemplate, times(1)).find(eq(expectedQql), eq(indexValue)); - verify(mockSelectResults, times(1)).asList(); - verify(mockSession, times(1)).getId(); - } - - @Test - @SuppressWarnings("unchecked") - public void findByPrincipalNameFindsMatchingSessions() throws Exception { - ExpiringSession mockSessionOne = mock(ExpiringSession.class, "MockSessionOne"); - ExpiringSession mockSessionTwo = mock(ExpiringSession.class, "MockSessionTwo"); - ExpiringSession mockSessionThree = mock(ExpiringSession.class, "MockSessionThree"); - - given(mockSessionOne.getId()).willReturn("1"); - given(mockSessionTwo.getId()).willReturn("2"); - given(mockSessionThree.getId()).willReturn("3"); - - SelectResults mockSelectResults = mock(SelectResults.class); - - given(mockSelectResults.asList()) - .willReturn(Arrays.asList(mockSessionOne, mockSessionTwo, mockSessionThree)); - - String principalName = "jblum"; - - String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, - this.sessionRepository.getFullyQualifiedRegionName()); - - given(this.mockTemplate.find(eq(expectedOql), eq(principalName))).willReturn(mockSelectResults); - - Map sessions = this.sessionRepository.findByIndexNameAndIndexValue( - FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName); - - assertThat(sessions).isNotNull(); - assertThat(sessions.size()).isEqualTo(3); - assertThat(sessions.get("1")).isEqualTo(mockSessionOne); - assertThat(sessions.get("2")).isEqualTo(mockSessionTwo); - assertThat(sessions.get("3")).isEqualTo(mockSessionThree); - - verify(this.mockTemplate, times(1)).find(eq(expectedOql), eq(principalName)); - verify(mockSelectResults, times(1)).asList(); - verify(mockSessionOne, times(1)).getId(); - verify(mockSessionTwo, times(1)).getId(); - verify(mockSessionThree, times(1)).getId(); - } - - @Test - @SuppressWarnings("unchecked") - public void findByPrincipalNameReturnsNoMatchingSessions() { - SelectResults mockSelectResults = mock(SelectResults.class); - - given(mockSelectResults.asList()).willReturn(Collections.emptyList()); - - String principalName = "jblum"; - - String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, - this.sessionRepository.getFullyQualifiedRegionName()); - - given(this.mockTemplate.find(eq(expectedOql), eq(principalName))).willReturn(mockSelectResults); - - Map sessions = this.sessionRepository.findByIndexNameAndIndexValue( - FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME, principalName); - - assertThat(sessions).isNotNull(); - assertThat(sessions.isEmpty()).isTrue(); - - verify(this.mockTemplate, times(1)).find(eq(expectedOql), eq(principalName)); - verify(mockSelectResults, times(1)).asList(); - } - - @Test - public void prepareQueryReturnsPrincipalNameOql() { - String actualQql = - this.sessionRepository.prepareQuery(FindByIndexNameSessionRepository.PRINCIPAL_NAME_INDEX_NAME); - - String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_PRINCIPAL_NAME_QUERY, - this.sessionRepository.getFullyQualifiedRegionName()); - - assertThat(actualQql).isEqualTo(expectedOql); - } - - @Test - public void prepareQueryReturnsIndexNameValueOql() { - String attributeName = "testAttributeName"; - String actualOql = this.sessionRepository.prepareQuery(attributeName); - String expectedOql = String.format(GemFireOperationsSessionRepository.FIND_SESSIONS_BY_INDEX_NAME_VALUE_QUERY, - this.sessionRepository.getFullyQualifiedRegionName(), attributeName); - - assertThat(actualOql).isEqualTo(expectedOql); - } - - @Test - public void createProperlyInitializedSession() { - long beforeOrAtCreationTime = System.currentTimeMillis(); - - ExpiringSession session = this.sessionRepository.createSession(); - - assertThat(session).isInstanceOf(AbstractGemFireOperationsSessionRepository.GemFireSession.class); - assertThat(session.getId()).isNotNull(); - assertThat(session.getAttributeNames().isEmpty()).isTrue(); - assertThat(session.getCreationTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(session.getLastAccessedTime()).isGreaterThanOrEqualTo(beforeOrAtCreationTime); - assertThat(session.getMaxInactiveIntervalInSeconds()).isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - } - - @Test - public void getSessionDeletesMatchingExpiredSessionById() { - final String expectedSessionId = "1"; - - final ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.isExpired()).willReturn(true); - given(mockSession.getId()).willReturn(expectedSessionId); - given(this.mockTemplate.get(eq(expectedSessionId))).willReturn(mockSession); - given(this.mockTemplate.remove(eq(expectedSessionId))).willReturn(mockSession); - - willAnswer(new Answer() { - public Void answer(final InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isSameAs(mockSession); - assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId); - - return null; - } - }).given(this.mockApplicationEventPublisher).publishEvent(any(ApplicationEvent.class)); - - assertThat(this.sessionRepository.getSession(expectedSessionId)).isNull(); - - verify(this.mockTemplate, times(1)).get(eq(expectedSessionId)); - verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId)); - verify(mockSession, times(1)).isExpired(); - verify(mockSession, times(2)).getId(); - verify(this.mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDeletedEvent.class)); - } - - @Test - public void getSessionFindsMatchingNonExpiredSessionById() { - String expectedId = "1"; - - long expectedCreationTime = System.currentTimeMillis(); - long currentLastAccessedTime = (expectedCreationTime + TimeUnit.MINUTES.toMillis(5)); - - ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.isExpired()).willReturn(false); - given(mockSession.getId()).willReturn(expectedId); - given(mockSession.getCreationTime()).willReturn(expectedCreationTime); - given(mockSession.getLastAccessedTime()).willReturn(currentLastAccessedTime); - given(mockSession.getAttributeNames()).willReturn(Collections.singleton("attrOne")); - given(mockSession.getAttribute(eq("attrOne"))).willReturn("test"); - given(this.mockTemplate.get(eq(expectedId))).willReturn(mockSession); - - ExpiringSession actualSession = this.sessionRepository.getSession(expectedId); - - assertThat(actualSession).isNotSameAs(mockSession); - assertThat(actualSession.getId()).isEqualTo(expectedId); - assertThat(actualSession.getCreationTime()).isEqualTo(expectedCreationTime); - assertThat(actualSession.getLastAccessedTime()).isNotEqualTo(currentLastAccessedTime); - assertThat(actualSession.getLastAccessedTime()).isGreaterThanOrEqualTo(expectedCreationTime); - assertThat(actualSession.getAttributeNames()).isEqualTo(Collections.singleton("attrOne")); - assertThat(String.valueOf(actualSession.getAttribute("attrOne"))).isEqualTo("test"); - - verify(this.mockTemplate, times(1)).get(eq(expectedId)); - verify(mockSession, times(1)).isExpired(); - verify(mockSession, times(1)).getId(); - verify(mockSession, times(1)).getCreationTime(); - verify(mockSession, times(1)).getLastAccessedTime(); - verify(mockSession, times(1)).getAttributeNames(); - verify(mockSession, times(1)).getAttribute(eq("attrOne")); - } - - @Test - public void getSessionReturnsNull() { - given(this.mockTemplate.get(anyString())).willReturn(null); - assertThat(this.sessionRepository.getSession("1")).isNull(); - } - - @Test - public void saveStoresSession() { - final String expectedSessionId = "1"; - - final long expectedCreationTime = System.currentTimeMillis(); - final long expectedLastAccessTime = (expectedCreationTime + TimeUnit.MINUTES.toMillis(5)); - - ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.getId()).willReturn(expectedSessionId); - given(mockSession.getCreationTime()).willReturn(expectedCreationTime); - given(mockSession.getLastAccessedTime()).willReturn(expectedLastAccessTime); - given(mockSession.getMaxInactiveIntervalInSeconds()) - .willReturn(MAX_INACTIVE_INTERVAL_IN_SECONDS); - given(mockSession.getAttributeNames()).willReturn(Collections.emptySet()); - - given(this.mockTemplate.put(eq(expectedSessionId), - isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class))) - .willAnswer(new Answer() { - public ExpiringSession answer(InvocationOnMock invocation) throws Throwable { - ExpiringSession session = invocation.getArgument(1); - - assertThat(session).isNotNull(); - assertThat(session.getId()).isEqualTo(expectedSessionId); - assertThat(session.getCreationTime()).isEqualTo(expectedCreationTime); - assertThat(session.getLastAccessedTime()).isEqualTo(expectedLastAccessTime); - assertThat(session.getMaxInactiveIntervalInSeconds()) - .isEqualTo(MAX_INACTIVE_INTERVAL_IN_SECONDS); - assertThat(session.getAttributeNames().isEmpty()).isTrue(); - - return null; - } - }); - - this.sessionRepository.save(mockSession); - - verify(mockSession, times(2)).getId(); - verify(mockSession, times(1)).getCreationTime(); - verify(mockSession, times(1)).getLastAccessedTime(); - verify(mockSession, times(1)).getMaxInactiveIntervalInSeconds(); - verify(mockSession, times(1)).getAttributeNames(); - verify(this.mockTemplate, times(1)).put(eq(expectedSessionId), - isA(AbstractGemFireOperationsSessionRepository.GemFireSession.class)); - } - - @Test - public void deleteRemovesExistingSessionAndHandlesDelete() { - final String expectedSessionId = "1"; - - final ExpiringSession mockSession = mock(ExpiringSession.class); - - given(mockSession.getId()).willReturn(expectedSessionId); - given(this.mockTemplate.remove(eq(expectedSessionId))).willReturn(mockSession); - - willAnswer(new Answer() { - public Void answer(final InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()) - .isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isSameAs(mockSession); - assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId); - - return null; - } - }).given(this.mockApplicationEventPublisher).publishEvent(isA(SessionDeletedEvent.class)); - - this.sessionRepository.delete(expectedSessionId); - - verify(mockSession, times(1)).getId(); - verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId)); - verify(this.mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDeletedEvent.class)); - } - - @Test - public void deleteRemovesNonExistingSessionAndHandlesDelete() { - final String expectedSessionId = "1"; - - given(this.mockTemplate.remove(anyString())).willReturn(null); - - willAnswer(new Answer() { - public Void answer(final InvocationOnMock invocation) throws Throwable { - ApplicationEvent applicationEvent = invocation.getArgument(0); - - assertThat(applicationEvent).isInstanceOf(SessionDeletedEvent.class); - - AbstractSessionEvent sessionEvent = (AbstractSessionEvent) applicationEvent; - - assertThat(sessionEvent.getSource()). - isSameAs(GemFireOperationsSessionRepositoryTest.this.sessionRepository); - assertThat(sessionEvent.getSession()).isNull(); - assertThat(sessionEvent.getSessionId()).isEqualTo(expectedSessionId); - - return null; - } - }).given(this.mockApplicationEventPublisher).publishEvent(isA(SessionDeletedEvent.class)); - - this.sessionRepository.delete(expectedSessionId); - - verify(this.mockTemplate, times(1)).remove(eq(expectedSessionId)); - verify(this.mockApplicationEventPublisher, times(1)) - .publishEvent(isA(SessionDeletedEvent.class)); - } - - protected abstract class GemfireOperationsAccessor extends GemfireAccessor - implements GemfireOperations { - } -} diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java deleted file mode 100644 index 40c3e84b..00000000 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionConfigurationTest.java +++ /dev/null @@ -1,407 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http; - -import java.lang.reflect.Field; -import java.util.HashMap; -import java.util.Map; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.ExpirationAction; -import org.apache.geode.cache.ExpirationAttributes; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.core.type.AnnotationMetadata; -import org.springframework.data.gemfire.GemfireOperations; -import org.springframework.data.gemfire.GemfireTemplate; -import org.springframework.data.gemfire.RegionAttributesFactoryBean; -import org.springframework.session.ExpiringSession; -import org.springframework.session.data.gemfire.GemFireOperationsSessionRepository; -import org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.eq; -import static org.mockito.BDDMockito.given; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; - -/** - * The GemFireHttpSessionConfigurationTest class is a test suite of test cases testing the - * contract and functionality of the {@link GemFireHttpSessionConfiguration} class. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.mockito.Mockito - * @see org.springframework.data.gemfire.GemfireOperations - * @see org.springframework.data.gemfire.GemfireTemplate - * @see org.springframework.session.data.gemfire.GemFireOperationsSessionRepository - * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.GemFireCache - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.client.ClientCache - */ -public class GemFireHttpSessionConfigurationTest { - - private GemFireHttpSessionConfiguration gemfireConfiguration; - - @SuppressWarnings("unchecked") - protected T getField(Object obj, String fieldName) { - try { - Field field = obj.getClass().getDeclaredField(fieldName); - field.setAccessible(true); - return (T) field.get(obj); - } - catch (NoSuchFieldException e) { - throw new IllegalArgumentException(String.format( - "field with name [%1$s] was not found in class [%2$s]", fieldName, obj), e); - } - catch (IllegalAccessException e) { - throw new Error(String.format("unable to access field [%1$s] on object of type [%2$s]", - fieldName, obj.getClass().getName()), e); - } - } - - protected T[] toArray(T... array) { - return array; - } - - @Before - public void setup() { - this.gemfireConfiguration = new GemFireHttpSessionConfiguration(); - } - - @Test - public void setAndGetBeanClassLoader() { - assertThat(this.gemfireConfiguration.getBeanClassLoader()).isNull(); - - this.gemfireConfiguration.setBeanClassLoader(Thread.currentThread().getContextClassLoader()); - - assertThat(this.gemfireConfiguration.getBeanClassLoader()).isEqualTo( - Thread.currentThread().getContextClassLoader()); - - this.gemfireConfiguration.setBeanClassLoader(null); - - assertThat(this.gemfireConfiguration.getBeanClassLoader()).isNull(); - } - - @Test - public void setAndGetClientRegionShortcut() { - assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT); - - this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); - - assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo( - ClientRegionShortcut.CACHING_PROXY); - - this.gemfireConfiguration.setClientRegionShortcut(null); - - assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_CLIENT_REGION_SHORTCUT); - } - - @Test - public void setAndGetMaxInactiveIntervalInSeconds() { - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_MAX_INACTIVE_INTERVAL_IN_SECONDS); - - this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(300); - - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(300); - - this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(Integer.MAX_VALUE); - - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(Integer.MAX_VALUE); - - this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(-1); - - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(-1); - - this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(Integer.MIN_VALUE); - - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(Integer.MIN_VALUE); - } - - @Test - public void setAndGetPoolName() { - assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); - - this.gemfireConfiguration.setPoolName("TestPoolName"); - - assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo("TestPoolName"); - - this.gemfireConfiguration.setPoolName(" "); - - assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); - - this.gemfireConfiguration.setPoolName(""); - - assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); - - this.gemfireConfiguration.setPoolName(null); - - assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_GEMFIRE_POOL_NAME); - } - - @Test - public void setAndGetServerRegionShortcut() { - assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT); - - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE_PERSISTENT); - - assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo( - RegionShortcut.REPLICATE_PERSISTENT); - - this.gemfireConfiguration.setServerRegionShortcut(null); - - assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SERVER_REGION_SHORTCUT); - } - - @Test - public void setAndGetSpringSessionGemFireRegionName() { - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - - this.gemfireConfiguration.setSpringSessionGemFireRegionName("test"); - - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("test"); - - this.gemfireConfiguration.setSpringSessionGemFireRegionName(" "); - - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - - this.gemfireConfiguration.setSpringSessionGemFireRegionName(""); - - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - - this.gemfireConfiguration.setSpringSessionGemFireRegionName(null); - - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - } - - @Test - public void setsImportMetadata() { - AnnotationMetadata mockAnnotationMetadata = mock(AnnotationMetadata.class); - - Map annotationAttributes = new HashMap(4); - - annotationAttributes.put("clientRegionShortcut", ClientRegionShortcut.CACHING_PROXY); - annotationAttributes.put("indexableSessionAttributes", toArray("one", "two", "three")); - annotationAttributes.put("maxInactiveIntervalInSeconds", 600); - annotationAttributes.put("poolName", "TestPool"); - annotationAttributes.put("serverRegionShortcut", RegionShortcut.REPLICATE); - annotationAttributes.put("regionName", "TEST"); - - given(mockAnnotationMetadata.getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName()))) - .willReturn(annotationAttributes); - - this.gemfireConfiguration.setImportMetadata(mockAnnotationMetadata); - - assertThat(this.gemfireConfiguration.getClientRegionShortcut()).isEqualTo(ClientRegionShortcut.CACHING_PROXY); - assertThat(this.gemfireConfiguration.getIndexableSessionAttributes()).isEqualTo(toArray("one", "two", "three")); - assertThat(this.gemfireConfiguration.getMaxInactiveIntervalInSeconds()).isEqualTo(600); - assertThat(this.gemfireConfiguration.getPoolName()).isEqualTo("TestPool"); - assertThat(this.gemfireConfiguration.getServerRegionShortcut()).isEqualTo(RegionShortcut.REPLICATE); - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("TEST"); - - verify(mockAnnotationMetadata, times(1)).getAnnotationAttributes(eq(EnableGemFireHttpSession.class.getName())); - } - - @Test - public void createsAndInitializesSessionRepositoryBean() { - GemfireOperations mockGemfireOperations = mock(GemfireOperations.class); - - this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(120); - - GemFireOperationsSessionRepository sessionRepository = this.gemfireConfiguration.sessionRepository( - mockGemfireOperations); - - assertThat(sessionRepository).isNotNull(); - assertThat(sessionRepository.getTemplate()).isSameAs(mockGemfireOperations); - assertThat(sessionRepository.getMaxInactiveIntervalInSeconds()).isEqualTo(120); - } - - @Test - @SuppressWarnings("unchecked") - public void createsAndInitializesSessionRegionTemplateBean() { - GemFireCache mockGemFireCache = mock(GemFireCache.class); - Region mockRegion = mock(Region.class); - - given(mockGemFireCache.getRegion(eq("Example"))).willReturn(mockRegion); - - this.gemfireConfiguration.setSpringSessionGemFireRegionName("Example"); - - GemfireTemplate template = this.gemfireConfiguration.sessionRegionTemplate(mockGemFireCache); - - assertThat(this.gemfireConfiguration.getSpringSessionGemFireRegionName()).isEqualTo("Example"); - assertThat(template).isNotNull(); - assertThat(template.getRegion()).isSameAs(mockRegion); - - verify(mockGemFireCache, times(1)).getRegion(eq("Example")); - } - - @Test - @SuppressWarnings("unchecked") - public void createsAndInitializesSessionRegionBean() { - GemFireCache mockGemFireCache = mock(GemFireCache.class); - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); - this.gemfireConfiguration.setPoolName("TestPool"); - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE_PERSISTENT); - this.gemfireConfiguration.setSpringSessionGemFireRegionName("TestRegion"); - - GemFireCacheTypeAwareRegionFactoryBean sessionRegionFactoryBean = - this.gemfireConfiguration.sessionRegion(mockGemFireCache, mockRegionAttributes); - - assertThat(sessionRegionFactoryBean).isNotNull(); - assertThat(this.getField(sessionRegionFactoryBean, "clientRegionShortcut")) - .isEqualTo(ClientRegionShortcut.CACHING_PROXY); - assertThat(this.getField(sessionRegionFactoryBean, "gemfireCache")) - .isEqualTo(mockGemFireCache); - assertThat(this.getField(sessionRegionFactoryBean, "poolName")).isEqualTo("TestPool"); - assertThat(this.>getField(sessionRegionFactoryBean, - "regionAttributes")).isEqualTo(mockRegionAttributes); - assertThat(this.getField(sessionRegionFactoryBean, "regionName")).isEqualTo("TestRegion"); - assertThat(this.getField(sessionRegionFactoryBean, "serverRegionShortcut")) - .isEqualTo(RegionShortcut.REPLICATE_PERSISTENT); - - verifyZeroInteractions(mockGemFireCache); - verifyZeroInteractions(mockRegionAttributes); - } - - @Test - @SuppressWarnings("unchecked") - public void createsAndInitializesSessionRegionAttributesWithExpiration() throws Exception { - Cache mockCache = mock(Cache.class); - - this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(300); - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.LOCAL); - - RegionAttributesFactoryBean regionAttributesFactory = - this.gemfireConfiguration.sessionRegionAttributes(mockCache); - - assertThat(regionAttributesFactory).isNotNull(); - - regionAttributesFactory.afterPropertiesSet(); - - RegionAttributes sessionRegionAttributes = regionAttributesFactory.getObject(); - - assertThat(sessionRegionAttributes).isNotNull(); - assertThat(sessionRegionAttributes.getKeyConstraint()).isEqualTo( - GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT); - assertThat(sessionRegionAttributes.getValueConstraint()).isEqualTo( - GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT); - - ExpirationAttributes entryIdleTimeoutExpiration = sessionRegionAttributes.getEntryIdleTimeout(); - - assertThat(entryIdleTimeoutExpiration).isNotNull(); - assertThat(entryIdleTimeoutExpiration.getAction()).isEqualTo(ExpirationAction.INVALIDATE); - assertThat(entryIdleTimeoutExpiration.getTimeout()).isEqualTo(300); - } - - @Test - @SuppressWarnings("unchecked") - public void createsAndInitializesSessionRegionAttributesWithoutExpiration() throws Exception { - ClientCache mockClientCache = mock(ClientCache.class); - - this.gemfireConfiguration.setMaxInactiveIntervalInSeconds(300); - - RegionAttributesFactoryBean regionAttributesFactory = - this.gemfireConfiguration.sessionRegionAttributes(mockClientCache); - - assertThat(regionAttributesFactory).isNotNull(); - - regionAttributesFactory.afterPropertiesSet(); - - RegionAttributes sessionRegionAttributes = regionAttributesFactory.getObject(); - - assertThat(sessionRegionAttributes).isNotNull(); - assertThat(sessionRegionAttributes.getKeyConstraint()).isEqualTo( - GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_KEY_CONSTRAINT); - assertThat(sessionRegionAttributes.getValueConstraint()).isEqualTo( - GemFireHttpSessionConfiguration.SPRING_SESSION_GEMFIRE_REGION_VALUE_CONSTRAINT); - - ExpirationAttributes entryIdleTimeoutExpiration = sessionRegionAttributes.getEntryIdleTimeout(); - - assertThat(entryIdleTimeoutExpiration).isNotNull(); - assertThat(entryIdleTimeoutExpiration.getAction()).isEqualTo(ExpirationAction.INVALIDATE); - assertThat(entryIdleTimeoutExpiration.getTimeout()).isEqualTo(0); - } - - @Test - public void expirationIsAllowed() { - Cache mockCache = mock(Cache.class); - - ClientCache mockClientCache = mock(ClientCache.class); - - this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.PROXY); - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE); - - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockCache)).isTrue(); - - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW); - - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockCache)).isTrue(); - - this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.CACHING_PROXY); - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION_PROXY); - - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)).isTrue(); - - this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW); - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.REPLICATE_PROXY); - - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)).isTrue(); - } - - @Test - public void expirationIsNotAllowed() { - Cache mockCache = mock(Cache.class); - ClientCache mockClientCache = mock(ClientCache.class); - - this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.PROXY); - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION); - - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockClientCache)).isFalse(); - - this.gemfireConfiguration.setClientRegionShortcut(ClientRegionShortcut.LOCAL); - this.gemfireConfiguration.setServerRegionShortcut(RegionShortcut.PARTITION_PROXY); - - assertThat(this.gemfireConfiguration.isExpirationAllowed(mockCache)).isFalse(); - } -} diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java deleted file mode 100644 index fd24f6c9..00000000 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/GemFireCacheTypeAwareRegionFactoryBeanTest.java +++ /dev/null @@ -1,295 +0,0 @@ -/* - * Copyright 2014-2017 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http.support; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.InterestResultPolicy; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientRegionShortcut; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.data.gemfire.client.Interest; -import org.springframework.session.ExpiringSession; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * The GemFireCacheTypeAwareRegionFactoryBeanTest class is a test suite of test cases - * testing the contract and functionality of the GemFireCacheTypeAwareRegionFactoryBean - * class. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Rule - * @see org.junit.Test - * @see org.junit.rules.ExpectedException - * @see org.mockito.Mockito - * @see org.springframework.session.data.gemfire.config.annotation.web.http.support.GemFireCacheTypeAwareRegionFactoryBean - * @see org.apache.geode.cache.Cache - * @see org.apache.geode.cache.GemFireCache - * @see org.apache.geode.cache.InterestResultPolicy - * @see org.apache.geode.cache.Region - * @see org.apache.geode.cache.RegionAttributes - * @see org.apache.geode.cache.RegionShortcut - * @see org.apache.geode.cache.client.ClientCache - * @see org.apache.geode.cache.client.ClientRegionShortcut - */ -@RunWith(MockitoJUnitRunner.class) -public class GemFireCacheTypeAwareRegionFactoryBeanTest { - - @Rule - public ExpectedException exception = ExpectedException.none(); - - @Mock - Cache mockCache; - - @Mock - ClientCache mockClientCache; - - @Mock - Region mockClientRegion; - - @Mock - Region mockServerRegion; - - private GemFireCacheTypeAwareRegionFactoryBean regionFactoryBean; - - @Before - public void setup() { - this.regionFactoryBean = new GemFireCacheTypeAwareRegionFactoryBean(); - } - - protected void afterPropertiesSetCreatesCorrectRegionForGemFireCacheType(final GemFireCache expectedCache, - Region expectedRegion) throws Exception { - - this.regionFactoryBean = new GemFireCacheTypeAwareRegionFactoryBean() { - @Override - protected Region newClientRegion(GemFireCache gemfireCache) throws Exception { - assertThat(gemfireCache).isSameAs(expectedCache); - return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockClientRegion; - } - - @Override - protected Region newServerRegion(GemFireCache gemfireCache) throws Exception { - assertThat(gemfireCache).isSameAs(expectedCache); - return GemFireCacheTypeAwareRegionFactoryBeanTest.this.mockServerRegion; - } - }; - - this.regionFactoryBean.setGemfireCache(expectedCache); - this.regionFactoryBean.afterPropertiesSet(); - - assertThat(this.regionFactoryBean.getGemfireCache()).isSameAs(expectedCache); - assertThat(this.regionFactoryBean.getObject()).isEqualTo(expectedRegion); - assertThat(this.regionFactoryBean.getObjectType()).isEqualTo(expectedRegion.getClass()); - } - - @Test - public void afterPropertiesSetCreatesClientRegionForClientCache() throws Exception { - afterPropertiesSetCreatesCorrectRegionForGemFireCacheType(this.mockClientCache, this.mockClientRegion); - } - - @Test - public void afterPropertiesSetCreatesServerRegionForPeerCache() throws Exception { - afterPropertiesSetCreatesCorrectRegionForGemFireCacheType(this.mockCache, this.mockServerRegion); - } - - @Test - public void allKeysInterestsRegistration() { - Interest[] interests = this.regionFactoryBean.registerInterests(true); - - assertThat(interests).isNotNull(); - assertThat(interests.length).isEqualTo(1); - assertThat(interests[0].isDurable()).isFalse(); - assertThat(interests[0].getKey().toString()).isEqualTo("ALL_KEYS"); - assertThat(interests[0].getPolicy()).isEqualTo(InterestResultPolicy.KEYS); - assertThat(interests[0].isReceiveValues()).isTrue(); - } - - @Test - public void emptyInterestsRegistration() { - Interest[] interests = this.regionFactoryBean.registerInterests(false); - - assertThat(interests).isNotNull(); - assertThat(interests.length).isEqualTo(0); - } - - @Test - public void getObjectTypeBeforeInitializationIsRegionClass() { - assertThat(this.regionFactoryBean.getObjectType()).isEqualTo(Region.class); - } - - @Test - public void isSingletonIsTrue() { - assertThat(this.regionFactoryBean.isSingleton()).isTrue(); - } - - @Test - public void setAndGetBeanFactory() { - BeanFactory mockBeanFactory = mock(BeanFactory.class); - - this.regionFactoryBean.setBeanFactory(mockBeanFactory); - - assertThat(this.regionFactoryBean.getBeanFactory()).isEqualTo(mockBeanFactory); - } - - @Test - public void setBeanFactoryToNullThrowsIllegalArgumentException() { - this.exception.expect(IllegalArgumentException.class); - this.exception.expectMessage("BeanFactory must not be null"); - this.regionFactoryBean.setBeanFactory(null); - } - - @Test - public void getBeanFactoryWhenNullThrowsIllegalStateException() { - this.exception.expect(IllegalStateException.class); - this.exception.expectMessage("A reference to the BeanFactory was not properly configured"); - this.regionFactoryBean.getBeanFactory(); - } - - @Test - public void setAndGetClientRegionShortcut() { - assertThat(this.regionFactoryBean.getClientRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_CLIENT_REGION_SHORTCUT); - - this.regionFactoryBean.setClientRegionShortcut(ClientRegionShortcut.LOCAL_PERSISTENT); - - assertThat(this.regionFactoryBean.getClientRegionShortcut()).isEqualTo( - ClientRegionShortcut.LOCAL_PERSISTENT); - - this.regionFactoryBean.setClientRegionShortcut(null); - - assertThat(this.regionFactoryBean.getClientRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_CLIENT_REGION_SHORTCUT); - } - - @Test - public void setAndGetGemfireCache() { - Cache mockCache = mock(Cache.class); - - this.regionFactoryBean.setGemfireCache(mockCache); - - assertThat(this.regionFactoryBean.getGemfireCache()).isEqualTo(mockCache); - } - - @Test - public void setGemfireCacheToNullThrowsIllegalArgumentException() { - this.exception.expect(IllegalArgumentException.class); - this.exception.expectMessage("GemFireCache must not be null"); - this.regionFactoryBean.setGemfireCache(null); - } - - @Test - public void getGemfireCacheWhenNullThrowsIllegalStateException() { - this.exception.expect(IllegalStateException.class); - this.exception.expectMessage("A reference to the GemFireCache was not properly configured"); - this.regionFactoryBean.getGemfireCache(); - } - - @Test - public void setAndGetPoolName() { - assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); - - this.regionFactoryBean.setPoolName("TestPoolName"); - - assertThat(this.regionFactoryBean.getPoolName()).isEqualTo("TestPoolName"); - - this.regionFactoryBean.setPoolName(" "); - - assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); - - this.regionFactoryBean.setPoolName(""); - - assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); - - this.regionFactoryBean.setPoolName(null); - - assertThat(this.regionFactoryBean.getPoolName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_GEMFIRE_POOL_NAME); - } - - @Test - @SuppressWarnings("unchecked") - public void setAndGetRegionAttributes() { - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - assertThat(this.regionFactoryBean.getRegionAttributes()).isNull(); - - this.regionFactoryBean.setRegionAttributes(mockRegionAttributes); - - assertThat(this.regionFactoryBean.getRegionAttributes()).isSameAs(mockRegionAttributes); - - this.regionFactoryBean.setRegionAttributes(null); - - assertThat(this.regionFactoryBean.getRegionAttributes()).isNull(); - } - - @Test - public void setAndGetRegionName() { - assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - - this.regionFactoryBean.setRegionName("Example"); - - assertThat(this.regionFactoryBean.getRegionName()).isEqualTo("Example"); - - this.regionFactoryBean.setRegionName(" "); - - assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - - this.regionFactoryBean.setRegionName(""); - - assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - - this.regionFactoryBean.setRegionName(null); - - assertThat(this.regionFactoryBean.getRegionName()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SPRING_SESSION_GEMFIRE_REGION_NAME); - } - - @Test - public void setAndGetServerRegionShortcut() { - assertThat(this.regionFactoryBean.getServerRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SERVER_REGION_SHORTCUT); - - this.regionFactoryBean.setServerRegionShortcut(RegionShortcut.LOCAL_PERSISTENT); - - assertThat(this.regionFactoryBean.getServerRegionShortcut()).isEqualTo(RegionShortcut.LOCAL_PERSISTENT); - - this.regionFactoryBean.setServerRegionShortcut(null); - - assertThat(this.regionFactoryBean.getServerRegionShortcut()).isEqualTo( - GemFireCacheTypeAwareRegionFactoryBean.DEFAULT_SERVER_REGION_SHORTCUT); - } -} diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBeanTests.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBeanTests.java deleted file mode 100644 index d0e767f6..00000000 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/config/annotation/web/http/support/SessionAttributesIndexFactoryBeanTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.config.annotation.web.http.support; - -import org.apache.geode.cache.query.Index; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Test suite of test cases testing the contract and functionality - * of the {@link SessionAttributesIndexFactoryBean} class. - * - * @author John Blum - * @since 1.3.0 - * @see org.junit.Test - * @see org.mockito.Mockito - * @see org.springframework.session.data.gemfire.config.annotation.web.http.support.SessionAttributesIndexFactoryBean - */ -public class SessionAttributesIndexFactoryBeanTests { - - static T[] toArray(T... array) { - return array; - } - - private SessionAttributesIndexFactoryBean indexFactoryBean; - - @Before - public void setup() { - this.indexFactoryBean = new SessionAttributesIndexFactoryBean(); - } - - @Test - public void indexIsNotInitializedWhenNoIndexableSessionAttributesAreConfigured() throws Exception { - final Index mockIndex = mock(Index.class); - - SessionAttributesIndexFactoryBean indexFactoryBean = new SessionAttributesIndexFactoryBean() { - @Override - protected Index newIndex() throws Exception { - return mockIndex; - } - }; - - indexFactoryBean.afterPropertiesSet(); - - assertThat(indexFactoryBean.getObject()).isNull(); - assertThat(indexFactoryBean.getObjectType()).isEqualTo(Index.class); - } - - @Test - public void initializesIndexWhenIndexableSessionAttributesAreConfigured() throws Exception { - final Index mockIndex = mock(Index.class); - - SessionAttributesIndexFactoryBean indexFactoryBean = new SessionAttributesIndexFactoryBean() { - @Override - protected Index newIndex() throws Exception { - return mockIndex; - } - }; - - indexFactoryBean.setIndexableSessionAttributes(toArray("one", "two")); - indexFactoryBean.afterPropertiesSet(); - - assertThat(indexFactoryBean.getObject()).isEqualTo(mockIndex); - assertThat(indexFactoryBean.getObjectType()).isEqualTo(mockIndex.getClass()); - } - - @Test - public void isSingletonIsTrue() { - assertThat(this.indexFactoryBean.isSingleton()).isTrue(); - } - - @Test - public void setAndGetIndexableSessionAttributes() { - assertThat(this.indexFactoryBean.getIndexableSessionAttributes()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); - - assertThat(this.indexFactoryBean.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo("*"); - - this.indexFactoryBean.setIndexableSessionAttributes(toArray("one", "two", "three")); - - assertThat(this.indexFactoryBean.getIndexableSessionAttributes()).isEqualTo( - toArray("one", "two", "three")); - - assertThat(this.indexFactoryBean.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo( - "'one', 'two', 'three'"); - - this.indexFactoryBean.setIndexableSessionAttributes(toArray("one")); - - assertThat(this.indexFactoryBean.getIndexableSessionAttributes()).isEqualTo(toArray("one")); - assertThat(this.indexFactoryBean.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo("'one'"); - - this.indexFactoryBean.setIndexableSessionAttributes(null); - - assertThat(this.indexFactoryBean.getIndexableSessionAttributes()).isEqualTo( - GemFireHttpSessionConfiguration.DEFAULT_INDEXABLE_SESSION_ATTRIBUTES); - - assertThat(this.indexFactoryBean.getIndexableSessionAttributesAsGemFireIndexExpression()).isEqualTo("*"); - } - - @Test - public void setAndGetRegionName() { - assertThat(this.indexFactoryBean.getRegionName()).isNull(); - - this.indexFactoryBean.setRegionName("Example"); - - assertThat(this.indexFactoryBean.getRegionName()).isEqualTo("Example"); - - this.indexFactoryBean.setRegionName(null); - - assertThat(this.indexFactoryBean.getRegionName()).isNull(); - } -} diff --git a/spring-session/src/test/java/org/springframework/session/data/gemfire/support/GemFireUtilsTest.java b/spring-session/src/test/java/org/springframework/session/data/gemfire/support/GemFireUtilsTest.java deleted file mode 100644 index 3b28d725..00000000 --- a/spring-session/src/test/java/org/springframework/session/data/gemfire/support/GemFireUtilsTest.java +++ /dev/null @@ -1,203 +0,0 @@ -/* - * Copyright 2014-2016 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.session.data.gemfire.support; - -import java.io.Closeable; -import java.io.IOException; - -import org.apache.geode.cache.Cache; -import org.apache.geode.cache.DataPolicy; -import org.apache.geode.cache.GemFireCache; -import org.apache.geode.cache.Region; -import org.apache.geode.cache.RegionAttributes; -import org.apache.geode.cache.RegionShortcut; -import org.apache.geode.cache.client.ClientCache; -import org.apache.geode.cache.client.ClientRegionShortcut; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.BDDMockito.given; -import static org.mockito.BDDMockito.willThrow; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -/** - * The GemFireUtilsTest class is a test suite of test cases testing the contract and - * functionality of the GemFireUtils utility class. - * - * @author John Blum - * @since 1.1.0 - * @see org.junit.Test - * @see org.mockito.Mockito - * @see org.springframework.session.data.gemfire.support.GemFireUtils - */ -public class GemFireUtilsTest { - - @Test - public void closeNonNullCloseableSuccessfullyReturnsTrue() throws IOException { - Closeable mockCloseable = mock(Closeable.class); - assertThat(GemFireUtils.close(mockCloseable)).isTrue(); - verify(mockCloseable, times(1)).close(); - } - - @Test - public void closeNonNullCloseableObjectThrowingIOExceptionReturnsFalse() throws IOException { - Closeable mockCloseable = mock(Closeable.class); - willThrow(new IOException("test")).given(mockCloseable).close(); - assertThat(GemFireUtils.close(mockCloseable)).isFalse(); - verify(mockCloseable, times(1)).close(); - } - - @Test - public void closeNullCloseableObjectReturnsFalse() { - assertThat(GemFireUtils.close(null)).isFalse(); - } - - @Test - public void clientCacheIsClient() { - assertThat(GemFireUtils.isClient(mock(ClientCache.class))).isTrue(); - } - - @Test - public void genericCacheIsNotClient() { - assertThat(GemFireUtils.isClient(mock(GemFireCache.class))).isFalse(); - } - - @Test - public void peerCacheIsNotClient() { - assertThat(GemFireUtils.isClient(mock(Cache.class))).isFalse(); - } - - @Test - public void peerCacheIsPeer() { - assertThat(GemFireUtils.isPeer(mock(Cache.class))).isTrue(); - } - - @Test - public void genericCacheIsNotPeer() { - assertThat(GemFireUtils.isPeer(mock(GemFireCache.class))).isFalse(); - } - - @Test - public void clientCacheIsNotPeer() { - assertThat(GemFireUtils.isPeer(mock(ClientCache.class))).isFalse(); - } - - @Test - public void clientRegionShortcutIsLocal() { - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL)).isTrue(); - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_HEAP_LRU)).isTrue(); - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_OVERFLOW)).isTrue(); - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_PERSISTENT)).isTrue(); - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW)).isTrue(); - } - - @Test - public void clientRegionShortcutIsNotLocal() { - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY)).isFalse(); - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU)).isFalse(); - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.CACHING_PROXY_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isLocal(ClientRegionShortcut.PROXY)).isFalse(); - } - - @Test - public void clientRegionShortcutIsProxy() { - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.PROXY)).isTrue(); - } - - @Test - public void clientRegionShortcutIsNotProxy() { - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY)).isFalse(); - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY_HEAP_LRU)).isFalse(); - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.CACHING_PROXY_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL)).isFalse(); - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_HEAP_LRU)).isFalse(); - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_PERSISTENT)).isFalse(); - assertThat(GemFireUtils.isProxy(ClientRegionShortcut.LOCAL_PERSISTENT_OVERFLOW)).isFalse(); - } - - @Test - public void regionShortcutIsProxy() { - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PROXY)).isTrue(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PROXY_REDUNDANT)).isTrue(); - assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_PROXY)).isTrue(); - } - - @Test - public void regionIsProxy() { - Region mockRegion = mock(Region.class); - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - given(mockRegion.getAttributes()).willReturn(mockRegionAttributes); - given(mockRegionAttributes.getDataPolicy()).willReturn(DataPolicy.EMPTY); - - assertThat(GemFireUtils.isProxy(mockRegion)).isTrue(); - - verify(mockRegion, times(1)).getAttributes(); - verify(mockRegionAttributes, times(1)).getDataPolicy(); - } - - @Test - public void regionIsNotProxy() { - Region mockRegion = mock(Region.class); - RegionAttributes mockRegionAttributes = mock(RegionAttributes.class); - - given(mockRegion.getAttributes()).willReturn(mockRegionAttributes); - given(mockRegionAttributes.getDataPolicy()).willReturn(DataPolicy.NORMAL); - - assertThat(GemFireUtils.isProxy(mockRegion)).isFalse(); - - verify(mockRegion, times(1)).getAttributes(); - verify(mockRegionAttributes, times(1)).getDataPolicy(); - } - - @Test - public void regionShortcutIsNotProxy() { - assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_HEAP_LRU)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_PERSISTENT)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.LOCAL_PERSISTENT_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_HEAP_LRU)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_PERSISTENT)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.REPLICATE_PERSISTENT_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_HEAP_LRU)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PERSISTENT)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_PERSISTENT_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_HEAP_LRU)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_OVERFLOW)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT)).isFalse(); - assertThat(GemFireUtils.isProxy(RegionShortcut.PARTITION_REDUNDANT_PERSISTENT_OVERFLOW)).isFalse(); - } - - @Test - public void toRegionPath() { - assertThat(GemFireUtils.toRegionPath("A")).isEqualTo("/A"); - assertThat(GemFireUtils.toRegionPath("Example")).isEqualTo("/Example"); - assertThat(GemFireUtils.toRegionPath("/Example")).isEqualTo("//Example"); - assertThat(GemFireUtils.toRegionPath("/")).isEqualTo("//"); - assertThat(GemFireUtils.toRegionPath("")).isEqualTo("/"); - } -} diff --git a/spring-session/src/test/resources/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests-context.xml b/spring-session/src/test/resources/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests-context.xml deleted file mode 100644 index 6ccf8742..00000000 --- a/spring-session/src/test/resources/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests-context.xml +++ /dev/null @@ -1,26 +0,0 @@ - - - - - GemFireHttpSessionXmlConfigurationTests - 0 - warning - - - - - - -