├── samples ├── xml │ ├── gemfire-p2p │ │ ├── src │ │ │ ├── main │ │ │ │ ├── webapp │ │ │ │ │ ├── META-INF │ │ │ │ │ │ └── MANIFEST.MF │ │ │ │ │ ├── WEB-INF │ │ │ │ │ │ ├── spring │ │ │ │ │ │ │ └── session.xml │ │ │ │ │ │ └── web.xml │ │ │ │ │ └── index.jsp │ │ │ │ └── java │ │ │ │ │ └── sample │ │ │ │ │ └── SessionServlet.java │ │ │ └── integration-test │ │ │ │ ├── resources │ │ │ │ ├── log4j2-test.xml │ │ │ │ └── logback-test.xml │ │ │ │ └── java │ │ │ │ └── sample │ │ │ │ └── AttributeTests.java │ │ └── spring-session-sample-xml-gemfire-p2p.gradle │ └── gemfire-clientserver │ │ ├── src │ │ ├── main │ │ │ ├── webapp │ │ │ │ ├── META-INF │ │ │ │ │ └── MANIFEST.MF │ │ │ │ ├── index.jsp │ │ │ │ └── WEB-INF │ │ │ │ │ ├── spring │ │ │ │ │ └── session-client.xml │ │ │ │ │ └── web.xml │ │ │ ├── java │ │ │ │ └── sample │ │ │ │ │ ├── server │ │ │ │ │ └── GemFireServer.java │ │ │ │ │ └── client │ │ │ │ │ ├── SessionServlet.java │ │ │ │ │ ├── ClientServerReadyBeanPostProcessor.java │ │ │ │ │ └── ApacheGeodeServerWebApplicationInitializer.java │ │ │ └── resources │ │ │ │ └── META-INF │ │ │ │ └── spring │ │ │ │ └── session-server.xml │ │ └── integration-test │ │ │ ├── resources │ │ │ ├── log4j2-test.xml │ │ │ └── logback-test.xml │ │ │ └── java │ │ │ └── sample │ │ │ └── AttributeTests.java │ │ └── spring-session-sample-xml-gemfire-clientserver.gradle ├── javaconfig │ ├── gemfire-p2p │ │ ├── src │ │ │ ├── main │ │ │ │ ├── webapp │ │ │ │ │ ├── META-INF │ │ │ │ │ │ └── MANIFEST.MF │ │ │ │ │ └── index.jsp │ │ │ │ └── java │ │ │ │ │ └── sample │ │ │ │ │ ├── Initializer.java │ │ │ │ │ ├── Config.java │ │ │ │ │ └── SessionServlet.java │ │ │ └── integration-test │ │ │ │ ├── resources │ │ │ │ ├── log4j2-test.xml │ │ │ │ └── logback-test.xml │ │ │ │ └── java │ │ │ │ └── sample │ │ │ │ └── AttributeTests.java │ │ └── spring-session-sample-javaconfig-gemfire-p2p.gradle │ └── gemfire-clientserver │ │ ├── src │ │ ├── main │ │ │ ├── webapp │ │ │ │ ├── META-INF │ │ │ │ │ └── MANIFEST.MF │ │ │ │ └── index.jsp │ │ │ └── java │ │ │ │ └── sample │ │ │ │ ├── server │ │ │ │ └── GemFireServer.java │ │ │ │ └── client │ │ │ │ ├── SessionServlet.java │ │ │ │ └── ClientConfig.java │ │ └── integration-test │ │ │ ├── resources │ │ │ ├── log4j2-test.xml │ │ │ └── logback-test.xml │ │ │ └── java │ │ │ └── sample │ │ │ └── AttributeTests.java │ │ └── spring-session-sample-javaconfig-gemfire-clientserver.gradle └── boot │ ├── gemfire │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ ├── application.properties │ │ │ │ └── templates │ │ │ │ │ └── index.ftlh │ │ │ └── java │ │ │ │ └── sample │ │ │ │ └── server │ │ │ │ └── GemFireServer.java │ │ └── integration-test │ │ │ ├── resources │ │ │ ├── logback-test.xml │ │ │ └── log4j2-test.xml │ │ │ └── java │ │ │ └── sample │ │ │ └── AttributeTests.java │ └── spring-session-sample-boot-gemfire.gradle │ ├── gemfire-with-gfsh-servers │ ├── src │ │ └── main │ │ │ └── resources │ │ │ ├── geode │ │ │ ├── bin │ │ │ │ ├── stop-cluster.gfsh │ │ │ │ ├── stop-cluster.sh │ │ │ │ └── start-cluster.sh │ │ │ └── oql │ │ │ │ └── queries.txt │ │ │ ├── initializer-cache.xml │ │ │ └── templates │ │ │ └── index.ftlh │ └── spring-session-sample-boot-gemfire-with-gfsh-servers.gradle │ └── gemfire-with-scoped-proxies │ ├── src │ └── main │ │ ├── resources │ │ └── templates │ │ │ └── index.ftlh │ │ └── java │ │ └── sample │ │ ├── client │ │ └── model │ │ │ ├── RequestScopedProxyBean.java │ │ │ └── SessionScopedProxyBean.java │ │ └── server │ │ └── GemFireServer.java │ └── spring-session-sample-boot-gemfire-with-scoped-proxies.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── spring-session-data-geode ├── lombok.config ├── src │ ├── test │ │ ├── resources │ │ │ ├── test-spring-session.properties │ │ │ ├── log4j2-test.xml │ │ │ ├── logback-test.xml │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── session │ │ │ │ └── data │ │ │ │ └── gemfire │ │ │ │ └── config │ │ │ │ └── annotation │ │ │ │ └── web │ │ │ │ └── http │ │ │ │ └── GemFireHttpSessionXmlConfigurationTests-context.xml │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── session │ │ │ └── data │ │ │ └── gemfire │ │ │ ├── support │ │ │ ├── IdentityEqualsDirtyPredicateUnitTests.java │ │ │ ├── SessionUtilsUnitTests.java │ │ │ ├── EqualsDirtyPredicateUnitTests.java │ │ │ ├── DeltaAwareDirtyPredicateUnitTests.java │ │ │ └── SessionIdHolderTests.java │ │ │ ├── events │ │ │ └── SessionChangedEventUnitTests.java │ │ │ ├── expiration │ │ │ ├── SessionExpirationPolicyUnitTests.java │ │ │ └── config │ │ │ │ └── FixedDurationExpirationSessionRepositoryBeanPostProcessorUnitTests.java │ │ │ ├── AbstractGemFireUnitTests.java │ │ │ ├── serialization │ │ │ └── SessionSerializerTests.java │ │ │ └── config │ │ │ └── CustomCookieSerializerConfigurationUnitTests.java │ ├── integration-test │ │ ├── resources │ │ │ ├── logback-test.xml │ │ │ └── log4j2-test.xml │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── session │ │ │ └── data │ │ │ └── gemfire │ │ │ ├── serialization │ │ │ ├── DataSerializationConfigurationIntegrationTests.java │ │ │ └── PdxSerializationConfigurationIntegrationTests.java │ │ │ └── ConcurrentSessionOperationsUsingClientProxyRegionIntegrationTests.java │ └── main │ │ └── java │ │ └── org │ │ └── springframework │ │ └── session │ │ └── data │ │ └── gemfire │ │ ├── support │ │ ├── SessionUtils.java │ │ ├── IdentityEqualsDirtyPredicate.java │ │ ├── EqualsDirtyPredicate.java │ │ ├── DeltaAwareDirtyPredicate.java │ │ ├── AbstractSession.java │ │ ├── GemFireOperationsSessionRepositorySupport.java │ │ ├── IsDirtyPredicate.java │ │ └── SessionIdHolder.java │ │ ├── expiration │ │ ├── config │ │ │ ├── SessionExpirationTimeoutAware.java │ │ │ ├── SessionExpirationTimeoutAwareBeanPostProcessor.java │ │ │ └── FixedDurationExpirationSessionRepositoryBeanPostProcessor.java │ │ └── support │ │ │ └── FixedTimeoutSessionExpirationPolicy.java │ │ ├── web │ │ └── http │ │ │ ├── AbstractCookieSerializer.java │ │ │ └── AbstractHttpSessionIdResolver.java │ │ ├── events │ │ └── SessionChangedEvent.java │ │ └── serialization │ │ ├── data │ │ └── support │ │ │ └── WirableDataSerializer.java │ │ ├── SessionSerializer.java │ │ ├── pdx │ │ ├── AbstractPdxSerializableSessionSerializer.java │ │ └── support │ │ │ ├── PdxSerializerSessionSerializerAdapter.java │ │ │ └── ComposablePdxSerializer.java │ │ └── SerializationException.java └── spring-session-data-geode.gradle ├── docs ├── src │ ├── docs │ │ └── asciidoc │ │ │ └── guides │ │ │ ├── docinfo-footer.html │ │ │ ├── images │ │ │ ├── sample-boot-gemfire-with-gfsh-servers.png │ │ │ └── sample-boot-gemfire-with-scoped-proxies.png │ │ │ └── gfsh.adoc │ └── integration-test │ │ ├── resources │ │ ├── logback-test.xml │ │ └── log4j2-test.xml │ │ └── java │ │ └── docs │ │ └── gemfire │ │ └── indexing │ │ └── HttpSessionGemFireCustomIndexingIntegrationTests.java └── spring-session-docs.gradle ├── ci ├── cleanupArtifacts.sh ├── check.sh ├── installGit.sh ├── cleanupGemFiles.sh ├── setup.sh ├── deployDocs.sh ├── pipeline.properties └── deployArtifacts.sh ├── .gitignore ├── gradle.properties ├── settings.gradle ├── CONTRIBUTING.adoc ├── etc └── build-notes.adoc └── gradlew.bat /samples/xml/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/main/webapp/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-session-data-geode/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /samples/boot/gemfire/src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | #server.error.whitelabel.enabled=false 2 | #spring.thymeleaf.prefix=classpath*:/templates/ 3 | -------------------------------------------------------------------------------- /spring-session-data-geode/lombok.config: -------------------------------------------------------------------------------- 1 | # This file is generated by the 'io.freefair.lombok' Gradle plugin 2 | config.stopBubbling = true 3 | lombok.addLombokGeneratedAnnotation = true 4 | -------------------------------------------------------------------------------- /docs/src/docs/asciidoc/guides/docinfo-footer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /ci/cleanupArtifacts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | rm -Rf ./.gradle 4 | rm -Rf ./.m2 5 | rm -Rf `find . -name "build" | grep -v "src"` 6 | rm -Rf `find . -name "target" | grep -v "src"` 7 | exit 0 8 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-gfsh-servers/src/main/resources/geode/bin/stop-cluster.gfsh: -------------------------------------------------------------------------------- 1 | #!$GEODE_HOME/bin/gfsh 2 | 3 | stop server --name=Server2 4 | stop server --name=Server1 5 | stop locator --name=Locator1 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .checkstyle 2 | .gradle 3 | .idea 4 | .iml 5 | .ipr 6 | .iws 7 | deps.txt 8 | build 9 | buildSrc/.gradle 10 | buildSrc/build 11 | docs/build 12 | out 13 | spring-session-data-geode/build 14 | target 15 | -------------------------------------------------------------------------------- /docs/src/docs/asciidoc/guides/images/sample-boot-gemfire-with-gfsh-servers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-session-data-geode/HEAD/docs/src/docs/asciidoc/guides/images/sample-boot-gemfire-with-gfsh-servers.png -------------------------------------------------------------------------------- /docs/src/docs/asciidoc/guides/images/sample-boot-gemfire-with-scoped-proxies.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-projects/spring-session-data-geode/HEAD/docs/src/docs/asciidoc/guides/images/sample-boot-gemfire-with-scoped-proxies.png -------------------------------------------------------------------------------- /samples/boot/gemfire-with-gfsh-servers/src/main/resources/geode/bin/stop-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gfsh -e "run --file=${SYS_USER_HOME}/spring-session-data-geode/samples/boot/gemfire-with-gfsh-servers/src/main/resources/geode/bin/stop-cluster.gfsh" 4 | -------------------------------------------------------------------------------- /ci/check.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | set -eou pipefail 4 | 5 | ./gradlew --no-daemon clean 6 | 7 | GRADLE_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home -Djava.io.tmpdir=/tmp" \ 8 | ./gradlew check --no-daemon --refresh-dependencies --stacktrace 9 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-gfsh-servers/src/main/resources/geode/bin/start-cluster.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | gfsh -e "run --file=${SYS_USER_HOME}/spring-session-data-geode/samples/boot/gemfire-with-gfsh-servers/src/main/resources/geode/bin/start-cluster.gfsh" 4 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Wed Nov 20 13:07:11 PST 2019 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-bin.zip 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-gfsh-servers/src/main/resources/geode/oql/queries.txt: -------------------------------------------------------------------------------- 1 | # tag::queries[] 2 | SELECT session.id FROM /Sessions session 3 | SELECT session.getClass().getName() FROM /Sessions session 4 | SELECT attributes.key, attributes.value FROM /Sessions session, session.attributes attributes 5 | # end::queries[] 6 | -------------------------------------------------------------------------------- /ci/installGit.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | which git 4 | git --version 2>1 /dev/null 5 | 6 | gitVersionCommandReturnValue=$? 7 | 8 | if test "$gitVersionCommandReturnValue" != 0 9 | then 10 | echo "Installing Git..." 11 | apt-get -y update 12 | apt-get -y install git 13 | which git 14 | git --version 15 | fi 16 | -------------------------------------------------------------------------------- /ci/cleanupGemFiles.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | rm -Rf `find . -name "BACKUPDEFAULT*"` 4 | rm -Rf `find . -name "ConfigDiskDir*"` 5 | rm -Rf `find . -name "locator*" | grep -v "src" | grep -v "locator-application"` 6 | rm -Rf `find . -name "newDB"` 7 | rm -Rf `find . -name "server" | grep -v "src"` 8 | rm -Rf `find . -name "*.log"` 9 | exit 0 10 | -------------------------------------------------------------------------------- /ci/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | # User ID 1001 is "jenkins" 4 | # Group ID 1001 is "jenkins" 5 | # Syntax: `chown -R userId:groupId .` 6 | 7 | echo "Logged into Jenkins CI as user [$USER] with home directory [$HOME] in the current working directory [$PWD]" 8 | chown -R 1001:1001 . 9 | #echo "Logging into Docker..." 10 | #docker login --username ${DOCKER_HUB_USR} --password ${DOCKER_HUB_PSW} 11 | source ci/installGit.sh 12 | exit 0 13 | -------------------------------------------------------------------------------- /ci/deployDocs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | set -eou pipefail 4 | 5 | echo "Deploying docs on host [$HOSTNAME]" 6 | 7 | # User ID 1001 is "jenkins" 8 | # Group ID 1001 is "jenkins" 9 | # Syntax: `chown -R userId:groupId .` 10 | chown -R 1001:1001 . 11 | 12 | GRADLE_OPTS="--add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/sun.nio.ch=ALL-UNNAMED -Duser.name=jenkins -Duser.home=/tmp/jenkins-home -Djava.io.tmpdir=/tmp" \ 13 | ./gradlew deployDocs --no-daemon --stacktrace \ 14 | -PdeployDocsSshKeyPath=$DEPLOY_SSH_KEY \ 15 | -PdeployDocsSshUsername=$SPRING_DOCS_USERNAME 16 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx2g -Dfile.encoding=UTF-8 2 | systemProp.user.name=jblum 3 | antlrVersion=2.7.7 4 | apacheGeodeVersion=1.15.1 5 | micrometerVersion=1.10.12 6 | springVersion=6.0.13 7 | ## NOTE: Spring Boot 3.0.0-M2+ requires Gradle 7.4+ which breaks the GemFireServer Gradle Plugin! Fix! 8 | springBootVersion=3.0.12 9 | springDataBomVersion=2022.0.11 10 | springDataCommonsVersion=3.0.11 11 | springDataGeodeVersion=3.0.0-M6 12 | springDataGeodeTestVersion=1.0.0-M7 13 | springSessionVersion=3.0.5-SNAPSHOT 14 | springSessionBomVersion=3.0.4 15 | version=3.0.0-SNAPSHOT 16 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-gfsh-servers/src/main/resources/initializer-cache.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | org.springframework.session.data.gemfire.serialization.data.support.DataSerializableSessionSerializerInitializer 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /ci/pipeline.properties: -------------------------------------------------------------------------------- 1 | # Java (JDK) versions 2 | java.main.tag=17.0.8_7-jdk-focal 3 | 4 | # Docker Container Images 5 | docker.container.image.java.main=harbor-repo.vmware.com/dockerhub-proxy-cache/library/eclipse-temurin:${java.main.tag} 6 | 7 | # Docker Environment Settings 8 | docker.container.inside.env.basic=-u root -v $HOME:/tmp/jenkins-home -v /tmp:/tmp 9 | docker.container.inside.env.full=-u root -v /usr/bin/docker:/usr/bin/docker -v /var/run/docker.sock:/var/run/docker.sock -v /tmp:/tmp -v $HOME:/tmp/jenkins-home 10 | 11 | # Credentials 12 | artifactory.credentials=02bd1690-b54f-4c9f-819d-a77cb7a9822c 13 | docker.credentials=hub.docker.com-springbuildmaster 14 | docker.registry= 15 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/resources/test-spring-session.properties: -------------------------------------------------------------------------------- 1 | # Test spring-session.properties 2 | 3 | spring.session.data.gemfire.cache.client.pool.name=CarPool 4 | spring.session.data.gemfire.cache.client.region.shortcut=CACHING_PROXY 5 | spring.session.data.gemfire.cache.server.region.shortcut=REPLICATE 6 | spring.session.data.gemfire.session.attributes.indexed=username,userId 7 | spring.session.data.gemfire.session.expiration.bean-name=TestSessionExpirationPolicyBean 8 | spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds=300 9 | spring.session.data.gemfire.session.region.name=TestSessions 10 | spring.session.data.gemfire.session.serializer.bean-name=SessionDataSerializer 11 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/spring-session-sample-xml-gemfire-p2p.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.gretty" version "4.0.3" 3 | id "io.spring.convention.spring-sample-war" 4 | } 5 | 6 | dependencies { 7 | 8 | implementation project(':spring-session-data-geode') 9 | implementation "org.springframework:spring-web" 10 | implementation jstlDependencies 11 | implementation slf4jDependencies 12 | 13 | providedCompile "jakarta.servlet:jakarta.servlet-api" 14 | 15 | runtimeOnly "org.springframework.shell:spring-shell" 16 | 17 | testImplementation "junit:junit" 18 | testImplementation "org.assertj:assertj-core" 19 | 20 | integrationTestCompile seleniumDependencies 21 | 22 | integrationTestRuntime "org.springframework.shell:spring-shell" 23 | 24 | } 25 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/spring-session-sample-javaconfig-gemfire-p2p.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.gretty" version "4.0.3" 3 | id "io.spring.convention.spring-sample-war" 4 | } 5 | 6 | dependencies { 7 | 8 | implementation project(':spring-session-data-geode') 9 | implementation "org.springframework:spring-web" 10 | implementation jstlDependencies 11 | implementation slf4jDependencies 12 | 13 | providedCompile "jakarta.servlet:jakarta.servlet-api" 14 | 15 | runtimeOnly "org.springframework.shell:spring-shell" 16 | 17 | testImplementation "junit:junit" 18 | testImplementation "org.assertj:assertj-core" 19 | 20 | integrationTestCompile seleniumDependencies 21 | 22 | integrationTestRuntime "org.springframework.shell:spring-shell" 23 | 24 | } 25 | -------------------------------------------------------------------------------- /ci/deployArtifacts.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash -x 2 | 3 | set -eou pipefail 4 | 5 | echo "Deploying artifacts on host [$HOSTNAME]" 6 | 7 | # User ID 1001 is "jenkins" 8 | # Group ID 1001 is "jenkins" 9 | # Syntax: `chown -R userId:groupId .` 10 | chown -R 1001:1001 . 11 | 12 | GRADLE_OPTS="-Duser.name=jenkins -Duser.home=/tmp/jenkins-home -Djava.io.tmpdir=/tmp" \ 13 | ./gradlew publishArtifacts releasePublishedArtifacts --no-build-cache --no-configuration-cache --no-daemon --stacktrace \ 14 | -PartifactoryUsername=$ARTIFACTORY_USERNAME \ 15 | -PartifactoryPassword=$ARTIFACTORY_PASSWORD \ 16 | -PossrhUsername=$OSSRH_USERNAME \ 17 | -PossrhPassword=$OSSRH_PASSWORD \ 18 | -Psigning.keyId=$SPRING_SIGNING_KEYID \ 19 | -Psigning.password=$SIGNING_PASSWORD \ 20 | -Psigning.secretKeyRingFile=$SIGNING_KEYRING_FILE 21 | -------------------------------------------------------------------------------- /docs/src/integration-test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /docs/src/integration-test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /samples/boot/gemfire/src/integration-test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /samples/boot/gemfire/src/integration-test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/src/integration-test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/integration-test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/integration-test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/integration-test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/integration-test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/integration-test/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/src/integration-test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/integration-test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/integration-test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/integration-test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | %d %5p %40.40c:%4L - %m%n 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/spring-session-sample-xml-gemfire-clientserver.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.gretty" version "4.0.3" 3 | id "io.spring.convention.spring-sample-war" 4 | } 5 | 6 | // apply plugin: "gemfire-server" 7 | apply plugin: "application" 8 | 9 | dependencies { 10 | 11 | implementation project(':spring-session-data-geode') 12 | implementation "org.springframework:spring-web" 13 | implementation "org.springframework.data:spring-data-geode-test" 14 | implementation jstlDependencies 15 | implementation slf4jDependencies 16 | 17 | providedCompile "jakarta.servlet:jakarta.servlet-api" 18 | 19 | runtimeOnly "org.springframework.shell:spring-shell" 20 | 21 | testImplementation "junit:junit" 22 | testImplementation "org.assertj:assertj-core" 23 | 24 | integrationTestCompile seleniumDependencies 25 | 26 | integrationTestRuntime "org.springframework.shell:spring-shell" 27 | 28 | } 29 | 30 | mainClassName = "sample.server.GemFireServer" 31 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/spring-session-sample-javaconfig-gemfire-clientserver.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "org.gretty" version "4.0.3" 3 | id "io.spring.convention.spring-sample-war" 4 | } 5 | 6 | // apply plugin: "gemfire-server" 7 | apply plugin: "application" 8 | 9 | dependencies { 10 | 11 | implementation project(':spring-session-data-geode') 12 | implementation "io.github.classgraph:classgraph:4.8.149" 13 | implementation "org.springframework:spring-web" 14 | implementation "org.springframework.data:spring-data-geode-test" 15 | implementation jstlDependencies 16 | implementation slf4jDependencies 17 | 18 | providedCompile "jakarta.servlet:jakarta.servlet-api" 19 | 20 | runtimeOnly "org.springframework.shell:spring-shell" 21 | 22 | testImplementation "junit:junit" 23 | testImplementation "org.assertj:assertj-core" 24 | 25 | integrationTestCompile seleniumDependencies 26 | 27 | integrationTestRuntime "org.springframework.shell:spring-shell" 28 | 29 | } 30 | 31 | mainClassName = "sample.server.GemFireServer" 32 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-scoped-proxies/src/main/resources/templates/index.ftlh: -------------------------------------------------------------------------------- 1 | 2 | 3 | Request and Session Counts 4 | 9 | 10 | 11 |
12 |

Description

13 |

14 | This application demonstrates how both Spring 'request' and 'session' scoped (proxy) beans are utilized 15 | in the context of Spring Session when GemFire is used to back the HTTP Session. 16 |

17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | <#attempt> 29 | 30 | 31 | 32 | 33 | 34 | 35 | <#recover> 36 | 37 | 38 |
* Session IDSession CountRequest Count
count${sessionId}${sessionCount}${requestCount}/>
39 |
40 | 41 | 42 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/main/java/sample/Initializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample; 18 | 19 | import org.springframework.session.web.context.AbstractHttpSessionApplicationInitializer; 20 | 21 | // tag::class[] 22 | public class Initializer extends AbstractHttpSessionApplicationInitializer { // <1> 23 | 24 | public Initializer() { 25 | super(Config.class); // <2> 26 | } 27 | } 28 | // end::class[] 29 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/main/java/sample/Config.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample; 18 | 19 | import org.springframework.data.gemfire.config.annotation.PeerCacheApplication; 20 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 21 | 22 | // tag::class[] 23 | @PeerCacheApplication(name = "SpringSessionDataGeodeJavaConfigP2pSample", logLevel = "error") // <1> 24 | @EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) // <2> 25 | public class Config { 26 | 27 | } 28 | // end::class[] 29 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-scoped-proxies/spring-session-sample-boot-gemfire-with-scoped-proxies.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'io.spring.convention.spring-sample-boot' 2 | apply plugin: "application" 3 | 4 | dependencies { 5 | 6 | implementation project(':spring-session-data-geode') 7 | 8 | implementation("org.springframework.boot:spring-boot-starter-freemarker") { 9 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 10 | } 11 | 12 | implementation("org.springframework.boot:spring-boot-starter-web") { 13 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 14 | } 15 | 16 | implementation "jakarta.servlet:jakarta.servlet-api" 17 | implementation "org.springframework.data:spring-data-geode-test" 18 | 19 | runtimeOnly "org.springframework.shell:spring-shell" 20 | 21 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 22 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 23 | } 24 | 25 | testImplementation seleniumDependencies 26 | 27 | } 28 | 29 | mainClassName = 'sample.client.Application' 30 | 31 | bootJar { 32 | mainClassName = 'sample.client.Application' 33 | } 34 | 35 | run { 36 | doFirst { 37 | mainClassName = 'sample.server.GemFireServer' 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | repositories { 3 | mavenCentral() 4 | gradlePluginPortal() 5 | maven { url 'https://repo.spring.io/release' } 6 | if (version.endsWith('-SNAPSHOT')) { 7 | maven { url "https://repo.spring.io/snapshot" } 8 | } 9 | } 10 | } 11 | 12 | rootProject.name = 'spring-session-data-geode-build' 13 | 14 | FileTree buildFiles = fileTree(rootDir) { 15 | include '**/*.gradle' 16 | exclude '/build.gradle', 'settings.gradle', '**/gradle', 'buildSrc', '.*' 17 | } 18 | 19 | String rootDirPath = rootDir.absolutePath + File.separator 20 | 21 | buildFiles.each { File buildFile -> 22 | 23 | boolean isDefaultName = 'build.gradle'.equals(buildFile.name) 24 | 25 | if (isDefaultName) { 26 | String buildFilePath = buildFile.parentFile.absolutePath 27 | String projectPath = buildFilePath.replace(rootDirPath, '').replaceAll(File.separator, ':') 28 | 29 | include projectPath 30 | } 31 | else { 32 | String projectName = buildFile.name.replace('.gradle', ''); 33 | String projectPath = ':' + projectName; 34 | 35 | include projectPath 36 | 37 | def project = findProject("${projectPath}") 38 | 39 | project.name = projectName 40 | project.projectDir = buildFile.parentFile 41 | project.buildFileName = buildFile.name 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/java/sample/server/GemFireServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package sample.server; 17 | 18 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 19 | import org.springframework.context.annotation.Configuration; 20 | import org.springframework.context.annotation.ImportResource; 21 | 22 | // tag::class[] 23 | @Configuration // <1> 24 | @ImportResource("META-INF/spring/session-server.xml") // <2> 25 | public class GemFireServer { 26 | 27 | public static void main(String[] args) { 28 | new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook(); 29 | } 30 | } 31 | // end::class[] 32 | -------------------------------------------------------------------------------- /samples/boot/gemfire/spring-session-sample-boot-gemfire.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'io.spring.convention.spring-sample-boot' 2 | // apply plugin: "gemfire-server" 3 | apply plugin: "application" 4 | 5 | dependencies { 6 | 7 | implementation project(':spring-session-data-geode') 8 | 9 | implementation("org.springframework.boot:spring-boot-starter-freemarker") { 10 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 11 | } 12 | 13 | implementation("org.springframework.boot:spring-boot-starter-web") { 14 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 15 | } 16 | 17 | implementation "jakarta.servlet:jakarta.servlet-api" 18 | implementation "org.springframework.data:spring-data-geode-test" 19 | 20 | runtimeOnly "org.springframework.shell:spring-shell" 21 | 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 23 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 24 | } 25 | 26 | integrationTestCompile seleniumDependencies 27 | 28 | integrationTestRuntime "org.springframework.shell:spring-shell" 29 | 30 | } 31 | 32 | mainClassName = 'sample.client.Application' 33 | 34 | bootJar { 35 | mainClassName = 'sample.client.Application' 36 | } 37 | 38 | run { 39 | doFirst { 40 | mainClassName = 'sample.server.GemFireServer' 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-gfsh-servers/spring-session-sample-boot-gemfire-with-gfsh-servers.gradle: -------------------------------------------------------------------------------- 1 | import org.apache.tools.ant.filters.ReplaceTokens 2 | 3 | apply plugin: 'io.spring.convention.spring-sample-boot' 4 | 5 | dependencies { 6 | 7 | implementation project(':spring-session-data-geode') 8 | 9 | implementation("org.springframework.boot:spring-boot-starter-freemarker") { 10 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 11 | } 12 | 13 | implementation("org.springframework.boot:spring-boot-starter-web") { 14 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 15 | } 16 | 17 | implementation "jakarta.servlet:jakarta.servlet-api" 18 | implementation "org.springframework.data:spring-data-geode-test" 19 | 20 | runtimeOnly "org.springframework.shell:spring-shell" 21 | 22 | testImplementation("org.springframework.boot:spring-boot-starter-test") { 23 | exclude group: "org.apache.logging.log4j", module: "log4j-to-slf4j" 24 | } 25 | } 26 | 27 | bootJar { 28 | mainClass = 'sample.client.Application' 29 | } 30 | 31 | processResources { 32 | filter ReplaceTokens, tokens: [ 33 | 'spring.version' : project.property("springVersion"), 34 | 'spring-data.version' : project.property("springDataGeodeVersion"), 35 | 'spring-session.version' : project.property("springSessionVersion"), 36 | 'spring-session-data-geode.version' : project.property("version") 37 | ] 38 | } 39 | -------------------------------------------------------------------------------- /CONTRIBUTING.adoc: -------------------------------------------------------------------------------- 1 | = Contributing to Spring Session for Apache Geode & VMware Tanzu GemFire 2 | 3 | Spring Session for Apache Geode & VMware Tanzu GemFire is released under the Apache 2.0 license. If you would like to 4 | contribute something, or simply want to hack on the code this document should help you get started. 5 | 6 | == Sign the Contributor License Agreement 7 | 8 | If you have not previously done so, please fill out and 9 | submit the https://cla.pivotal.io/sign/spring[Contributor License Agreement]. 10 | 11 | [[code-of-conduct]] 12 | == Code of Conduct 13 | 14 | Please see our https://github.com/spring-projects/.github/blob/master/CODE_OF_CONDUCT.md[code of conduct] 15 | 16 | [[report-security-vulnerability]] 17 | == Reporting Security Vulnerabilities 18 | 19 | Please see our https://github.com/spring-projects/spring-session-data-geode/security/policy[Security policy]. 20 | 21 | == Using GitHub issues 22 | 23 | We use GitHub issues to track bugs and enhancements. If you have a general usage question 24 | please ask on https://stackoverflow.com[Stack Overflow]. The Spring Session team and the 25 | broader community monitor the https://stackoverflow.com/tags/spring-session[`spring-session`] 26 | tag. 27 | 28 | If you are reporting a bug, please help to speed up problem diagnosis by providing as much 29 | information as possible. Ideally, that would include a small sample project that 30 | reproduces the problem. 31 | -------------------------------------------------------------------------------- /samples/boot/gemfire/src/main/resources/templates/index.ftlh: -------------------------------------------------------------------------------- 1 | 2 | 3 | Session Attributes 4 | 9 | 10 | 11 |
12 |

Description

13 |

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

18 | 19 |

Try it

20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <#attempt> 40 | <#list sessionAttributes as attributeName, attributeValue> 41 | 42 | 43 | 44 | 45 | 46 | <#recover> 47 | 48 | 49 |
Attribute NameAttribute Value
${attributeName}${attributeValue}
50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-gfsh-servers/src/main/resources/templates/index.ftlh: -------------------------------------------------------------------------------- 1 | 2 | 3 | Session Attributes 4 | 9 | 10 | 11 |
12 |

Description

13 |

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

18 | 19 |

Try it

20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 |
28 | 29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | <#attempt> 40 | <#list sessionAttributes as attributeName, attributeValue> 41 | 42 | 43 | 44 | 45 | 46 | <#recover> 47 | 48 | 49 |
Attribute NameAttribute Value
${attributeName}${attributeValue}
50 |
51 | 52 | 53 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/main/java/sample/server/GemFireServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package sample.server; 17 | 18 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 19 | import org.springframework.data.gemfire.config.annotation.CacheServerApplication; 20 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 21 | 22 | // tag::class[] 23 | @CacheServerApplication(name = "SpringSessionDataGeodeJavaConfigSampleServer") // <1> 24 | @EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 30) // <2> 25 | public class GemFireServer { 26 | 27 | @SuppressWarnings("resource") 28 | public static void main(String[] args) { 29 | new AnnotationConfigApplicationContext(GemFireServer.class).registerShutdownHook(); 30 | } 31 | } 32 | // end::class[] 33 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | 3 | 4 | 5 | Session Attributes 6 | 11 | 12 | 13 |
14 |

Description

15 |

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.

16 | 17 |

Try it

18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
Attribute NameAttribute Value
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | 3 | 4 | 5 | Session Attributes 6 | 11 | 12 | 13 |
14 |

Description

15 |

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.

16 | 17 |

Try it

18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
Attribute NameAttribute Value
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | 3 | 4 | 5 | Session Attributes 6 | 11 | 12 | 13 |
14 |

Description

15 |

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.

16 | 17 |

Try it

18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
Attribute NameAttribute Value
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/resources/org/springframework/session/data/gemfire/config/annotation/web/http/GemFireHttpSessionXmlConfigurationTests-context.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 14 | GemFireHttpSessionXmlConfigurationTests 15 | 0 16 | warning 17 | 18 | 19 | 20 | 21 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/spring/session.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | SpringSessionDataGeodeXmlP2pSample 23 | ${spring.data.gemfire.cache.log-level:error} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/src/main/java/sample/SessionServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample; 18 | 19 | import java.io.IOException; 20 | 21 | import jakarta.servlet.ServletException; 22 | import jakarta.servlet.http.HttpServlet; 23 | import jakarta.servlet.http.HttpServletRequest; 24 | import jakarta.servlet.http.HttpServletResponse; 25 | 26 | // tag::class[] 27 | public class SessionServlet extends HttpServlet { 28 | 29 | private static final long serialVersionUID = 2878267318695777395L; 30 | 31 | @Override 32 | protected void doPost(HttpServletRequest request, HttpServletResponse response) 33 | throws ServletException, IOException { 34 | 35 | String attributeName = request.getParameter("attributeName"); 36 | String attributeValue = request.getParameter("attributeValue"); 37 | 38 | request.getSession().setAttribute(attributeName, attributeValue); 39 | response.sendRedirect(request.getContextPath() + "/"); 40 | } 41 | } 42 | // end::class[] 43 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/java/sample/client/SessionServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample.client; 18 | 19 | import java.io.IOException; 20 | 21 | import jakarta.servlet.ServletException; 22 | import jakarta.servlet.http.HttpServlet; 23 | import jakarta.servlet.http.HttpServletRequest; 24 | import jakarta.servlet.http.HttpServletResponse; 25 | 26 | // tag::class[] 27 | public class SessionServlet extends HttpServlet { 28 | 29 | private static final long serialVersionUID = 2878267318695777395L; 30 | 31 | @Override 32 | protected void doPost(HttpServletRequest request, HttpServletResponse response) 33 | throws ServletException, IOException { 34 | 35 | String attributeName = request.getParameter("attributeName"); 36 | String attributeValue = request.getParameter("attributeValue"); 37 | 38 | request.getSession().setAttribute(attributeName, attributeValue); 39 | response.sendRedirect(request.getContextPath() + "/"); 40 | } 41 | } 42 | // end::class[] 43 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/main/java/sample/SessionServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample; 18 | 19 | import java.io.IOException; 20 | 21 | import jakarta.servlet.ServletException; 22 | import jakarta.servlet.annotation.WebServlet; 23 | import jakarta.servlet.http.HttpServlet; 24 | import jakarta.servlet.http.HttpServletRequest; 25 | import jakarta.servlet.http.HttpServletResponse; 26 | 27 | // tag::class[] 28 | @WebServlet("/session") 29 | public class SessionServlet extends HttpServlet { 30 | 31 | private static final long serialVersionUID = 2878267318695777395L; 32 | 33 | @Override 34 | protected void doPost(HttpServletRequest request, HttpServletResponse response) 35 | throws ServletException, IOException { 36 | 37 | String attributeName = request.getParameter("attributeName"); 38 | String attributeValue = request.getParameter("attributeValue"); 39 | 40 | request.getSession().setAttribute(attributeName, attributeValue); 41 | response.sendRedirect(request.getContextPath() + "/"); 42 | } 43 | } 44 | // end::class[] 45 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/main/java/sample/client/SessionServlet.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample.client; 18 | 19 | import java.io.IOException; 20 | 21 | import jakarta.servlet.ServletException; 22 | import jakarta.servlet.annotation.WebServlet; 23 | import jakarta.servlet.http.HttpServlet; 24 | import jakarta.servlet.http.HttpServletRequest; 25 | import jakarta.servlet.http.HttpServletResponse; 26 | 27 | // tag::class[] 28 | @WebServlet("/session") 29 | public class SessionServlet extends HttpServlet { 30 | 31 | private static final long serialVersionUID = 2878267318695777395L; 32 | 33 | @Override 34 | protected void doPost(HttpServletRequest request, HttpServletResponse response) 35 | throws ServletException, IOException { 36 | 37 | String attributeName = request.getParameter("attributeName"); 38 | String attributeValue = request.getParameter("attributeValue"); 39 | 40 | request.getSession().setAttribute(attributeName, attributeValue); 41 | response.sendRedirect(request.getContextPath() + "/"); 42 | } 43 | } 44 | // end::class[] 45 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/resources/META-INF/spring/session-server.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | SpringSessionDataGeodeSampleXmlServer 23 | ${spring.data.gemfire.cache.log-level:error} 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/src/main/webapp/index.jsp: -------------------------------------------------------------------------------- 1 | <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> 2 | 3 | 4 | 5 | Session Attributes 6 | 11 | 12 | 13 |
14 |

Description

15 |

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.

16 | 17 |

Try it

18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 |
28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 |
Attribute NameAttribute Value
45 |
46 | 47 | 48 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/SessionUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import java.util.Optional; 20 | 21 | import org.springframework.lang.Nullable; 22 | import org.springframework.session.Session; 23 | import org.springframework.util.StringUtils; 24 | 25 | /** 26 | * Abstract utility class containing functions for managing {@link Session} objects. 27 | * 28 | * @author John Blum 29 | * @see org.springframework.session.Session 30 | * @since 2.1.2 31 | */ 32 | public abstract class SessionUtils { 33 | 34 | /** 35 | * Determines whether the given {@link Object Session ID} is valid. 36 | * 37 | * @param sessionId {@link Object ID} of a {@link Session} to evaluate. 38 | * @return a boolean value indicating whether the given {@link Object Session ID} is valid. 39 | */ 40 | public static boolean isValidSessionId(@Nullable Object sessionId) { 41 | 42 | return Optional.ofNullable(sessionId) 43 | .map(Object::toString) 44 | .filter(StringUtils::hasText) 45 | .isPresent(); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-scoped-proxies/src/main/java/sample/client/model/RequestScopedProxyBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample.client.model; 18 | 19 | import java.util.concurrent.atomic.AtomicInteger; 20 | 21 | import org.springframework.context.annotation.ScopedProxyMode; 22 | import org.springframework.stereotype.Component; 23 | import org.springframework.web.context.annotation.RequestScope; 24 | 25 | /** 26 | * The RequestScopedProxyBean class... 27 | * 28 | * @author John Blum 29 | * @since 1.0.0 30 | */ 31 | @SuppressWarnings("unused") 32 | // tag::class[] 33 | @Component // <1> 34 | @RequestScope(proxyMode = ScopedProxyMode.TARGET_CLASS) // <2> 35 | public class RequestScopedProxyBean { 36 | 37 | private static final AtomicInteger INSTANCE_COUNTER = new AtomicInteger(0); 38 | 39 | private final int count; 40 | 41 | public RequestScopedProxyBean() { 42 | this.count = INSTANCE_COUNTER.incrementAndGet(); // <3> 43 | } 44 | 45 | public int getCount() { 46 | return count; 47 | } 48 | 49 | @Override 50 | public String toString() { 51 | return String.format("{ @type = '%s', count = %d }", getClass().getName(), getCount()); 52 | } 53 | } 54 | // end::class[] 55 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-scoped-proxies/src/main/java/sample/client/model/SessionScopedProxyBean.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample.client.model; 18 | 19 | import java.io.Serializable; 20 | import java.util.concurrent.atomic.AtomicInteger; 21 | 22 | import org.springframework.context.annotation.ScopedProxyMode; 23 | import org.springframework.stereotype.Component; 24 | import org.springframework.web.context.annotation.SessionScope; 25 | 26 | /** 27 | * The SessionScopedProxyBean class... 28 | * 29 | * @author John Blum 30 | * @since 1.0.0 31 | */ 32 | @SuppressWarnings("unused") 33 | // tag::class[] 34 | @Component // <1> 35 | @SessionScope(proxyMode = ScopedProxyMode.TARGET_CLASS) // <2> 36 | public class SessionScopedProxyBean implements Serializable { 37 | 38 | private static final AtomicInteger INSTANCE_COUNTER = new AtomicInteger(0); 39 | 40 | private final int count; 41 | 42 | public SessionScopedProxyBean() { 43 | this.count = INSTANCE_COUNTER.incrementAndGet(); // <3> 44 | } 45 | 46 | public int getCount() { 47 | return count; 48 | } 49 | 50 | @Override 51 | public String toString() { 52 | return String.format("{ @type = '%s', count = %d }", getClass().getName(), getCount()); 53 | } 54 | } 55 | // end::class[] 56 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/main/java/sample/client/ClientConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample.client; 18 | 19 | import org.springframework.beans.factory.annotation.Value; 20 | import org.springframework.context.annotation.Bean; 21 | import org.springframework.data.gemfire.config.annotation.ClientCacheApplication; 22 | import org.springframework.data.gemfire.config.annotation.ClientCacheConfigurer; 23 | import org.springframework.data.gemfire.tests.integration.ClientServerIntegrationTestsSupport; 24 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 25 | 26 | // tag::class[] 27 | @ClientCacheApplication(name = "SpringSessionDataGeodeJavaConfigSampleClient", 28 | readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true) // <1> 29 | @EnableGemFireHttpSession(poolName = "DEFAULT") // <2> 30 | public class ClientConfig extends ClientServerIntegrationTestsSupport { 31 | 32 | @Bean 33 | ClientCacheConfigurer gemfireServerReadyConfigurer( // <3> 34 | @Value("${spring.data.gemfire.cache.server.port:40404}") int cacheServerPort) { 35 | 36 | return (beanName, clientCacheFactoryBean) -> waitForServerToStart("localhost", cacheServerPort); 37 | } 38 | } 39 | // end::class[] 40 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.junit.After; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | 25 | import org.openqa.selenium.WebDriver; 26 | import org.openqa.selenium.htmlunit.HtmlUnitDriver; 27 | 28 | import sample.pages.HomePage; 29 | 30 | /** 31 | * @author Eddú Meléndez 32 | */ 33 | public class AttributeTests { 34 | 35 | private WebDriver driver; 36 | 37 | @Before 38 | public void setup() { 39 | this.driver = new HtmlUnitDriver(); 40 | } 41 | 42 | @After 43 | public void tearDown() { 44 | this.driver.quit(); 45 | } 46 | 47 | @Test 48 | public void noAttributes() { 49 | HomePage home = HomePage.go(this.driver, HomePage.class); 50 | assertThat(home.attributes().size()).isEqualTo(0); 51 | } 52 | 53 | @Test 54 | public void createAttribute() { 55 | HomePage home = HomePage.go(this.driver, HomePage.class); 56 | home = home.form().attributeName("a").attributeValue("b").submit(HomePage.class); 57 | assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); 58 | assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package sample; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | import org.junit.After; 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import org.openqa.selenium.WebDriver; 25 | import org.openqa.selenium.htmlunit.HtmlUnitDriver; 26 | 27 | import sample.pages.HomePage; 28 | 29 | /** 30 | * @author Eddú Meléndez 31 | */ 32 | public class AttributeTests { 33 | 34 | private WebDriver driver; 35 | 36 | @Before 37 | public void setup() { 38 | this.driver = new HtmlUnitDriver(); 39 | } 40 | 41 | @After 42 | public void tearDown() { 43 | this.driver.quit(); 44 | } 45 | 46 | @Test 47 | public void noAttributes() { 48 | HomePage home = HomePage.go(this.driver, HomePage.class); 49 | assertThat(home.attributes().size()).isEqualTo(0); 50 | } 51 | 52 | @Test 53 | public void createAttribute() { 54 | HomePage home = HomePage.go(this.driver, HomePage.class); 55 | home = home.form().attributeName("a").attributeValue("b").submit(HomePage.class); 56 | assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); 57 | assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-clientserver/src/integration-test/java/sample/AttributeTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package sample; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | import org.junit.After; 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import org.openqa.selenium.WebDriver; 25 | import org.openqa.selenium.htmlunit.HtmlUnitDriver; 26 | 27 | import sample.pages.HomePage; 28 | 29 | /** 30 | * @author Eddú Meléndez 31 | */ 32 | public class AttributeTests { 33 | 34 | private WebDriver driver; 35 | 36 | @Before 37 | public void setup() { 38 | this.driver = new HtmlUnitDriver(); 39 | } 40 | 41 | @After 42 | public void tearDown() { 43 | this.driver.quit(); 44 | } 45 | 46 | @Test 47 | public void noAttributes() { 48 | HomePage home = HomePage.go(this.driver, HomePage.class); 49 | assertThat(home.attributes().size()).isEqualTo(0); 50 | } 51 | 52 | @Test 53 | public void createAttribute() { 54 | HomePage home = HomePage.go(this.driver, HomePage.class); 55 | home = home.form().attributeName("a").attributeValue("b").submit(HomePage.class); 56 | assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); 57 | assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /samples/javaconfig/gemfire-p2p/src/integration-test/java/sample/AttributeTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.junit.After; 22 | import org.junit.Before; 23 | import org.junit.Test; 24 | 25 | import org.openqa.selenium.WebDriver; 26 | import org.openqa.selenium.htmlunit.HtmlUnitDriver; 27 | 28 | import sample.pages.HomePage; 29 | 30 | /** 31 | * @author Eddú Meléndez 32 | */ 33 | public class AttributeTests { 34 | 35 | private WebDriver driver; 36 | 37 | @Before 38 | public void setup() { 39 | this.driver = new HtmlUnitDriver(); 40 | } 41 | 42 | @After 43 | public void tearDown() { 44 | this.driver.quit(); 45 | } 46 | 47 | @Test 48 | public void noAttributes() { 49 | HomePage home = HomePage.go(this.driver, HomePage.class); 50 | assertThat(home.attributes().size()).isEqualTo(0); 51 | } 52 | 53 | @Test 54 | public void createAttribute() { 55 | HomePage home = HomePage.go(this.driver, HomePage.class); 56 | home = home.form().attributeName("a").attributeValue("b").submit(HomePage.class); 57 | assertThat(home.attributes()).extracting("attributeName").containsOnly("a"); 58 | assertThat(home.attributes()).extracting("attributeValue").containsOnly("b"); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/spring/session-client.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | ${spring.data.gemfire.cache.log-level:error} 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/support/IdentityEqualsDirtyPredicateUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.junit.Test; 22 | 23 | /** 24 | * Unit Tests for {@link IdentityEqualsDirtyPredicate}. 25 | * 26 | * @author John Blum 27 | * @see org.junit.Test 28 | * @see org.springframework.session.data.gemfire.support.IdentityEqualsDirtyPredicate 29 | * @since 2.1.2 30 | */ 31 | public class IdentityEqualsDirtyPredicateUnitTests { 32 | 33 | @Test 34 | public void isDirtyIsNullSafe() { 35 | 36 | assertThat(IdentityEqualsDirtyPredicate.INSTANCE.isDirty(null, null)).isFalse(); 37 | assertThat(IdentityEqualsDirtyPredicate.INSTANCE.isDirty("one", null)).isTrue(); 38 | assertThat(IdentityEqualsDirtyPredicate.INSTANCE.isDirty(null, "one")).isTrue(); 39 | } 40 | 41 | @Test 42 | public void isDirtyWithDifferentObjectsReturnsTrue() { 43 | assertThat(IdentityEqualsDirtyPredicate.INSTANCE.isDirty("one", "two")).isTrue(); 44 | } 45 | 46 | @Test 47 | public void isDirtyWithSameObjectsReturnsFalse() { 48 | assertThat(IdentityEqualsDirtyPredicate.INSTANCE.isDirty("one", "one")).isFalse(); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/events/SessionChangedEventUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.events; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | import org.junit.Test; 21 | import org.junit.runner.RunWith; 22 | import org.mockito.Mock; 23 | import org.mockito.junit.MockitoJUnitRunner; 24 | 25 | import org.springframework.session.Session; 26 | 27 | /** 28 | * Unit Tests for {@link SessionChangedEvent}. 29 | * 30 | * @author John Blum 31 | * @see org.junit.Test 32 | * @see org.mockito.Mock 33 | * @see org.mockito.Mockito 34 | * @see org.mockito.junit.MockitoJUnitRunner 35 | * @see org.springframework.session.Session 36 | * @since 2.2.0 37 | */ 38 | @RunWith(MockitoJUnitRunner.class) 39 | public class SessionChangedEventUnitTests { 40 | 41 | @Mock 42 | private Session mockSession; 43 | 44 | @Test 45 | public void constructSessionChangedEvent() { 46 | 47 | Object source = new Object(); 48 | 49 | SessionChangedEvent event = new SessionChangedEvent(source, this.mockSession); 50 | 51 | assertThat(event).isNotNull(); 52 | assertThat(event.getSource()).isEqualTo(source); 53 | assertThat(event.getSession()).isEqualTo(this.mockSession); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/support/SessionUtilsUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.junit.Test; 22 | 23 | /** 24 | * Unit Tests for {@link SessionUtils}. 25 | * 26 | * @author John Blum 27 | * @see org.springframework.session.Session 28 | * @see org.springframework.session.data.gemfire.support.SessionUtils 29 | * @since 2.1.2 30 | */ 31 | public class SessionUtilsUnitTests { 32 | 33 | @Test 34 | public void isValidSessionIdWithValidSessionId() { 35 | assertThat(SessionUtils.isValidSessionId("1")).isTrue(); 36 | } 37 | 38 | private void testIsValidSessionIdWithInvalidSessionId(Object sessionId) { 39 | assertThat(SessionUtils.isValidSessionId(sessionId)).isFalse(); 40 | } 41 | 42 | @Test 43 | public void isValidSessionIdWithEmptySessionId() { 44 | testIsValidSessionIdWithInvalidSessionId(""); 45 | } 46 | 47 | @Test 48 | public void isValidSessionIdWithNullSessionId() { 49 | testIsValidSessionIdWithInvalidSessionId(null); 50 | } 51 | 52 | @Test 53 | public void isValidSessionIdWithUnspecifiedSessionId() { 54 | testIsValidSessionIdWithInvalidSessionId(" "); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 11 | contextConfigLocation 12 | /WEB-INF/spring/session-client.xml 13 | 14 | 15 | 16 | 17 | 18 | springSessionRepositoryFilter 19 | org.springframework.web.filter.DelegatingFilterProxy 20 | 21 | 22 | springSessionRepositoryFilter 23 | /* 24 | REQUEST 25 | ERROR 26 | 27 | 28 | 29 | 34 | 35 | 36 | org.springframework.web.context.ContextLoaderListener 37 | 38 | 39 | 40 | 41 | session 42 | sample.client.SessionServlet 43 | 44 | 45 | 46 | session 47 | /session 48 | 49 | 50 | 51 | index.jsp 52 | 53 | 54 | -------------------------------------------------------------------------------- /samples/xml/gemfire-p2p/src/main/webapp/WEB-INF/web.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 9 | 10 | 11 | contextConfigLocation 12 | 13 | /WEB-INF/spring/*.xml 14 | 15 | 16 | 17 | 18 | 19 | 20 | springSessionRepositoryFilter 21 | org.springframework.web.filter.DelegatingFilterProxy 22 | 23 | 24 | springSessionRepositoryFilter 25 | /* 26 | REQUEST 27 | ERROR 28 | 29 | 30 | 31 | 36 | 37 | 38 | 39 | org.springframework.web.context.ContextLoaderListener 40 | 41 | 42 | 43 | 44 | 45 | session 46 | sample.SessionServlet 47 | 48 | 49 | 50 | session 51 | /session 52 | 53 | 54 | 55 | index.jsp 56 | 57 | 58 | -------------------------------------------------------------------------------- /docs/src/docs/asciidoc/guides/gfsh.adoc: -------------------------------------------------------------------------------- 1 | :data-store-version: {master-data-store-version} 2 | :data-store-docs: https://geode.apache.org/docs/guide/{data-store-version} 3 | :stylesdir: ../ 4 | 5 | NOTE: The following instructions assume you have installed a local Apache Geode installation. For more information 6 | on installation, see {data-store-docs}/prereq_and_install.html[Prerequisites and Installation Instructions]. 7 | 8 | If you like, you can easily remove the session using `gfsh`. 9 | 10 | For example, on a Linux-based system type the following at the command-line: 11 | 12 | $ gfsh 13 | 14 | Then, enter the following commands in _Gfsh_, ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value 15 | from your SESSION cookie, or the session id returned by the Apache Geode OQL query (which should match): 16 | 17 | [source,text] 18 | ---- 19 | gfsh>connect --jmx-manager=localhost[1099] 20 | 21 | gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet' 22 | 23 | Result : true 24 | startCount : 0 25 | endCount : 20 26 | Rows : 1 27 | 28 | Result 29 | ------------------------------------ 30 | 70002719-3c54-4c20-82c3-e7faa6b718f3 31 | 32 | NEXT_STEP_NAME : END 33 | 34 | gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3" 35 | ---- 36 | 37 | NOTE: The Apache Geode User Guide contains more detailed instructions on using 38 | {data-store-docs}/tools_modules/gfsh/chapter_overview.html[gfsh]. 39 | 40 | Now visit the application at `http://localhost:8080/` again and observe the attribute we added is no longer displayed. 41 | 42 | Alternatively, you can wait **20 seconds** for the session to timeout/expire and then refresh the page. The attribute 43 | we added should no longer be displayed in the table. However, keep in mind, by refreshing the page, you will 44 | inadvertently create a new (empty) session. If you run the query again, you will also see two session ids, 45 | the new and the old, since Apache Geode keeps a "tombstone" of the old session around (for consistency purposes). 46 | -------------------------------------------------------------------------------- /samples/boot/gemfire/src/main/java/sample/server/GemFireServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample.server; 18 | 19 | import org.springframework.boot.WebApplicationType; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import org.springframework.boot.builder.SpringApplicationBuilder; 22 | import org.springframework.data.gemfire.config.annotation.CacheServerApplication; 23 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 24 | 25 | /** 26 | * A Spring Boot application bootstrapping a Pivotal GemFire Cache Server JVM process. 27 | * 28 | * @author John Blum 29 | * @see org.springframework.boot.SpringApplication 30 | * @see org.springframework.boot.autoconfigure.SpringBootApplication 31 | * @see org.springframework.context.annotation.Bean 32 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession 33 | * @see org.apache.geode.cache.Cache 34 | * @since 1.2.1 35 | */ 36 | // tag::class[] 37 | @SpringBootApplication // <1> 38 | @CacheServerApplication(name = "SpringSessionDataGeodeBootSampleServer") // <2> 39 | @EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 20) // <3> 40 | public class GemFireServer { 41 | 42 | public static void main(String[] args) { 43 | 44 | new SpringApplicationBuilder(GemFireServer.class) 45 | .web(WebApplicationType.NONE) 46 | .build() 47 | .run(args); 48 | } 49 | } 50 | // end::class[] 51 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/expiration/config/SessionExpirationTimeoutAware.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.expiration.config; 18 | 19 | import java.time.Duration; 20 | 21 | import org.springframework.session.Session; 22 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 23 | 24 | /** 25 | * The {@link SessionExpirationTimeoutAware} interface is a configuration callback interface allowing implementors 26 | * to receive a callback with the configured {@link Session} {@link Duration expiration timeout} as set on the 27 | * {@link EnableGemFireHttpSession} annotation, {@link EnableGemFireHttpSession#maxInactiveIntervalInSeconds()} 28 | * attribute. 29 | * 30 | * @author John Blum 31 | * @see java.time.Duration 32 | * @see org.springframework.session.Session 33 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession 34 | * @since 2.1.0 35 | */ 36 | @SuppressWarnings("unused") 37 | public interface SessionExpirationTimeoutAware { 38 | 39 | /** 40 | * Configures the {@link Session} {@link Duration expiration timeout} on this implementating object. 41 | * 42 | * @param expirationTimeout {@link Duration} specifying the expiration timeout fo the {@link Session}. 43 | * @see java.time.Duration 44 | */ 45 | void setExpirationTimeout(Duration expirationTimeout); 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/web/http/AbstractCookieSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.web.http; 17 | 18 | import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newUnsupportedOperationException; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import jakarta.servlet.http.HttpServletRequest; 24 | 25 | import org.springframework.session.web.http.CookieSerializer; 26 | 27 | /** 28 | * Abstract base class implementing the Spring Session core {@link CookieSerializer} interface to encapsulate 29 | * functionality common to all implementations as well as to simplify the implementation of the Spring Session core 30 | * {@link CookieSerializer} interface. 31 | * 32 | * @author John Blum 33 | * @see jakarta.servlet.http.HttpServletRequest 34 | * @see org.springframework.session.web.http.CookieSerializer 35 | * @since 2.5.0 36 | */ 37 | public class AbstractCookieSerializer implements CookieSerializer { 38 | 39 | protected static final String NOT_IMPLEMENTED = "NOT IMPLEMENTED"; 40 | 41 | /** 42 | * @inheritDoc 43 | */ 44 | @Override 45 | public List readCookieValues(HttpServletRequest request) { 46 | return Collections.emptyList(); 47 | } 48 | 49 | /** 50 | * @inheritDoc 51 | */ 52 | @Override 53 | public void writeCookieValue(CookieValue cookieValue) { 54 | throw newUnsupportedOperationException(NOT_IMPLEMENTED); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /samples/boot/gemfire-with-scoped-proxies/src/main/java/sample/server/GemFireServer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package sample.server; 18 | 19 | import org.springframework.boot.WebApplicationType; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import org.springframework.boot.builder.SpringApplicationBuilder; 22 | import org.springframework.data.gemfire.config.annotation.CacheServerApplication; 23 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 24 | 25 | /** 26 | * A Spring Boot application bootstrapping a Pivotal GemFire Cache Server JVM process. 27 | * 28 | * @author John Blum 29 | * @see org.springframework.boot.SpringApplication 30 | * @see org.springframework.boot.autoconfigure.SpringBootApplication 31 | * @see org.springframework.context.annotation.Bean 32 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession 33 | * @see org.apache.geode.cache.Cache 34 | * @since 1.2.1 35 | */ 36 | // tag::class[] 37 | @SpringBootApplication // <1> 38 | @CacheServerApplication(name = "SpringSessionDataGeodeBootSampleWithScopedProxiesServer", logLevel = "error") // <2> 39 | @EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 10) // <3> 40 | public class GemFireServer { 41 | 42 | public static void main(String[] args) { 43 | 44 | new SpringApplicationBuilder(GemFireServer.class) 45 | .web(WebApplicationType.NONE) 46 | .build() 47 | .run(args); 48 | } 49 | } 50 | // end::class[] 51 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/events/SessionChangedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.events; 17 | 18 | import org.springframework.context.ApplicationEvent; 19 | import org.springframework.session.Session; 20 | 21 | /** 22 | * {@link SessionChangedEvent} is a Spring {@link ApplicationEvent} fire when the {@link Session} state changes. 23 | * 24 | * @author John Blum 25 | * @see org.springframework.context.ApplicationEvent 26 | * @see org.springframework.session.Session 27 | * @since 2.2.0 28 | */ 29 | public class SessionChangedEvent extends ApplicationEvent { 30 | 31 | private final Session session; 32 | 33 | /** 34 | * Constructs a new instance of {@link SessionChangedEvent} initialized with the given {@link Object source} 35 | * and {@link Session}. 36 | * 37 | * @param source {@link Object} referencing the source of the event. 38 | * @param session {@link Session} that changed. 39 | * @see org.springframework.session.Session 40 | */ 41 | public SessionChangedEvent(Object source, Session session) { 42 | 43 | super(source); 44 | 45 | this.session = session; 46 | } 47 | 48 | /** 49 | * Gets the {@link Session} that was changed. 50 | * 51 | * @param {@link Class type} of {@link Session}. 52 | * @return a reference to the {@link Session} that is the subject of the change event. 53 | * @see org.springframework.session.Session 54 | */ 55 | @SuppressWarnings("unchecked") 56 | public S getSession() { 57 | return (S) this.session; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/IdentityEqualsDirtyPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import org.springframework.lang.Nullable; 20 | 21 | /** 22 | * {@link IdentityEqualsDirtyPredicate} is an {@link IsDirtyPredicate} strategy interface implementation 23 | * that determines whether the {@link Object new value} is dirty by comparing the {@link Object new value} 24 | * with the {@link Object old value} using the identity operator ({@literal ==}). 25 | * 26 | * @author John Blum 27 | * @see org.springframework.session.data.gemfire.support.IsDirtyPredicate 28 | * @since 2.1.2 29 | */ 30 | @SuppressWarnings("unused") 31 | public class IdentityEqualsDirtyPredicate implements IsDirtyPredicate { 32 | 33 | public static final IdentityEqualsDirtyPredicate INSTANCE = new IdentityEqualsDirtyPredicate(); 34 | 35 | /** 36 | * Determines whether the {@link Object new value} is dirty by comparing the {@link Object new value} 37 | * with the {@link Object old value} using the identity operator ({@literal ==}). 38 | * 39 | * This method is {@literal null-safe}. 40 | * 41 | * @param oldValue {@link Object} referring to the previous value. 42 | * @param newValue {@link Object} referring to the new value. 43 | * @return a boolean value indicating whether the {@link Object new value} is dirty by comparing 44 | * the {@link Object new value} with the {@link Object old value} using the identity operator ({@literal ==}). 45 | */ 46 | @Override 47 | public boolean isDirty(@Nullable Object oldValue, @Nullable Object newValue) { 48 | return newValue != oldValue; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/java/sample/client/ClientServerReadyBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package sample.client; 17 | 18 | import java.util.concurrent.atomic.AtomicBoolean; 19 | 20 | import org.springframework.beans.BeansException; 21 | import org.springframework.beans.factory.annotation.Value; 22 | import org.springframework.beans.factory.config.BeanPostProcessor; 23 | import org.springframework.data.gemfire.tests.integration.ClientServerIntegrationTestsSupport; 24 | import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; 25 | 26 | @SuppressWarnings("unused") 27 | public class ClientServerReadyBeanPostProcessor extends ClientServerIntegrationTestsSupport 28 | implements BeanPostProcessor { 29 | 30 | private final AtomicBoolean verifyGemFireServerIsRunning = new AtomicBoolean(true); 31 | 32 | @Value("${spring.data.gemfire.cache.server.port:40404}") 33 | private int port; 34 | 35 | @Value("${spring.session.data.geode.cache.server.host:localhost}") 36 | private String host; 37 | 38 | @Override 39 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 40 | 41 | if (isGemFireServerRunningVerificationEnabled(bean, beanName)) { 42 | waitForServerToStart(host, port); 43 | } 44 | 45 | return bean; 46 | } 47 | 48 | private boolean isGemFireServerRunningVerificationEnabled(Object bean, String beanName) { 49 | 50 | return isSessionGemFireRegion(bean, beanName) 51 | && this.verifyGemFireServerIsRunning.compareAndSet(true, false); 52 | } 53 | 54 | private boolean isSessionGemFireRegion(Object bean, String beanName) { 55 | return GemFireHttpSessionConfiguration.DEFAULT_SESSION_REGION_NAME.equals(beanName); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/EqualsDirtyPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import org.springframework.lang.Nullable; 20 | 21 | /** 22 | * {@link EqualsDirtyPredicate} is an {@link IsDirtyPredicate} strategy interface implementation that determines 23 | * whether the {@link Object new value} is dirty by comparing the {@link Object new value} 24 | * with the {@link Object old value} using the {@link Object#equals(Object)} method. 25 | * 26 | * @author John Blum 27 | * @see org.springframework.session.data.gemfire.support.IsDirtyPredicate 28 | * @since 2.1.2 29 | */ 30 | @SuppressWarnings("unused") 31 | public class EqualsDirtyPredicate implements IsDirtyPredicate { 32 | 33 | public static final EqualsDirtyPredicate INSTANCE = new EqualsDirtyPredicate(); 34 | 35 | /** 36 | * Determines whether the {@link Object new value} is dirty by comparing the {@link Object new value} 37 | * with the {@link Object old value} using the {@link Object#equals(Object)} method. 38 | * 39 | * This method is {@literal null-safe}. 40 | * 41 | * @param oldValue {@link Object} referring to the previous value. 42 | * @param newValue {@link Object} referring to the new value. 43 | * @return a boolean value indicating whether the {@link Object new value} is dirty by comparing 44 | * the {@link Object new value} with the {@link Object old value} using the {@link Object#equals(Object)} method. 45 | * @see java.lang.Object#equals(Object) 46 | */ 47 | @Override 48 | public boolean isDirty(@Nullable Object oldValue, @Nullable Object newValue) { 49 | 50 | return newValue != null 51 | ? !newValue.equals(oldValue) 52 | : oldValue != null; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /etc/build-notes.adoc: -------------------------------------------------------------------------------- 1 | [[build-notes]] 2 | = Gradle Build Notes for Spring Session for Apache Geode & VMware Tanzu GemFire (SSDG) 3 | 4 | This document contains notes on running specific Gradle (i.e. `gradlew`) build tasks. 5 | 6 | [[build-notes-test-run-single]] 7 | == Running a Single Unit Test 8 | 9 | Use the following `gradlew` command to run a single SSDG Unit Test in a specific module: 10 | 11 | .Example of running a single SSDG Unit Test class from the test suite 12 | [source,text] 13 | ---- 14 | $ gradlew :spring-session-data-geode:test 15 | --tests=GemFireOperationsSessionRepositoryTests 16 | ---- 17 | 18 | [[build-notes-integrationTest-run-single]] 19 | == Running a Single Integration Test 20 | 21 | Use the following `gradlew` command to run a single SSDG Integration Test in the specified module: 22 | 23 | .Example of running a single SSDG Integration Test class from the test suite 24 | [source,text] 25 | ---- 26 | $ gradlew :spring-session-data-geode:integrationTest 27 | --tests MultiThreadedHighlyConcurrentClientServerHttpSessionAccessIntegrationTests 28 | ---- 29 | 30 | [[build-notes-integrationTests-geode-logging]] 31 | == Setting Apache Geode's Log Level when running Integration Tests 32 | 33 | Set the Apache Geode Logger `org.apache.geode` Logger `log-level` using the JVM System Property, or alternatively, 34 | the Gradle Project Property `logback.log.level`. 35 | 36 | .Example setting Apache Geode Log Level using JVM System Property 37 | [source,txt] 38 | ---- 39 | $ gradlew :spring-session-data-geode:integrationTests -Dlogback.log.level=DEBUG 40 | ---- 41 | 42 | .Example setting Apache Geode Log Level using Gradlew Build Property 43 | [source,txt] 44 | ---- 45 | $ gradlew :spring-session-data-geode:integrationTests -Plogback.log.level=DEBUG 46 | ---- 47 | 48 | [[build-notes-test-jvm-heap-sizes]] 49 | == Setting (Unit | Integration) Test JVM Heap Memory Sizes 50 | 51 | Use the `-Ptest.jvm.heap.max-size` Gradle Project Property to set the test JVM Heap maximum memory size. 52 | 53 | Use the `-Ptest.jvm.heap.min-size` Gradle Project Property to set the test JVM Heap minimum memory size. 54 | 55 | .Setting the JVM Heap max and min memory size when running Unit and/or Integration Tests (or a single Unit or Integration Test) 56 | [source,text] 57 | ---- 58 | $ gradlew :spring-session-data-geode:integrationTest 59 | --tests=MultiThreadedHighlyConcurrentClientServerHttpSessionAccessIntegrationTests 60 | -Ptest.jvm.heap.max-size=4g 61 | -Ptest.jvm.heap.min-size=512m 62 | ---- 63 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/web/http/AbstractHttpSessionIdResolver.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.web.http; 17 | 18 | import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newUnsupportedOperationException; 19 | 20 | import java.util.Collections; 21 | import java.util.List; 22 | 23 | import jakarta.servlet.http.HttpServletRequest; 24 | import jakarta.servlet.http.HttpServletResponse; 25 | 26 | import org.springframework.session.web.http.HttpSessionIdResolver; 27 | 28 | /** 29 | * Abstract base class implementing the Spring Session core {@link HttpSessionIdResolver} interface to encapsulate 30 | * functionality common to all implementations as well as to simplify the implementation of the Spring Session core 31 | * {@link HttpSessionIdResolver} interface. 32 | * 33 | * @author John Blum 34 | * @see jakarta.servlet.http.HttpServletRequest 35 | * @see jakarta.servlet.http.HttpServletResponse 36 | * @see org.springframework.session.web.http.HttpSessionIdResolver 37 | * @since 2.5.0 38 | */ 39 | public abstract class AbstractHttpSessionIdResolver implements HttpSessionIdResolver { 40 | 41 | private static final String NOT_IMPLEMENTED = "NOT IMPLEMENTED"; 42 | 43 | /** 44 | * @inheritDoc 45 | */ 46 | @Override 47 | public void setSessionId(HttpServletRequest request, HttpServletResponse response, String sessionId) { 48 | throw newUnsupportedOperationException(NOT_IMPLEMENTED); 49 | 50 | } 51 | 52 | /** 53 | * @inheritDoc 54 | */ 55 | @Override 56 | public List resolveSessionIds(HttpServletRequest request) { 57 | return Collections.emptyList(); 58 | } 59 | 60 | /** 61 | * @inheritDoc 62 | */ 63 | @Override 64 | public void expireSession(HttpServletRequest request, HttpServletResponse response) { 65 | throw newUnsupportedOperationException(NOT_IMPLEMENTED); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | set DIRNAME=%~dp0 12 | if "%DIRNAME%" == "" set DIRNAME=. 13 | set APP_BASE_NAME=%~n0 14 | set APP_HOME=%DIRNAME% 15 | 16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 17 | set DEFAULT_JVM_OPTS= 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windows variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | 53 | :win9xME_args 54 | @rem Slurp the command line arguments. 55 | set CMD_LINE_ARGS= 56 | set _SKIP=2 57 | 58 | :win9xME_args_slurp 59 | if "x%~1" == "x" goto execute 60 | 61 | set CMD_LINE_ARGS=%* 62 | 63 | :execute 64 | @rem Setup the command line 65 | 66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 67 | 68 | @rem Execute Gradle 69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 70 | 71 | :end 72 | @rem End local scope for the variables with windows NT shell 73 | if "%ERRORLEVEL%"=="0" goto mainEnd 74 | 75 | :fail 76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 77 | rem the _cmd.exe /c_ return code! 78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 79 | exit /b 1 80 | 81 | :mainEnd 82 | if "%OS%"=="Windows_NT" endlocal 83 | 84 | :omega 85 | -------------------------------------------------------------------------------- /spring-session-data-geode/spring-session-data-geode.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "io.freefair.lombok" version "6.5.0.3" 3 | } 4 | 5 | apply plugin: 'io.spring.convention.spring-module' 6 | 7 | description = "Spring Session for Apache Geode" 8 | 9 | dependencies { 10 | 11 | api "jakarta.annotation:jakarta.annotation-api" 12 | api "org.springframework:spring-context-support" 13 | api "org.springframework:spring-jcl" 14 | api "org.springframework.data:spring-data-geode" 15 | api "org.springframework.session:spring-session-core" 16 | implementation slf4jDependencies 17 | 18 | compileOnly "com.google.code.findbugs:jsr305:$findbugsVersion" 19 | 20 | optional "org.springframework.security:spring-security-core" 21 | optional "org.springframework.security:spring-security-web" 22 | 23 | provided "jakarta.resource:jakarta.resource-api" 24 | provided "jakarta.servlet:jakarta.servlet-api" 25 | 26 | testCompileOnly "com.google.code.findbugs:jsr305:$findbugsVersion" 27 | 28 | testImplementation "org.springframework:spring-web" 29 | 30 | testRuntimeOnly "ch.qos.logback:logback-classic" 31 | testRuntimeOnly "org.apache.logging.log4j:log4j-to-slf4j" 32 | 33 | integrationTestCompile "com.google.code.findbugs:jsr305:$findbugsVersion" 34 | 35 | integrationTestRuntime "org.springframework.shell:spring-shell" 36 | 37 | } 38 | 39 | def jvmArgList = [ 40 | "--add-opens", "java.base/java.lang=ALL-UNNAMED", 41 | "--add-opens", "java.base/java.nio=ALL-UNNAMED", 42 | "--add-opens", "java.base/java.util=ALL-UNNAMED", 43 | "--add-opens", "java.base/sun.nio.ch=ALL-UNNAMED", 44 | "--add-opens", "java.management/com.sun.jmx.remote.security=ALL-UNNAMED", 45 | "--add-opens", "jdk.management/com.sun.management.internal=ALL-UNNAMED" 46 | ] 47 | 48 | test { 49 | 50 | jvmArgs jvmArgList 51 | 52 | maxHeapSize = project.hasProperty("test.jvm.heap.max-size") 53 | ? project.getProperty("test.jvm.heap.max-size") 54 | : "512m" 55 | 56 | minHeapSize = project.hasProperty("test.jvm.heap.min-size") 57 | ? project.getProperty("test.jvm.heap.min-size") 58 | : "512m" 59 | 60 | } 61 | 62 | integrationTest { 63 | 64 | jvmArgs jvmArgList 65 | 66 | maxHeapSize = project.hasProperty("test.jvm.heap.max-size") 67 | ? project.getProperty("test.jvm.heap.max-size") 68 | : "2g" 69 | 70 | minHeapSize = project.hasProperty("test.jvm.heap.min-size") 71 | ? project.getProperty("test.jvm.heap.min-size") 72 | : "512m" 73 | 74 | def gradleProjectPropertyLogbackLogLevel = project.hasProperty("logback.log.level") 75 | ? project.getProperty("logback.log.level") 76 | : "ERROR" 77 | 78 | systemProperty "logback.log.level", System.getProperty("logback.log.level", gradleProjectPropertyLogbackLogLevel) 79 | 80 | } 81 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/expiration/SessionExpirationPolicyUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.expiration; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | import static org.mockito.Mockito.times; 20 | import static org.mockito.Mockito.verify; 21 | import static org.mockito.Mockito.when; 22 | import static org.springframework.session.data.gemfire.expiration.SessionExpirationPolicy.ExpirationAction; 23 | 24 | import org.junit.Test; 25 | import org.junit.runner.RunWith; 26 | import org.mockito.Mock; 27 | import org.mockito.junit.MockitoJUnitRunner; 28 | 29 | /** 30 | * Unit Tests for {@link SessionExpirationPolicy}. 31 | * 32 | * @author John Blum 33 | * @see org.junit.Test 34 | * @see org.mockito.Mock 35 | * @see org.mockito.Mockito 36 | * @see org.mockito.junit.MockitoJUnitRunner 37 | * @see org.springframework.session.data.gemfire.expiration.SessionExpirationPolicy 38 | * @see org.springframework.session.data.gemfire.expiration.SessionExpirationPolicy.ExpirationAction 39 | * @since 2.1.0 40 | */ 41 | @RunWith(MockitoJUnitRunner.class) 42 | public class SessionExpirationPolicyUnitTests { 43 | 44 | @Mock 45 | private SessionExpirationPolicy mockSessionExpirationPolicy; 46 | 47 | @Test 48 | public void expirationActionDefaultsToInvalidate() { 49 | 50 | when(this.mockSessionExpirationPolicy.getExpirationAction()).thenCallRealMethod(); 51 | 52 | assertThat(this.mockSessionExpirationPolicy.getExpirationAction()) 53 | .isEqualTo(SessionExpirationPolicy.ExpirationAction.INVALIDATE); 54 | 55 | verify(this.mockSessionExpirationPolicy, times(1)).getExpirationAction(); 56 | } 57 | 58 | @Test 59 | public void expirationActionDefaultIfNullReturnsDefault() { 60 | assertThat(ExpirationAction.defaultIfNull(null)).isEqualTo(ExpirationAction.INVALIDATE); 61 | } 62 | 63 | @Test 64 | public void expirationActionDefaultIfNullReturnsExpirationAction() { 65 | assertThat(ExpirationAction.defaultIfNull(ExpirationAction.DESTROY)).isEqualTo(ExpirationAction.DESTROY); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/serialization/data/support/WirableDataSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.serialization.data.support; 18 | 19 | import static org.springframework.data.gemfire.support.GemfireBeanFactoryLocator.newBeanFactoryLocator; 20 | 21 | import java.util.Optional; 22 | 23 | import org.apache.geode.DataSerializer; 24 | 25 | import org.springframework.beans.factory.BeanFactory; 26 | import org.springframework.beans.factory.wiring.BeanConfigurerSupport; 27 | import org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer; 28 | import org.springframework.stereotype.Component; 29 | 30 | /** 31 | * {@link WirableDataSerializer} is an abstract base class supporting auto-wiring of a non-managed, 32 | * GemFire/Geode {@link DataSerializer}, Spring {@link Component}. 33 | * 34 | * @author John Blum 35 | * @see org.apache.geode.DataSerializer 36 | * @see org.springframework.beans.factory.BeanFactory 37 | * @see org.springframework.beans.factory.wiring.BeanConfigurerSupport 38 | * @see org.springframework.session.data.gemfire.serialization.data.AbstractDataSerializableSessionSerializer 39 | * @since 2.0.0 40 | */ 41 | abstract class WirableDataSerializer extends AbstractDataSerializableSessionSerializer { 42 | 43 | protected final void autowire() { 44 | 45 | locateBeanFactory().map(this::newBeanConfigurer).ifPresent(beanConfigurer -> { 46 | beanConfigurer.configureBean(this); 47 | beanConfigurer.destroy(); 48 | }); 49 | } 50 | 51 | Optional locateBeanFactory() { 52 | 53 | try { 54 | return Optional.ofNullable(newBeanFactoryLocator().useBeanFactory()); 55 | } 56 | catch (Exception ignore) { 57 | return Optional.empty(); 58 | } 59 | } 60 | 61 | BeanConfigurerSupport newBeanConfigurer(BeanFactory beanFactory) { 62 | 63 | BeanConfigurerSupport beanConfigurer = new BeanConfigurerSupport(); 64 | 65 | beanConfigurer.setBeanFactory(beanFactory); 66 | beanConfigurer.afterPropertiesSet(); 67 | 68 | return beanConfigurer; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/AbstractGemFireUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire; 17 | 18 | import static org.mockito.Mockito.mock; 19 | 20 | import org.apache.geode.cache.client.ClientCache; 21 | import org.apache.geode.cache.client.Pool; 22 | 23 | import org.springframework.context.annotation.Bean; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport; 26 | import org.springframework.data.gemfire.tests.mock.GemFireMockObjectsSupport; 27 | import org.springframework.data.gemfire.tests.util.ObjectUtils; 28 | import org.springframework.data.gemfire.tests.util.ReflectionUtils; 29 | import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; 30 | 31 | /** 32 | * {@link AbstractGemFireUnitTests} is an abstract base class encapsulating functionality common to all Unit Tests 33 | * in the SSDG test suite. 34 | * 35 | * @author John Blum 36 | * @see org.junit.Test 37 | * @see org.mockito.Mockito 38 | * @see org.apache.geode.cache.client.ClientCache 39 | * @see org.apache.geode.cache.client.Pool 40 | * @see org.springframework.context.annotation.Bean 41 | * @see org.springframework.context.annotation.Configuration 42 | * @see org.springframework.data.gemfire.tests.mock.GemFireMockObjectsSupport 43 | * @see org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport 44 | * @since 2.5.0 45 | */ 46 | public class AbstractGemFireUnitTests extends IntegrationTestsSupport { 47 | 48 | protected T getValue(Object target, String fieldName) { 49 | return ObjectUtils.doOperationSafely(() -> ReflectionUtils.getFieldValue(target, fieldName), null); 50 | } 51 | 52 | @Configuration 53 | protected static class BaseTestConfiguration { 54 | 55 | @Bean 56 | ClientCache mockClientCache() { 57 | return GemFireMockObjectsSupport.mockClientCache(); 58 | } 59 | 60 | @Bean(GemFireHttpSessionConfiguration.DEFAULT_POOL_NAME) 61 | Pool mockPool() { 62 | return mock(Pool.class); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/serialization/SessionSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.serialization; 17 | 18 | import java.util.Optional; 19 | 20 | /** 21 | * The {@link SessionSerializer} interface is a Service Provider Interface (SPI) for providers 22 | * needing to provide a custom implementation of their serialization strategy. 23 | * 24 | * @author John Blum 25 | * @since 2.0.0 26 | */ 27 | public interface SessionSerializer { 28 | 29 | /** 30 | * Serializes the given {@link Object} to the provided {@code out} stream. 31 | * 32 | * @param session {@link Object} to serialize. 33 | * @param out stream in which to write the bytes of the {@link Object}. 34 | */ 35 | void serialize(T session, OUT out); 36 | 37 | /** 38 | * Deserializes an {@link Object} from bytes contained in the provided {@code in} stream. 39 | * 40 | * @param in stream from which to read the bytes of the {@link Object}. 41 | * @return the deserialized {@link Object}. 42 | */ 43 | T deserialize(IN in); 44 | 45 | /** 46 | * Determines whether the given {@link Class type} can be de/serialized by this {@link SessionSerializer}. 47 | * 48 | * @param type {@link Class} to evaluate for whether de/serialization is supported. 49 | * @return a boolean value indicating whether the specified {@link Class type} can be de/serialized 50 | * by this {@link SessionSerializer}. 51 | * @see #canSerialize(Object) 52 | */ 53 | boolean canSerialize(Class type); 54 | 55 | /** 56 | * Determines whether the given {@link Object} can be de/serialized by this {@link SessionSerializer}. 57 | * 58 | * @param obj {@link Object} to evaluate for whether de/serialization is supported. 59 | * @return a boolean value indicating whether the specified {@link Object} can be de/serialized 60 | * by this {@link SessionSerializer}. 61 | * @see #canSerialize(Class) 62 | */ 63 | default boolean canSerialize(Object obj) { 64 | 65 | return Optional.ofNullable(obj) 66 | .map(Object::getClass) 67 | .filter(this::canSerialize) 68 | .isPresent(); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/support/EqualsDirtyPredicateUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.junit.Test; 22 | 23 | import lombok.Data; 24 | import lombok.EqualsAndHashCode; 25 | import lombok.NonNull; 26 | import lombok.RequiredArgsConstructor; 27 | 28 | /** 29 | * Unit Tests for {@link EqualsDirtyPredicate}. 30 | * 31 | * @author John Blum 32 | * @see org.junit.Test 33 | * @see org.springframework.session.data.gemfire.support.EqualsDirtyPredicate 34 | * @since 2.1.2 35 | */ 36 | public class EqualsDirtyPredicateUnitTests { 37 | 38 | @Test 39 | public void isDirtyIsIsNullSafe() { 40 | 41 | assertThat(EqualsDirtyPredicate.INSTANCE.isDirty(null, null)).isFalse(); 42 | assertThat(EqualsDirtyPredicate.INSTANCE.isDirty("one", null)).isTrue(); 43 | assertThat(EqualsDirtyPredicate.INSTANCE.isDirty(null, "one")).isTrue(); 44 | } 45 | 46 | @Test 47 | public void isDirtyWithSameObjectReturnsFalse() { 48 | 49 | Entry keyValue = Entry.newEntry(1, "one"); 50 | 51 | assertThat(EqualsDirtyPredicate.INSTANCE.isDirty(keyValue, keyValue)); 52 | } 53 | 54 | @Test 55 | public void isDirtyWithEqualObjectsReturnsFalse() { 56 | 57 | Entry entryOne = Entry.newEntry(1, "one"); 58 | Entry entryTwo = Entry.newEntry(1, "one"); 59 | 60 | assertThat(EqualsDirtyPredicate.INSTANCE.isDirty(entryOne, entryTwo)); 61 | } 62 | 63 | @Test 64 | public void isDirtyWithDifferentObjectsReturnsFalse() { 65 | 66 | Entry entryOne = Entry.newEntry(1, "one"); 67 | Entry entryTwo = Entry.newEntry(2, "two"); 68 | 69 | assertThat(EqualsDirtyPredicate.INSTANCE.isDirty(entryOne, entryTwo)); 70 | } 71 | 72 | @Data 73 | @EqualsAndHashCode 74 | @RequiredArgsConstructor(staticName = "newEntry") 75 | static class Entry { 76 | 77 | @NonNull 78 | private final Object key; 79 | 80 | @NonNull 81 | private final Object value; 82 | 83 | @Override 84 | public String toString() { 85 | return String.format("%1$s = %2$s", getKey(), getValue()); 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/serialization/pdx/AbstractPdxSerializableSessionSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.serialization.pdx; 18 | 19 | import java.util.Optional; 20 | 21 | import org.apache.geode.pdx.PdxReader; 22 | import org.apache.geode.pdx.PdxSerializer; 23 | import org.apache.geode.pdx.PdxWriter; 24 | 25 | import org.springframework.session.Session; 26 | import org.springframework.session.data.gemfire.serialization.SessionSerializer; 27 | 28 | /** 29 | * The {@link AbstractPdxSerializableSessionSerializer} class is an abstract base class containing functionality common 30 | * to all GemFire/Geode PDX-based {@link SessionSerializer} implementations. 31 | * 32 | * This class also implements GemFire/Geode's {@link PdxSerializer} interface, adapting it to the Spring Session, 33 | * Data Pivotal GemFire {@link SessionSerializer} interface. 34 | * 35 | * @author John Blum 36 | * @see org.apache.geode.pdx.PdxReader 37 | * @see org.apache.geode.pdx.PdxWriter 38 | * @see org.apache.geode.pdx.PdxSerializer 39 | * @see org.springframework.session.Session 40 | * @see org.springframework.session.data.gemfire.serialization.SessionSerializer 41 | * @since 2.0.0 42 | */ 43 | public abstract class AbstractPdxSerializableSessionSerializer 44 | implements PdxSerializer, SessionSerializer { 45 | 46 | @Override 47 | @SuppressWarnings("unchecked") 48 | public boolean toData(Object session, PdxWriter writer) { 49 | 50 | return Optional.ofNullable(session) 51 | .filter(this::canSerialize) 52 | .map(it -> { 53 | serialize((T) session, writer); 54 | return true; 55 | }) 56 | .orElse(false); 57 | } 58 | 59 | @Override 60 | public Object fromData(Class type, PdxReader reader) { 61 | 62 | return Optional.ofNullable(type) 63 | .filter(this::canSerialize) 64 | .map(it -> deserialize(reader)) 65 | .orElse(null); 66 | } 67 | 68 | @Override 69 | public boolean canSerialize(Class type) { 70 | return Optional.ofNullable(type).map(Session.class::isAssignableFrom).orElse(false); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/DeltaAwareDirtyPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import org.apache.geode.Delta; 20 | 21 | import org.springframework.lang.Nullable; 22 | 23 | /** 24 | * {@link DeltaAwareDirtyPredicate} is an {@link IsDirtyPredicate} strategy interface implementation that evaluates 25 | * the {@link Object new value} as instance of {@link Delta} and uses the {@link Delta#hasDelta()} method 26 | * to determine if the {@link Object new value} is dirty. 27 | * 28 | * @author John Blum 29 | * @see org.apache.geode.Delta 30 | * @see org.springframework.session.data.gemfire.support.IsDirtyPredicate 31 | * @since 2.1.2 32 | */ 33 | @SuppressWarnings("unused") 34 | public class DeltaAwareDirtyPredicate implements IsDirtyPredicate { 35 | 36 | public static final DeltaAwareDirtyPredicate INSTANCE = new DeltaAwareDirtyPredicate(); 37 | 38 | /** 39 | * Determines whether the {@link Object new value} is dirty by evaluating the {@link Object new value} 40 | * as an instance of {@link Delta} and invoking its {@link Delta#hasDelta()} method. 41 | * 42 | * The {@link Object new value} is considered dirty immediately and automatically if the {@link Object new value} 43 | * is not an instance of {@link Delta}. 44 | * 45 | * This method is {@literal null-safe}. 46 | * 47 | * @param oldValue {@link Object} referring to the previous value. 48 | * @param newValue {@link Object} referring to the new value. 49 | * @return a boolean value indicating whether the {@link Object new value} is dirty by evaluating 50 | * the {@link Object new value} as an instance of {@link Delta} and invoking its {@link Delta#hasDelta()} method. 51 | * Returns {@literal true} immediately if the {@link Object new value} is not an instance of {@link Delta}. 52 | * @see org.apache.geode.Delta#hasDelta() 53 | * @see org.apache.geode.Delta 54 | */ 55 | @Override 56 | public boolean isDirty(@Nullable Object oldValue, @Nullable Object newValue) { 57 | 58 | return newValue != oldValue 59 | || !(newValue instanceof Delta) 60 | || ((Delta) newValue).hasDelta(); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /docs/src/integration-test/java/docs/gemfire/indexing/HttpSessionGemFireCustomIndexingIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package docs.gemfire.indexing; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | import java.util.Map; 21 | 22 | import org.junit.Test; 23 | import org.junit.runner.RunWith; 24 | 25 | import org.springframework.beans.factory.annotation.Autowired; 26 | import org.springframework.data.gemfire.config.annotation.PeerCacheApplication; 27 | import org.springframework.data.gemfire.tests.integration.IntegrationTestsSupport; 28 | import org.springframework.session.Session; 29 | import org.springframework.session.data.gemfire.GemFireOperationsSessionRepository; 30 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 31 | import org.springframework.test.context.ContextConfiguration; 32 | import org.springframework.test.context.junit4.SpringRunner; 33 | 34 | /** 35 | * @author Rob Winch 36 | * @author John Blum 37 | */ 38 | @RunWith(SpringRunner.class) 39 | @ContextConfiguration 40 | @SuppressWarnings("unused") 41 | public class HttpSessionGemFireCustomIndexingIntegrationTests extends IntegrationTestsSupport { 42 | 43 | @Autowired 44 | private GemFireOperationsSessionRepository sessionRepository; 45 | 46 | @Test 47 | public void findByIndexName() { 48 | 49 | Session session = this.sessionRepository.createSession(); 50 | 51 | String indexValue = "HttpSessionGemFireCustomIndexingIntegrationTests-findByIndexName"; 52 | 53 | // tag::findbyindexname-set[] 54 | String indexName = "name1"; 55 | 56 | session.setAttribute(indexName, indexValue); 57 | // end::findbyindexname-set[] 58 | 59 | this.sessionRepository.save(session); 60 | 61 | // tag::findbyindexname-get[] 62 | Map idToSessions = 63 | this.sessionRepository.findByIndexNameAndIndexValue(indexName, indexValue); 64 | // end::findbyindexname-get[] 65 | 66 | assertThat(idToSessions.keySet()).containsOnly(session.getId()); 67 | 68 | this.sessionRepository.deleteById(session.getId()); 69 | } 70 | 71 | @PeerCacheApplication(name = "HttpSessionGemFireCustomIndexingIntegrationTests") 72 | @EnableGemFireHttpSession(indexableSessionAttributes = { "name1", "name2", "name3" }, 73 | regionName = "HttpSessionGemFireIndexingCustomTestRegion") 74 | static class TestConfiguration { } 75 | 76 | } 77 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/serialization/pdx/support/PdxSerializerSessionSerializerAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.serialization.pdx.support; 18 | 19 | import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; 20 | 21 | import java.util.Optional; 22 | 23 | import org.apache.geode.pdx.PdxReader; 24 | import org.apache.geode.pdx.PdxSerializer; 25 | import org.apache.geode.pdx.PdxWriter; 26 | 27 | import org.springframework.session.Session; 28 | import org.springframework.session.data.gemfire.serialization.SessionSerializer; 29 | import org.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializer; 30 | 31 | /** 32 | * The {@link PdxSerializerSessionSerializerAdapter} class is a two-way Adapter adapting a {@link SessionSerializer} 33 | * instance as an instance of {@link PdxSerializer} in a GemFire/Geode context, or adapting a {@link PdxSerializer} 34 | * as a {@link SessionSerializer} in a Spring Session context. 35 | * 36 | * @author John Blum 37 | * @see org.apache.geode.pdx.PdxSerializer 38 | * @see org.springframework.session.Session 39 | * @see org.springframework.session.data.gemfire.serialization.SessionSerializer 40 | * @see org.springframework.session.data.gemfire.serialization.pdx.AbstractPdxSerializableSessionSerializer 41 | * @since 2.0.0 42 | */ 43 | @SuppressWarnings("unused") 44 | public class PdxSerializerSessionSerializerAdapter 45 | extends AbstractPdxSerializableSessionSerializer { 46 | 47 | private final SessionSerializer sessionSerializer; 48 | 49 | public PdxSerializerSessionSerializerAdapter(SessionSerializer sessionSerializer) { 50 | this.sessionSerializer = Optional.ofNullable(sessionSerializer) 51 | .orElseThrow(() -> newIllegalArgumentException("SessionSerializer is required")); 52 | } 53 | 54 | public SessionSerializer getSessionSerializer() { 55 | return this.sessionSerializer; 56 | } 57 | 58 | @Override 59 | public void serialize(T session, PdxWriter writer) { 60 | getSessionSerializer().serialize(session, writer); 61 | } 62 | 63 | @Override 64 | public T deserialize(PdxReader reader) { 65 | return getSessionSerializer().deserialize(reader); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/expiration/config/SessionExpirationTimeoutAwareBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.expiration.config; 18 | 19 | import java.time.Duration; 20 | 21 | import org.springframework.beans.BeansException; 22 | import org.springframework.beans.factory.config.BeanPostProcessor; 23 | import org.springframework.lang.Nullable; 24 | import org.springframework.session.Session; 25 | import org.springframework.util.Assert; 26 | 27 | /** 28 | * The {@link SessionExpirationTimeoutAwareBeanPostProcessor} class is a Spring {@link BeanPostProcessor} handling 29 | * the post processing of all Spring beans defined in the Spring container implementing 30 | * the {@link SessionExpirationTimeoutAware} interface. 31 | * 32 | * @author John Blum 33 | * @see org.springframework.beans.factory.config.BeanPostProcessor 34 | * @since 2.1.0 35 | */ 36 | public class SessionExpirationTimeoutAwareBeanPostProcessor implements BeanPostProcessor { 37 | 38 | private final Duration expirationTimeout; 39 | 40 | /** 41 | * Constructs a new {@link SessionExpirationTimeoutAwareBeanPostProcessor} initialized with 42 | * the given {@link Session} {@link Duration expiration timeout}. 43 | * 44 | * @param expirationTimeout {@link Duration} specifying the length of time until {@link Session} expires. 45 | * @throws IllegalArgumentException if {@link Duration} is {@literal null}. 46 | * @see java.time.Duration 47 | */ 48 | public SessionExpirationTimeoutAwareBeanPostProcessor(Duration expirationTimeout) { 49 | 50 | Assert.notNull(expirationTimeout, "Expiration timeout is required"); 51 | 52 | this.expirationTimeout = expirationTimeout; 53 | } 54 | 55 | /** 56 | * Returns the configured {@link Session} {@link Duration expiration timeout}. 57 | * 58 | * @return the configured {@link Session} {@link Duration expiration timeout}. 59 | * @see java.time.Duration 60 | */ 61 | protected Duration getExpirationTimeout() { 62 | return this.expirationTimeout; 63 | } 64 | 65 | @Nullable @Override 66 | public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 67 | 68 | if (bean instanceof SessionExpirationTimeoutAware) { 69 | ((SessionExpirationTimeoutAware) bean).setExpirationTimeout(getExpirationTimeout()); 70 | } 71 | 72 | return bean; 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/serialization/SerializationException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.serialization; 18 | 19 | /** 20 | * The SerializationException class is a {@link RuntimeException} indicating an error occurred while attempting to 21 | * serialize a {@link org.springframework.session.Session}. 22 | * 23 | * @author John Blum 24 | * @see java.lang.RuntimeException 25 | * @since 2.0.0 26 | */ 27 | @SuppressWarnings("unused") 28 | public class SerializationException extends RuntimeException { 29 | 30 | /** 31 | * Constructs a default instance of {@link SerializationException} with no {@link String message} 32 | * or {@link Throwable cause}. 33 | * 34 | * @see java.lang.RuntimeException#RuntimeException() 35 | */ 36 | public SerializationException() { } 37 | 38 | /** 39 | * Constructs a new instance of {@link SerializationException} initialized with the given {@link String message} 40 | * describing the serialization error. 41 | * 42 | * @param message {@link String} describing the serialization error. 43 | * @see java.lang.RuntimeException#RuntimeException(String) 44 | * @see java.lang.String 45 | */ 46 | public SerializationException(String message) { 47 | super(message); 48 | } 49 | 50 | /** 51 | * Constructs a new instance of {@link SerializationException} initialized with the given {@link Throwable cause} 52 | * of the serialization error. 53 | * 54 | * @param cause {@link Throwable underlying cause} of the serialization error. 55 | * @see java.lang.RuntimeException#RuntimeException(Throwable) 56 | * @see java.lang.Throwable 57 | */ 58 | public SerializationException(Throwable cause) { 59 | super(cause); 60 | } 61 | 62 | /** 63 | * Constructs a new instance of {@link SerializationException} initialized with the given {@link String message} 64 | * describing the serialization error and {@link Throwable cause} of the serialization error. 65 | * 66 | * @param message {@link String} describing the serialization error. 67 | * @param cause {@link Throwable underlying cause} of the serialization error. 68 | * @see java.lang.RuntimeException#RuntimeException(String, Throwable) 69 | * @see java.lang.Throwable 70 | * @see java.lang.String 71 | */ 72 | public SerializationException(String message, Throwable cause) { 73 | super(message, cause); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /docs/spring-session-docs.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | // id 'org.asciidoctor.jvm.convert' version '3.2.0' 3 | // id 'org.asciidoctor.jvm.pdf' version '3.2.0' 4 | } 5 | 6 | apply plugin: 'io.spring.convention.docs' 7 | apply plugin: 'io.spring.convention.spring-test' 8 | 9 | repositories { 10 | maven { url "https://repo.spring.io/release" } 11 | } 12 | 13 | dependencies { 14 | 15 | testImplementation project(':spring-session-data-geode') 16 | testImplementation "jakarta.servlet:jakarta.servlet-api" 17 | testImplementation "org.springframework.security:spring-security-core" 18 | testImplementation "org.springframework.security:spring-security-test" 19 | testImplementation "org.springframework.security:spring-security-web" 20 | 21 | } 22 | 23 | def versions = dependencyManagement.managedVersions 24 | 25 | asciidoctor { 26 | clearSources() 27 | clearSecondarySources() 28 | sources { 29 | include "index.adoc" 30 | include "guides/*.adoc" 31 | } 32 | resources { 33 | duplicatesStrategy DuplicatesStrategy.EXCLUDE 34 | } 35 | } 36 | 37 | asciidoctorj { 38 | 39 | def ghTag = snapshotBuild ? 'master' : project.version 40 | def ghUrl = "https://github.com/spring-projects/spring-session-data-geode/tree/$ghTag" 41 | 42 | attributes 'gh-url': ghUrl, 43 | 'gh-samples-url': "$ghUrl/samples/", 44 | 'download-url' : "https://github.com/spring-projects/spring-session-data-geode/archive/${ghTag}.zip", 45 | 'docinfodir@': ".", 46 | 'highlightjsdir@': "js/highlight", 47 | // 'stylesheet' : pathToSpringCss, 48 | 'master-data-store-name' : 'Apache Geode', 49 | 'master-data-store-version' : '112', 50 | // 'spring-version' : "$springVersion", 51 | 'spring-version' : versions['org.springframework:spring-core'], 52 | 'spring-data-commons-version' : "$springDataCommonsVersion", 53 | 'spring-data-geode-version' : "$springDataGeodeVersion", 54 | 'spring-session-core-version' : "$springSessionVersion", 55 | 'spring-session-data-geode-version' : project.version, 56 | 'docs-itest-dir' : rootProject.projectDir.path + '/docs/src/integration-test/java/', 57 | 'docs-test-dir' : rootProject.projectDir.path + '/docs/src/test/java/', 58 | 'docs-test-resources-dir' : rootProject.projectDir.path + '/docs/src/test/resources/', 59 | 'samples-dir' : rootProject.projectDir.path + '/samples/', 60 | 'session-main-resources-dir' : rootProject.projectDir.path + '/spring-session/src/main/resources/', 61 | 'version-snapshot': snapshotBuild, 62 | 'version-milestone': milestoneBuild, 63 | 'version-release': releaseBuild 64 | 65 | } 66 | 67 | asciidoctorPdf { 68 | clearSources() 69 | clearSecondarySources() 70 | sources { 71 | include "index.adoc" 72 | // include "guides/*.adoc" 73 | } 74 | resources { 75 | duplicatesStrategy DuplicatesStrategy.EXCLUDE 76 | } 77 | } 78 | 79 | javadoc { 80 | configure(options) { 81 | links = [ 82 | "https://docs.spring.io/spring/docs/current/javadoc-api/", 83 | "https://docs.spring.io/spring-data/commons/docs/current/api/index.html", 84 | "https://docs.spring.io/spring-data/geode/docs/current/api/", 85 | "https://docs.spring.io/spring-session/docs/${springSessionVersion}/api/", 86 | "https://geode.apache.org/releases/latest/javadoc/index.html", 87 | ] 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /samples/boot/gemfire/src/integration-test/java/sample/AttributeTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package sample; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | import java.io.IOException; 21 | 22 | import org.junit.After; 23 | import org.junit.Before; 24 | import org.junit.BeforeClass; 25 | import org.junit.Test; 26 | import org.junit.runner.RunWith; 27 | 28 | import org.springframework.beans.factory.annotation.Autowired; 29 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 30 | import org.springframework.boot.test.context.SpringBootTest; 31 | import org.springframework.boot.test.context.SpringBootTest.WebEnvironment; 32 | import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport; 33 | import org.springframework.test.context.junit4.SpringRunner; 34 | import org.springframework.test.web.servlet.MockMvc; 35 | import org.springframework.test.web.servlet.htmlunit.webdriver.MockMvcHtmlUnitDriverBuilder; 36 | 37 | import org.openqa.selenium.WebDriver; 38 | 39 | import sample.client.Application; 40 | import sample.pages.HomePage; 41 | import sample.server.GemFireServer; 42 | 43 | /** 44 | * @author Eddú Meléndez 45 | */ 46 | @RunWith(SpringRunner.class) 47 | @SpringBootTest(classes = Application.class, webEnvironment = WebEnvironment.MOCK) 48 | @AutoConfigureMockMvc 49 | public class AttributeTests extends ForkingClientServerIntegrationTestsSupport { 50 | 51 | @Autowired 52 | private MockMvc mockMvc; 53 | 54 | private WebDriver driver; 55 | 56 | @BeforeClass 57 | public static void startGeodeServer() throws IOException { 58 | startGeodeServer(GemFireServer.class); 59 | } 60 | 61 | @Before 62 | public void setup() { 63 | this.driver = MockMvcHtmlUnitDriverBuilder.mockMvcSetup(this.mockMvc).build(); 64 | } 65 | 66 | @After 67 | public void tearDown() { 68 | this.driver.quit(); 69 | } 70 | 71 | @Test 72 | public void noAttributes() { 73 | 74 | HomePage homePage = HomePage.go(this.driver, HomePage.class); 75 | 76 | homePage.assertAt(); 77 | 78 | assertThat(homePage.attributes().size()).isEqualTo(0); 79 | } 80 | 81 | @Test 82 | public void createAttribute() { 83 | 84 | HomePage homePage = HomePage.go(this.driver, HomePage.class); 85 | 86 | homePage = homePage.assertAt().form().attributeName("a").attributeValue("b").submit(HomePage.class); 87 | 88 | assertThat(homePage.attributes()).extracting("attributeName").containsOnly("requestCount", "a"); 89 | assertThat(homePage.attributes()).extracting("attributeValue").containsOnly("1", "b"); 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/serialization/SessionSerializerTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.serialization; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | import static org.mockito.ArgumentMatchers.any; 20 | import static org.mockito.ArgumentMatchers.eq; 21 | import static org.mockito.Mockito.never; 22 | import static org.mockito.Mockito.times; 23 | import static org.mockito.Mockito.verify; 24 | import static org.mockito.Mockito.when; 25 | 26 | import org.junit.Test; 27 | import org.junit.runner.RunWith; 28 | import org.mockito.Mock; 29 | import org.mockito.junit.MockitoJUnitRunner; 30 | 31 | /** 32 | * Unit Tests for the {@link SessionSerializer} interface. 33 | * 34 | * @author John Blum 35 | * @see org.junit.Test 36 | * @see org.mockito.Mock 37 | * @see org.mockito.Mockito 38 | * @see org.springframework.session.data.gemfire.serialization.SessionSerializer 39 | * @since 2.0.0 40 | */ 41 | @RunWith(MockitoJUnitRunner.class) 42 | public class SessionSerializerTests { 43 | 44 | @Mock 45 | @SuppressWarnings("rawtypes") 46 | private SessionSerializer sessionSerializer; 47 | 48 | @Test 49 | @SuppressWarnings("unchecked") 50 | public void canSerializeWithSerializableObjectReturnsTrue() { 51 | 52 | when(this.sessionSerializer.canSerialize(any(Class.class))).thenReturn(true); 53 | when(this.sessionSerializer.canSerialize(any(Object.class))).thenCallRealMethod(); 54 | 55 | assertThat(this.sessionSerializer.canSerialize("test")).isTrue(); 56 | 57 | verify(this.sessionSerializer, times(1)).canSerialize(eq("test")); 58 | verify(this.sessionSerializer, times(1)).canSerialize(eq(String.class)); 59 | } 60 | 61 | @Test 62 | @SuppressWarnings("unchecked") 63 | public void canSerializeWithNullReturnFalse() { 64 | 65 | assertThat(this.sessionSerializer.canSerialize((Object) null)).isFalse(); 66 | 67 | verify(this.sessionSerializer, times(1)).canSerialize(eq((Object) null)); 68 | verify(this.sessionSerializer, never()).canSerialize(any(Class.class)); 69 | } 70 | 71 | @Test 72 | @SuppressWarnings("unchecked") 73 | public void canSerializeWithNonSerializableObjectReturnFalse() { 74 | 75 | when(this.sessionSerializer.canSerialize(any(Class.class))).thenReturn(false); 76 | when(this.sessionSerializer.canSerialize(any(Object.class))).thenCallRealMethod(); 77 | 78 | assertThat(this.sessionSerializer.canSerialize("test")).isFalse(); 79 | 80 | verify(this.sessionSerializer, times(1)).canSerialize(eq("test")); 81 | verify(this.sessionSerializer, times(1)).canSerialize(eq(String.class)); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /samples/xml/gemfire-clientserver/src/main/java/sample/client/ApacheGeodeServerWebApplicationInitializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package sample.client; 17 | 18 | import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newRuntimeException; 19 | 20 | import java.io.IOException; 21 | import java.net.URL; 22 | import java.util.List; 23 | import java.util.Objects; 24 | 25 | import jakarta.servlet.ServletContext; 26 | 27 | import org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport; 28 | import org.springframework.data.gemfire.tests.process.ProcessWrapper; 29 | import org.springframework.data.gemfire.util.CollectionUtils; 30 | import org.springframework.util.StringUtils; 31 | import org.springframework.web.WebApplicationInitializer; 32 | 33 | import io.github.classgraph.ClassGraph; 34 | import sample.server.GemFireServer; 35 | 36 | /** 37 | * Spring {@link WebApplicationInitializer} used to bootstrap an Apache Geode server process. 38 | * 39 | * @author John Blum 40 | * @see sample.server.GemFireServer 41 | * @see org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport 42 | * @see org.springframework.data.gemfire.tests.process.ProcessWrapper 43 | * @see org.springframework.web.WebApplicationInitializer 44 | * @since 3.0.0 45 | */ 46 | public class ApacheGeodeServerWebApplicationInitializer extends ForkingClientServerIntegrationTestsSupport 47 | implements WebApplicationInitializer { 48 | 49 | @Override 50 | public void onStartup(ServletContext servletContext) { 51 | 52 | try { 53 | 54 | //System.err.printf("JAVA CLASSPATH [%s]%n", javaSystemClasspath()); 55 | //System.err.printf("THREAD CONTEXT CLASSLOADER CLASSPATH [%s]%n", contextClassLoaderClasspath()); 56 | //System.err.printf("CLASS-GRAPH CLASSLOADER CLASSPATH [%s]%n", classGraphClassLoaderClasspath()); 57 | 58 | registerGeodeServerRuntimeShutdownHook( 59 | startGeodeServer(classGraphClasspath(), GemFireServer.class)); 60 | } 61 | catch(IOException cause) { 62 | throw newRuntimeException(cause, "Failed to start the Apache Geode Server"); 63 | } 64 | } 65 | 66 | static String classGraphClasspath() { 67 | 68 | List classpathElements = CollectionUtils.nullSafeList(new ClassGraph().getClasspathURLs()).stream() 69 | .filter(Objects::nonNull) 70 | .map(URL::getFile) 71 | .filter(StringUtils::hasText) 72 | .toList(); 73 | 74 | return StringUtils.collectionToDelimitedString(classpathElements, System.getProperty("path.separator")); 75 | } 76 | 77 | static ProcessWrapper registerGeodeServerRuntimeShutdownHook(ProcessWrapper geodeServer) { 78 | 79 | if (geodeServer != null) { 80 | Runtime.getRuntime().addShutdownHook(new Thread(() -> { 81 | ForkingClientServerIntegrationTestsSupport.stop(geodeServer); 82 | }, "Apache Geode Server Runtime Shutdown Hook")); 83 | } 84 | 85 | return geodeServer; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/AbstractSession.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.support; 17 | 18 | import java.time.Duration; 19 | import java.time.Instant; 20 | import java.util.Set; 21 | 22 | import org.springframework.session.Session; 23 | 24 | /** 25 | * Abstract base class for implementations of the {@link Session} interface in order to simplify the implementation 26 | * of various {@link Session} types and their capabilities. 27 | * 28 | * @author John Blum 29 | * @see java.time.Duration 30 | * @see java.time.Instant 31 | * @see org.springframework.session.Session 32 | * @since 2.0.0 33 | */ 34 | public class AbstractSession implements Session { 35 | 36 | public static final String NOT_IMPLEMENTED = "Not Implemented"; 37 | 38 | @Override 39 | public String getId() { 40 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 41 | } 42 | 43 | @Override 44 | public void setAttribute(String attributeName, Object attributeValue) { 45 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 46 | } 47 | 48 | @Override 49 | public T getAttribute(String attributeName) { 50 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 51 | } 52 | 53 | @Override 54 | public T getAttributeOrDefault(String name, T defaultValue) { 55 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 56 | } 57 | 58 | @Override 59 | public T getRequiredAttribute(String name) { 60 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 61 | } 62 | 63 | @Override 64 | public Set getAttributeNames() { 65 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 66 | } 67 | 68 | @Override 69 | public boolean isExpired() { 70 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 71 | } 72 | 73 | @Override 74 | public Instant getCreationTime() { 75 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 76 | } 77 | 78 | @Override 79 | public void setLastAccessedTime(Instant lastAccessedTime) { 80 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 81 | } 82 | 83 | @Override 84 | public Instant getLastAccessedTime() { 85 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 86 | } 87 | 88 | @Override 89 | public void setMaxInactiveInterval(Duration interval) { 90 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 91 | } 92 | 93 | @Override 94 | public Duration getMaxInactiveInterval() { 95 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 96 | } 97 | 98 | @Override 99 | public String changeSessionId() { 100 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 101 | } 102 | 103 | @Override 104 | public void removeAttribute(String attributeName) { 105 | throw new UnsupportedOperationException(NOT_IMPLEMENTED); 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/expiration/config/FixedDurationExpirationSessionRepositoryBeanPostProcessor.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.expiration.config; 18 | 19 | import java.time.Duration; 20 | 21 | import org.springframework.beans.BeansException; 22 | import org.springframework.beans.factory.config.BeanPostProcessor; 23 | import org.springframework.lang.Nullable; 24 | import org.springframework.session.Session; 25 | import org.springframework.session.SessionRepository; 26 | import org.springframework.session.data.gemfire.expiration.repository.FixedDurationExpirationSessionRepository; 27 | 28 | /** 29 | * The {@link FixedDurationExpirationSessionRepositoryBeanPostProcessor} class wraps an existing, data store specific, 30 | * instance of {@link SessionRepository} in an instance of {@link FixedDurationExpirationSessionRepository} initialized 31 | * with a provided {@link Duration} for the expiration timeout to implement lazy, fixed {@link Duration} expiration 32 | * on all {@link Session Sessions}. 33 | * 34 | * @author John Blum 35 | * @see org.springframework.beans.factory.config.BeanPostProcessor 36 | * @see org.springframework.session.Session 37 | * @see org.springframework.session.SessionRepository 38 | * @see org.springframework.session.data.gemfire.expiration.repository.FixedDurationExpirationSessionRepository 39 | * @see Absolute Session Timeouts 40 | * @since 2.1.0 41 | */ 42 | @SuppressWarnings("unused") 43 | public class FixedDurationExpirationSessionRepositoryBeanPostProcessor implements BeanPostProcessor { 44 | 45 | private final Duration expirationTimeout; 46 | 47 | /** 48 | * Constructs a new instance of {@link FixedDurationExpirationSessionRepositoryBeanPostProcessor} initialized with 49 | * the given {@link Duration} to implement lazy, fixed {@link Duration} expiration policy 50 | * on all {@link Session Sessions}. 51 | * 52 | * @param expirationTimeout {@link Duration} indicating the length of time until the {@link Session} expires. 53 | * @see java.time.Duration 54 | */ 55 | public FixedDurationExpirationSessionRepositoryBeanPostProcessor(@Nullable Duration expirationTimeout) { 56 | this.expirationTimeout = expirationTimeout; 57 | } 58 | 59 | /** 60 | * Returns the configured {@link Session} {@link Duration expiration timeout}. 61 | * 62 | * @return the configured {@link Session} {@link Duration expiration timeout}. 63 | * @see java.time.Duration 64 | */ 65 | protected Duration getExpirationTimeout() { 66 | return this.expirationTimeout; 67 | } 68 | 69 | @Nullable @Override @SuppressWarnings("unchecked") 70 | public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 71 | 72 | return bean instanceof SessionRepository 73 | ? new FixedDurationExpirationSessionRepository<>((SessionRepository) bean, getExpirationTimeout()) 74 | : bean; 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/support/DeltaAwareDirtyPredicateUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | import static org.mockito.Mockito.mock; 21 | import static org.mockito.Mockito.never; 22 | import static org.mockito.Mockito.times; 23 | import static org.mockito.Mockito.verify; 24 | import static org.mockito.Mockito.when; 25 | 26 | import org.junit.Test; 27 | 28 | import org.apache.geode.Delta; 29 | 30 | /** 31 | * Unit Tests for {@link DeltaAwareDirtyPredicate}. 32 | * 33 | * @author John Blum 34 | * @see org.junit.Test 35 | * @see org.springframework.session.data.gemfire.support.DeltaAwareDirtyPredicate 36 | * @since 2.1.2 37 | */ 38 | public class DeltaAwareDirtyPredicateUnitTests { 39 | 40 | @Test 41 | public void isDirtyIsNullSafe() { 42 | 43 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty(null, null)).isTrue(); 44 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty("one", null)).isTrue(); 45 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty(null, "one")).isTrue(); 46 | } 47 | 48 | @Test 49 | public void isDirtyWithNonDeltaObjectReturnsTrue() { 50 | 51 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty("one", "one")).isTrue(); 52 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty("one", "two")).isTrue(); 53 | } 54 | 55 | @Test 56 | public void isDirtyWithSameDeltaObjectReturnsTrue() { 57 | 58 | Delta mockDelta = mock(Delta.class); 59 | 60 | when(mockDelta.hasDelta()).thenReturn(true); 61 | 62 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty(mockDelta, mockDelta)).isTrue(); 63 | 64 | verify(mockDelta, times(1)).hasDelta(); 65 | } 66 | 67 | @Test 68 | public void isDirtyWithSameDeltaObjectReturnsFalse() { 69 | 70 | Delta mockDelta = mock(Delta.class); 71 | 72 | when(mockDelta.hasDelta()).thenReturn(false); 73 | 74 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty(mockDelta, mockDelta)).isFalse(); 75 | 76 | verify(mockDelta, times(1)).hasDelta(); 77 | } 78 | 79 | @Test 80 | public void isDirtyWithStringAndDeltaObjectReturnsTrue() { 81 | 82 | Delta mockDelta = mock(Delta.class); 83 | 84 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty("one", mockDelta)).isTrue(); 85 | 86 | verify(mockDelta, never()).hasDelta(); 87 | } 88 | 89 | @Test 90 | public void isDirtyWithNullAndDeltaObjectReturnsTrue() { 91 | 92 | Delta mockDelta = mock(Delta.class); 93 | 94 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty(null, mockDelta)).isTrue(); 95 | 96 | verify(mockDelta, never()).hasDelta(); 97 | } 98 | 99 | @Test 100 | public void isDirtyWithDeltaObjectAndNullReturnsTrue() { 101 | 102 | Delta mockDelta = mock(Delta.class); 103 | 104 | assertThat(DeltaAwareDirtyPredicate.INSTANCE.isDirty(mockDelta, null)).isTrue(); 105 | 106 | verify(mockDelta, never()).hasDelta(); 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/expiration/support/FixedTimeoutSessionExpirationPolicy.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.expiration.support; 18 | 19 | import java.time.Duration; 20 | import java.util.Optional; 21 | 22 | import org.springframework.lang.NonNull; 23 | import org.springframework.session.Session; 24 | import org.springframework.session.data.gemfire.expiration.SessionExpirationPolicy; 25 | import org.springframework.util.Assert; 26 | 27 | /** 28 | * An implementation of the {@link SessionExpirationPolicy} interface that specifies an expiration policy based on 29 | * a {@link Duration fixed duration of time}. 30 | * 31 | * In other words, the {@link Session} will timeout after a {@link Duration fixed duration of time} even if 32 | * the {@link Session} is still active (i.e. not idle). 33 | * 34 | * @author John Blum 35 | * @see java.time.Duration 36 | * @see org.springframework.session.Session 37 | * @see org.springframework.session.data.gemfire.expiration.SessionExpirationPolicy 38 | * @see org.springframework.session.data.gemfire.expiration.support.IdleTimeoutSessionExpirationPolicy 39 | * @since 2.1.0 40 | */ 41 | @SuppressWarnings("unused") 42 | public class FixedTimeoutSessionExpirationPolicy extends IdleTimeoutSessionExpirationPolicy { 43 | 44 | private final Duration fixedTimeout; 45 | 46 | /** 47 | * Constructs a new {@link FixedTimeoutSessionExpirationPolicy} initialized with 48 | * the given {@link Duration fixed, expiration timeout}. 49 | * 50 | * @param fixedTimeout {@link Duration fixed length of time} until the {@link Session} will expire. 51 | * @throws IllegalArgumentException if the {@link Duration fixed timeout} is {@literal null}. 52 | * @see java.time.Duration 53 | */ 54 | public FixedTimeoutSessionExpirationPolicy(@NonNull Duration fixedTimeout) { 55 | 56 | super(null); 57 | 58 | Assert.notNull(fixedTimeout, "Fixed expiration timeout is required"); 59 | 60 | this.fixedTimeout = fixedTimeout; 61 | } 62 | 63 | /** 64 | * Return the configured {@link Duration fixed expiration timeout}. 65 | * 66 | * @return the configured {@link Duration fixed expiration timeout}. 67 | * @see java.time.Duration 68 | */ 69 | protected Duration getFixedTimeout() { 70 | return this.fixedTimeout; 71 | } 72 | 73 | @Override 74 | public Optional determineExpirationTimeout(@NonNull Session session) { 75 | 76 | Optional idleTimeout = super.determineExpirationTimeout(session); 77 | 78 | Duration fixedExpirationTimeout = getFixedTimeout().minus(computeTimeSinceCreation(session)); 79 | 80 | return idleTimeout.filter(it -> it.compareTo(fixedExpirationTimeout) <= 0).isPresent() 81 | ? Optional.empty() : Optional.of(fixedExpirationTimeout); 82 | } 83 | 84 | private Duration computeTimeSinceCreation(@NonNull Session session) { 85 | 86 | long timeSinceCreation = Math.max(System.currentTimeMillis() - session.getCreationTime().toEpochMilli(), 0L); 87 | 88 | return Duration.ofMillis(timeSinceCreation); 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/serialization/pdx/support/ComposablePdxSerializer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.serialization.pdx.support; 18 | 19 | import static java.util.stream.StreamSupport.stream; 20 | import static org.springframework.data.gemfire.util.ArrayUtils.nullSafeArray; 21 | import static org.springframework.data.gemfire.util.CollectionUtils.nullSafeIterable; 22 | import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; 23 | 24 | import java.util.Arrays; 25 | import java.util.Collections; 26 | import java.util.Iterator; 27 | import java.util.List; 28 | import java.util.Objects; 29 | import java.util.Optional; 30 | import java.util.stream.Collectors; 31 | 32 | import org.apache.geode.pdx.PdxReader; 33 | import org.apache.geode.pdx.PdxSerializer; 34 | import org.apache.geode.pdx.PdxWriter; 35 | 36 | /** 37 | * The {@link ComposablePdxSerializer} class is a composite of {@link PdxSerializer} objects implementing 38 | * the Composite Software Design Pattern. 39 | * 40 | * @author John Blum 41 | * @see java.lang.Iterable 42 | * @see org.apache.geode.pdx.PdxSerializer 43 | * @since 2.0.0 44 | */ 45 | @SuppressWarnings("unused") 46 | public class ComposablePdxSerializer implements PdxSerializer, Iterable { 47 | 48 | private final List pdxSerializers; 49 | 50 | public static PdxSerializer compose(PdxSerializer... pdxSerializers) { 51 | return compose(Arrays.asList(nullSafeArray(pdxSerializers, PdxSerializer.class))); 52 | } 53 | 54 | public static PdxSerializer compose(Iterable pdxSerializers) { 55 | 56 | List pdxSerializerList = 57 | stream(nullSafeIterable(pdxSerializers).spliterator(), false) 58 | .filter(Objects::nonNull).collect(Collectors.toList()); 59 | 60 | return (pdxSerializerList.isEmpty() ? null 61 | : (pdxSerializerList.size() == 1 ? pdxSerializerList.get(0) 62 | : new ComposablePdxSerializer(pdxSerializerList))); 63 | } 64 | 65 | private ComposablePdxSerializer(List pdxSerializers) { 66 | 67 | this.pdxSerializers = Optional.ofNullable(pdxSerializers) 68 | .map(it -> Collections.unmodifiableList(pdxSerializers)) 69 | .orElseThrow(() -> newIllegalArgumentException("PdxSerializers [%s] are required", pdxSerializers)); 70 | } 71 | 72 | @Override 73 | public Iterator iterator() { 74 | return this.pdxSerializers.iterator(); 75 | } 76 | 77 | @Override 78 | public boolean toData(Object obj, PdxWriter out) { 79 | 80 | for (PdxSerializer pdxSerializer : this) { 81 | if (pdxSerializer.toData(obj, out)) { 82 | return true; 83 | } 84 | } 85 | 86 | return false; 87 | } 88 | 89 | @Override 90 | public Object fromData(Class type, PdxReader in) { 91 | 92 | for (PdxSerializer pdxSerializer : this) { 93 | 94 | Object obj = pdxSerializer.fromData(type, in); 95 | 96 | if (obj != null) { 97 | return obj; 98 | } 99 | } 100 | 101 | return null; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/integration-test/java/org/springframework/session/data/gemfire/serialization/DataSerializationConfigurationIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.serialization; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | import org.junit.Test; 21 | import org.junit.runner.RunWith; 22 | 23 | import org.apache.geode.cache.GemFireCache; 24 | import org.apache.geode.cache.client.ClientRegionShortcut; 25 | 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.beans.factory.annotation.Qualifier; 28 | import org.springframework.data.gemfire.config.annotation.ClientCacheApplication; 29 | import org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests; 30 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 31 | import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; 32 | import org.springframework.test.context.ContextConfiguration; 33 | import org.springframework.test.context.junit4.SpringRunner; 34 | 35 | /** 36 | * Integration tests to assert that GemFire/Geode's Data Serialization framework is configured and applied properly. 37 | * 38 | * @author John Blum 39 | * @see org.junit.Test 40 | * @see org.apache.geode.DataSerializer 41 | * @see org.apache.geode.cache.GemFireCache 42 | * @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication 43 | * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests 44 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession 45 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration 46 | * @see org.springframework.test.context.ContextConfiguration 47 | * @see org.springframework.test.context.junit4.SpringRunner 48 | * @since 2.0.0 49 | */ 50 | @RunWith(SpringRunner.class) 51 | @ContextConfiguration 52 | @SuppressWarnings("unused") 53 | public class DataSerializationConfigurationIntegrationTests extends AbstractGemFireIntegrationTests { 54 | 55 | @Autowired 56 | @Qualifier(GemFireHttpSessionConfiguration.SESSION_SERIALIZER_BEAN_ALIAS) 57 | private SessionSerializer configuredSessionSerializer; 58 | 59 | @Autowired 60 | @Qualifier(GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME) 61 | private SessionSerializer dataSerializableSessionSerialzer; 62 | 63 | @Autowired 64 | private GemFireCache gemfireCache; 65 | 66 | @Test 67 | public void gemfireCachePdxSerializerIsNull() { 68 | assertThat(this.gemfireCache.getPdxSerializer()).isNull(); 69 | } 70 | 71 | @Test 72 | public void configuredSessionSerializerIsSetToDataSerializableSessionSerializer() { 73 | assertThat(this.configuredSessionSerializer).isSameAs(this.dataSerializableSessionSerialzer); 74 | 75 | } 76 | 77 | @ClientCacheApplication( 78 | name = "DataSerializationConfigurationIntegrationTests", 79 | logLevel = "error" 80 | ) 81 | @EnableGemFireHttpSession( 82 | clientRegionShortcut = ClientRegionShortcut.LOCAL, 83 | poolName = "DEFAULT", 84 | sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME 85 | ) 86 | static class TestConfiguration { } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/config/CustomCookieSerializerConfigurationUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.config; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | import static org.mockito.Mockito.mock; 20 | 21 | import org.junit.Test; 22 | import org.junit.runner.RunWith; 23 | 24 | import org.springframework.beans.factory.annotation.Autowired; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.session.data.gemfire.AbstractGemFireUnitTests; 28 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 29 | import org.springframework.session.web.http.CookieHttpSessionIdResolver; 30 | import org.springframework.session.web.http.CookieSerializer; 31 | import org.springframework.session.web.http.HttpSessionIdResolver; 32 | import org.springframework.session.web.http.SessionRepositoryFilter; 33 | import org.springframework.test.context.ContextConfiguration; 34 | import org.springframework.test.context.junit4.SpringRunner; 35 | 36 | /** 37 | * Unit Tests testing the configuration of a custom {@link CookieSerializer} in the context of SSDG. 38 | * 39 | * @author John Blum 40 | * @see org.junit.Test 41 | * @see org.mockito.Mockito 42 | * @see org.springframework.context.annotation.Bean 43 | * @see org.springframework.context.annotation.Configuration 44 | * @see org.springframework.session.data.gemfire.AbstractGemFireUnitTests 45 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession 46 | * @see org.springframework.session.web.http.CookieHttpSessionIdResolver 47 | * @see org.springframework.session.web.http.CookieSerializer 48 | * @see org.springframework.session.web.http.HttpSessionIdResolver 49 | * @see org.springframework.session.web.http.SessionRepositoryFilter 50 | * @see org.springframework.test.context.ContextConfiguration 51 | * @see org.springframework.test.context.junit4.SpringRunner 52 | * @since 1.0.0 53 | */ 54 | @RunWith(SpringRunner.class) 55 | @ContextConfiguration 56 | public class CustomCookieSerializerConfigurationUnitTests extends AbstractGemFireUnitTests { 57 | 58 | @Autowired 59 | private CookieSerializer cookieSerializer; 60 | 61 | @Autowired 62 | private SessionRepositoryFilter filter; 63 | 64 | @Test 65 | public void customCookieSerializerConfigured() { 66 | 67 | assertThat(this.filter).isNotNull(); 68 | assertThat(this.cookieSerializer).isInstanceOf(TestCookieSerializer.class); 69 | 70 | HttpSessionIdResolver configuredHttpSessionIdResolver = 71 | getValue(this.filter, "httpSessionIdResolver"); 72 | 73 | assertThat(configuredHttpSessionIdResolver).isInstanceOf(CookieHttpSessionIdResolver.class); 74 | 75 | CookieSerializer configuredCookieSerializer = 76 | getValue(configuredHttpSessionIdResolver, "cookieSerializer"); 77 | 78 | assertThat(configuredCookieSerializer).isSameAs(this.cookieSerializer); 79 | } 80 | 81 | @Configuration 82 | @EnableGemFireHttpSession 83 | static class TestConfiguration extends BaseTestConfiguration { 84 | 85 | @Bean 86 | CookieSerializer mockCookieSerializer() { 87 | return mock(TestCookieSerializer.class); 88 | } 89 | } 90 | 91 | interface TestCookieSerializer extends CookieSerializer { } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/integration-test/java/org/springframework/session/data/gemfire/serialization/PdxSerializationConfigurationIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire.serialization; 17 | 18 | import static org.assertj.core.api.Assertions.assertThat; 19 | 20 | import org.junit.Test; 21 | import org.junit.runner.RunWith; 22 | 23 | import org.apache.geode.cache.GemFireCache; 24 | import org.apache.geode.cache.client.ClientRegionShortcut; 25 | 26 | import org.springframework.beans.factory.annotation.Autowired; 27 | import org.springframework.beans.factory.annotation.Qualifier; 28 | import org.springframework.data.gemfire.config.annotation.ClientCacheApplication; 29 | import org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests; 30 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 31 | import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; 32 | import org.springframework.test.context.ContextConfiguration; 33 | import org.springframework.test.context.junit4.SpringRunner; 34 | 35 | /** 36 | * Integration tests to assert that GemFire/Geode's PDX Serialization framework is configured and applied properly. 37 | * 38 | * @author John Blum 39 | * @see org.junit.Test 40 | * @see org.apache.geode.cache.GemFireCache 41 | * @see org.apache.geode.pdx.PdxSerializer 42 | * @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication 43 | * @see org.springframework.session.data.gemfire.AbstractGemFireIntegrationTests 44 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession 45 | * @see org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration 46 | * @see org.springframework.test.context.ContextConfiguration 47 | * @see org.springframework.test.context.junit4.SpringRunner 48 | * @since 2.0.0 49 | */ 50 | @RunWith(SpringRunner.class) 51 | @ContextConfiguration 52 | @SuppressWarnings("unused") 53 | public class PdxSerializationConfigurationIntegrationTests extends AbstractGemFireIntegrationTests { 54 | 55 | @Autowired 56 | @Qualifier(GemFireHttpSessionConfiguration.SESSION_SERIALIZER_BEAN_ALIAS) 57 | private SessionSerializer configuredSessionSerializer; 58 | 59 | @Autowired 60 | @Qualifier(GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME) 61 | private SessionSerializer pdxSerializableSessionSerialzer; 62 | 63 | @Autowired 64 | private GemFireCache gemfireCache; 65 | 66 | @Test 67 | public void gemfireCachePdxSerializerIsSetToPdxSerializableSessionSerializer() { 68 | assertThat(this.gemfireCache.getPdxSerializer()).isSameAs(this.pdxSerializableSessionSerialzer); 69 | } 70 | 71 | @Test 72 | public void configuredSessionSerializerIsSetToPdxSerializableSessionSerializer() { 73 | assertThat(this.configuredSessionSerializer).isSameAs(this.pdxSerializableSessionSerialzer); 74 | 75 | } 76 | 77 | @ClientCacheApplication( 78 | name = "PdxSerializationConfigurationIntegrationTests", 79 | logLevel = "error" 80 | ) 81 | @EnableGemFireHttpSession( 82 | clientRegionShortcut = ClientRegionShortcut.LOCAL, 83 | poolName = "DEFAULT", 84 | sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_PDX_SERIALIZER_BEAN_NAME 85 | ) 86 | @SuppressWarnings("all") 87 | static class TestConfiguration { } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/integration-test/java/org/springframework/session/data/gemfire/ConcurrentSessionOperationsUsingClientProxyRegionIntegrationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package org.springframework.session.data.gemfire; 17 | 18 | import java.io.IOException; 19 | 20 | import org.junit.BeforeClass; 21 | import org.junit.runner.RunWith; 22 | 23 | import org.apache.geode.cache.Region; 24 | import org.apache.geode.cache.client.ClientCache; 25 | import org.apache.geode.cache.client.ClientRegionShortcut; 26 | 27 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 28 | import org.springframework.data.gemfire.config.annotation.CacheServerApplication; 29 | import org.springframework.data.gemfire.config.annotation.ClientCacheApplication; 30 | import org.springframework.session.Session; 31 | import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession; 32 | import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration; 33 | import org.springframework.test.context.ContextConfiguration; 34 | import org.springframework.test.context.junit4.SpringRunner; 35 | 36 | /** 37 | * Integration Tests testing the concurrent access of a {@link Session} stored in an Apache Geode 38 | * {@link ClientCache client} {@link ClientRegionShortcut#PROXY} {@link Region}. 39 | * 40 | * @author John Blum 41 | * @see org.junit.Test 42 | * @see org.apache.geode.cache.Region 43 | * @see org.apache.geode.cache.client.ClientCache 44 | * @see org.springframework.context.annotation.AnnotationConfigApplicationContext 45 | * @see org.springframework.data.gemfire.config.annotation.CacheServerApplication 46 | * @see org.springframework.data.gemfire.config.annotation.ClientCacheApplication 47 | * @see org.springframework.session.Session 48 | * @see org.springframework.session.data.gemfire.AbstractConcurrentSessionOperationsIntegrationTests 49 | * @see org.springframework.test.context.ContextConfiguration 50 | * @see org.springframework.test.context.junit4.SpringRunner 51 | * @since 2.1.x 52 | */ 53 | @RunWith(SpringRunner.class) 54 | @ContextConfiguration( 55 | classes = ConcurrentSessionOperationsUsingClientProxyRegionIntegrationTests.GemFireClientConfiguration.class 56 | ) 57 | public class ConcurrentSessionOperationsUsingClientProxyRegionIntegrationTests 58 | extends AbstractConcurrentSessionOperationsIntegrationTests { 59 | 60 | @BeforeClass 61 | public static void startGemFireServer() throws IOException { 62 | startGemFireServer(GemFireServerConfiguration.class); 63 | } 64 | 65 | @ClientCacheApplication(subscriptionEnabled = true) 66 | @EnableGemFireHttpSession( 67 | clientRegionShortcut = ClientRegionShortcut.PROXY, 68 | poolName = "DEFAULT", 69 | sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME 70 | ) 71 | static class GemFireClientConfiguration { } 72 | 73 | @CacheServerApplication(name = "ConcurrentSessionOperationsUsingClientProxyRegionIntegrationTests") 74 | @EnableGemFireHttpSession( 75 | sessionSerializerBeanName = GemFireHttpSessionConfiguration.SESSION_DATA_SERIALIZER_BEAN_NAME 76 | ) 77 | static class GemFireServerConfiguration { 78 | 79 | public static void main(String[] args) { 80 | 81 | AnnotationConfigApplicationContext applicationContext = 82 | new AnnotationConfigApplicationContext(GemFireServerConfiguration.class); 83 | 84 | applicationContext.registerShutdownHook(); 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/expiration/config/FixedDurationExpirationSessionRepositoryBeanPostProcessorUnitTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.expiration.config; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | import static org.mockito.Mockito.mock; 21 | 22 | import java.lang.reflect.Method; 23 | import java.time.Duration; 24 | 25 | import org.junit.Test; 26 | 27 | import org.springframework.session.SessionRepository; 28 | import org.springframework.session.data.gemfire.expiration.repository.FixedDurationExpirationSessionRepository; 29 | import org.springframework.util.ReflectionUtils; 30 | 31 | /** 32 | * Unit tests for {@link FixedDurationExpirationSessionRepositoryBeanPostProcessor}. 33 | * 34 | * @author John Blum 35 | * @see org.junit.Test 36 | * @see org.mockito.Mockito 37 | * @see org.springframework.session.data.gemfire.expiration.config.FixedDurationExpirationSessionRepositoryBeanPostProcessor 38 | * @since 2.1.0 39 | */ 40 | public class FixedDurationExpirationSessionRepositoryBeanPostProcessorUnitTests { 41 | 42 | @SuppressWarnings("unchecked") 43 | private T invokeMethod(Object target, String methodName) throws NoSuchMethodException { 44 | 45 | Method method = target.getClass().getDeclaredMethod(methodName); 46 | 47 | ReflectionUtils.makeAccessible(method); 48 | 49 | return (T) ReflectionUtils.invokeMethod(method, target); 50 | } 51 | 52 | @Test 53 | public void constructsFixedDurationExpirationSessionRepositoryBeanPostProcessor() { 54 | 55 | Duration expirationTimeout = Duration.ofMinutes(30L); 56 | 57 | FixedDurationExpirationSessionRepositoryBeanPostProcessor beanPostProcessor = 58 | new FixedDurationExpirationSessionRepositoryBeanPostProcessor(expirationTimeout); 59 | 60 | assertThat(beanPostProcessor).isNotNull(); 61 | assertThat(beanPostProcessor.getExpirationTimeout()).isEqualTo(expirationTimeout); 62 | } 63 | 64 | @Test 65 | public void doesNotProcessNonSessionRepositoryBeans() { 66 | 67 | FixedDurationExpirationSessionRepositoryBeanPostProcessor beanPostProcessor = 68 | new FixedDurationExpirationSessionRepositoryBeanPostProcessor(null); 69 | 70 | Object bean = beanPostProcessor.postProcessAfterInitialization("test", "testBean"); 71 | 72 | assertThat(bean).isNotInstanceOf(SessionRepository.class); 73 | assertThat(bean).isEqualTo("test"); 74 | } 75 | 76 | @Test 77 | @SuppressWarnings("all") 78 | public void processesSessionRepositoryBean() throws Exception { 79 | 80 | Duration expirationTimeout = Duration.ofMinutes(30); 81 | 82 | SessionRepository mockSessionRepository = mock(SessionRepository.class); 83 | 84 | FixedDurationExpirationSessionRepositoryBeanPostProcessor beanPostProcessor = 85 | new FixedDurationExpirationSessionRepositoryBeanPostProcessor(expirationTimeout); 86 | 87 | Object sessionRepository = 88 | beanPostProcessor.postProcessAfterInitialization(mockSessionRepository, "sessionRepository"); 89 | 90 | assertThat(sessionRepository).isNotSameAs(mockSessionRepository); 91 | assertThat(sessionRepository).isInstanceOf(FixedDurationExpirationSessionRepository.class); 92 | assertThat(((FixedDurationExpirationSessionRepository) sessionRepository).getExpirationTimeout() 93 | .orElse(null)).isEqualTo(expirationTimeout); 94 | assertThat(this.>invokeMethod(sessionRepository, "getDelegate")) 95 | .isEqualTo(mockSessionRepository); 96 | } 97 | } 98 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/GemFireOperationsSessionRepositorySupport.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import java.util.Map; 20 | 21 | import org.apache.geode.cache.Region; 22 | 23 | import org.springframework.data.gemfire.GemfireOperations; 24 | import org.springframework.session.Session; 25 | import org.springframework.session.SessionRepository; 26 | import org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository; 27 | 28 | /** 29 | * Framework supporting class for {@link AbstractGemFireOperationsSessionRepository} implementations. 30 | * 31 | * By default, all {@link SessionRepository} data access operations throw an {@link UnsupportedOperationException}. 32 | * Therefore, you are free to implement only the {@link SessionRepository} data access operations you need. 33 | * 34 | * For instance, if you only want to implement a {@literal read-only} {@link SessionRepository}, then you can simply 35 | * {@literal override} the {@link #findById(String)}, {@link #findByIndexNameAndIndexValue(String, String)} 36 | * and {@link #findByPrincipalName(String)} Repository methods. In that way, the {@link Session} can never be updated. 37 | * 38 | * @author John Blum 39 | * @see org.apache.geode.cache.Region 40 | * @see org.springframework.data.gemfire.GemfireOperations 41 | * @see org.springframework.session.Session 42 | * @see org.springframework.session.data.gemfire.AbstractGemFireOperationsSessionRepository 43 | * @since 2.1.1 44 | */ 45 | @SuppressWarnings("unused") 46 | public abstract class GemFireOperationsSessionRepositorySupport 47 | extends AbstractGemFireOperationsSessionRepository { 48 | 49 | private static final String OPERATION_NOT_SUPPORTED = "Operation Not Supported"; 50 | 51 | /** 52 | * Construct an uninitialized instance of {@link GemFireOperationsSessionRepositorySupport}. 53 | * 54 | * @see #GemFireOperationsSessionRepositorySupport(GemfireOperations) 55 | */ 56 | protected GemFireOperationsSessionRepositorySupport() { } 57 | 58 | /** 59 | * Constructs a new instance of {@link GemFireOperationsSessionRepositorySupport} initialized with 60 | * the given {@link GemfireOperations} object used to perform {@link Region} data access operations 61 | * managing the {@link Session} state. 62 | * 63 | * @param gemfireOperations {@link GemfireOperations} for performing data access operations 64 | * on the {@link Region} used to manage {@link Session} state. 65 | * @see org.springframework.data.gemfire.GemfireOperations 66 | */ 67 | public GemFireOperationsSessionRepositorySupport(GemfireOperations gemfireOperations) { 68 | super(gemfireOperations); 69 | } 70 | 71 | @Override 72 | public Session createSession() { 73 | throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED); 74 | } 75 | 76 | @Override 77 | public void deleteById(String id) { 78 | throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED); 79 | } 80 | 81 | @Override 82 | public Session findById(String id) { 83 | throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED); 84 | } 85 | 86 | @Override 87 | public Map findByIndexNameAndIndexValue(String indexName, String indexValue) { 88 | throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED); 89 | } 90 | 91 | @Override 92 | public void save(Session session) { 93 | throw new UnsupportedOperationException(OPERATION_NOT_SUPPORTED); 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/test/java/org/springframework/session/data/gemfire/support/SessionIdHolderTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import static org.assertj.core.api.Assertions.assertThat; 20 | 21 | import org.junit.Test; 22 | 23 | import org.springframework.session.Session; 24 | 25 | /** 26 | * Unit tests for {@link SessionIdHolder}. 27 | * 28 | * @author John Blum 29 | * @see org.junit.Test 30 | * @see org.springframework.session.Session 31 | * @see org.springframework.session.data.gemfire.support.SessionIdHolder 32 | * @since 2.0.0 33 | */ 34 | public class SessionIdHolderTests { 35 | 36 | @Test 37 | public void createSessionIdHolderWithId() { 38 | 39 | SessionIdHolder session = SessionIdHolder.create("12345"); 40 | 41 | assertThat(session).isNotNull(); 42 | assertThat(session.getId()).isEqualTo("12345"); 43 | } 44 | 45 | @Test(expected = IllegalArgumentException.class) 46 | public void createSessionIdHolderWithEmptyId() { 47 | 48 | try { 49 | SessionIdHolder.create(" "); 50 | } 51 | catch (IllegalArgumentException expected) { 52 | 53 | assertThat(expected).hasMessage("Session ID [ ] is required"); 54 | assertThat(expected).hasNoCause(); 55 | 56 | throw expected; 57 | } 58 | } 59 | 60 | @Test(expected = IllegalArgumentException.class) 61 | public void createSessionIdHolderWithNoId() { 62 | 63 | try { 64 | SessionIdHolder.create(null); 65 | } 66 | catch (IllegalArgumentException expected) { 67 | 68 | assertThat(expected).hasMessage("Session ID [null] is required"); 69 | assertThat(expected).hasNoCause(); 70 | 71 | throw expected; 72 | } 73 | } 74 | 75 | @Test 76 | public void equalsWithSameSessionReturnsTrue() { 77 | 78 | Session session = SessionIdHolder.create("12345"); 79 | 80 | assertThat(session.equals(session)).isTrue(); 81 | } 82 | 83 | @Test 84 | public void equalsWithEqualSessionsReturnsTrue() { 85 | 86 | Session sessionOne = SessionIdHolder.create("12345"); 87 | Session sessionTwo = SessionIdHolder.create("12345"); 88 | 89 | assertThat(sessionOne.equals(sessionTwo)).isTrue(); 90 | } 91 | 92 | @Test 93 | @SuppressWarnings("all") 94 | public void equalsWithUnequalSessionsReturnsFalse() { 95 | 96 | Session sessionOne = SessionIdHolder.create("123"); 97 | Session sessionTwo = SessionIdHolder.create("12345"); 98 | 99 | assertThat(sessionOne.equals(sessionTwo)).isFalse(); 100 | assertThat(sessionTwo.equals(null)).isFalse(); 101 | } 102 | 103 | @Test 104 | public void hashCodeForSameSessionIsEqual() { 105 | 106 | Session session = SessionIdHolder.create("12345"); 107 | 108 | assertThat(session.hashCode()).isEqualTo(session.hashCode()); 109 | } 110 | 111 | @Test 112 | public void hashCodeWithEqualSessionsIsEqual() { 113 | 114 | Session sessionOne = SessionIdHolder.create("12345"); 115 | Session sessionTwo = SessionIdHolder.create("12345"); 116 | 117 | assertThat(sessionOne.hashCode()).isEqualTo(sessionTwo.hashCode()); 118 | } 119 | 120 | @Test 121 | public void hashCodeForUnequalSessionsAreNotEqual() { 122 | 123 | Session sessionOne = SessionIdHolder.create("123"); 124 | Session sessionTwo = SessionIdHolder.create("12345"); 125 | 126 | assertThat(sessionOne.hashCode()).isNotEqualTo(sessionTwo.hashCode()); 127 | } 128 | 129 | @Test 130 | public void toStringReturnsSessionId() { 131 | assertThat(SessionIdHolder.create("12345").toString()).isEqualTo("12345"); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/IsDirtyPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import org.springframework.lang.NonNull; 20 | import org.springframework.lang.Nullable; 21 | 22 | /** 23 | * {@link IsDirtyPredicate} is a strategy interface used to configure Spring Session on how to evaluate application 24 | * domain objects to determine whether they are dirty or not. 25 | * 26 | * @author John Blum 27 | * @since 2.1.2 28 | */ 29 | @FunctionalInterface 30 | @SuppressWarnings("unused") 31 | public interface IsDirtyPredicate { 32 | 33 | IsDirtyPredicate ALWAYS_DIRTY = (oldValue, newValue) -> true; 34 | IsDirtyPredicate NEVER_DIRTY = (oldValue, newValue) -> false; 35 | 36 | /** 37 | * Determines whether the {@link Object newValue} is dirty relative to the {@link Object oldValue}. 38 | * 39 | * @param oldValue {@link Object} referring to the previous value. 40 | * @param newValue {@link Object} referring to the new value. 41 | * @return a boolean value indicating whether the {@link Object newValue} is dirty 42 | * relative to the {@link Object oldValue}. 43 | */ 44 | boolean isDirty(Object oldValue, Object newValue); 45 | 46 | /** 47 | * Composes 2 {@link IsDirtyPredicate} objects using the logical AND operator. 48 | * 49 | * The {@code other} {@link IsDirtyPredicate} is applied after {@literal this} {@link IsDirtyPredicate} 50 | * in the {@link #isDirty(Object, Object)} comparison evaluation. 51 | * 52 | * This composition is {@literal null-safe} and returns {@literal this} {@link IsDirtyPredicate} 53 | * if {@link IsDirtyPredicate other} is {@literal null}. 54 | * 55 | * @param other {@link IsDirtyPredicate} composed with {@literal this} {@link IsDirtyPredicate}. 56 | * @return an {@link IsDirtyPredicate} composition consisting of {@literal this} {@link IsDirtyPredicate} 57 | * composed with the {@code other} {@link IsDirtyPredicate} using the logical AND operator. 58 | * Returns {@literal this} {@link IsDirtyPredicate} if {@link IsDirtyPredicate other} is {@literal null}. 59 | * @see #orThen(IsDirtyPredicate) 60 | */ 61 | default @NonNull IsDirtyPredicate andThen(@Nullable IsDirtyPredicate other) { 62 | 63 | return other != null 64 | ? (oldValue, newValue) -> this.isDirty(oldValue, newValue) && other.isDirty(oldValue, newValue) 65 | : this; 66 | } 67 | 68 | /** 69 | * Composes 2 {@link IsDirtyPredicate} objects using the logical OR operator. 70 | * 71 | * The {@code other} {@link IsDirtyPredicate} is applied after {@literal this} {@link IsDirtyPredicate} 72 | * in the {@link #isDirty(Object, Object)} comparison evaluation. 73 | * 74 | * This composition is {@literal null-safe} and returns {@literal this} {@link IsDirtyPredicate} 75 | * if {@link IsDirtyPredicate other} is {@literal null}. 76 | * 77 | * @param other {@link IsDirtyPredicate} composed with {@literal this} {@link IsDirtyPredicate}. 78 | * @return an {@link IsDirtyPredicate} composition consisting of {@literal this} {@link IsDirtyPredicate} 79 | * composed with the {@code other} {@link IsDirtyPredicate} using the logical OR operator. 80 | * Returns {@literal this} {@link IsDirtyPredicate} if {@link IsDirtyPredicate other} is {@literal null}. 81 | * @see #andThen(IsDirtyPredicate) 82 | */ 83 | default @NonNull IsDirtyPredicate orThen(@Nullable IsDirtyPredicate other) { 84 | 85 | return other != null 86 | ? (oldValue, newValue) -> this.isDirty(oldValue, newValue) || other.isDirty(oldValue, newValue) 87 | : this; 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /spring-session-data-geode/src/main/java/org/springframework/session/data/gemfire/support/SessionIdHolder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present the original author or authors. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * https://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package org.springframework.session.data.gemfire.support; 18 | 19 | import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalArgumentException; 20 | 21 | import java.util.Optional; 22 | 23 | import org.apache.geode.cache.EntryEvent; 24 | import org.apache.geode.cache.Operation; 25 | import org.apache.geode.cache.Region; 26 | 27 | import org.springframework.session.Session; 28 | import org.springframework.util.ObjectUtils; 29 | import org.springframework.util.StringUtils; 30 | 31 | /** 32 | * {@link SessionIdHolder} class is a Spring Session {@link Session} implementation that only holds 33 | * the {@link String ID} of the {@link Session}. 34 | * 35 | * This implementation is only used in case Apache Geode or Pivotal GemFire returns a {@literal null} (old) value 36 | * in a {@link Region} {@link EntryEvent} triggered by a {@link Operation#DESTROY} or {@link Operation#INVALIDATE} 37 | * operation. 38 | * 39 | * @author John Blum 40 | * @see org.apache.geode.cache.EntryEvent 41 | * @see org.apache.geode.cache.Operation 42 | * @see org.apache.geode.cache.Region 43 | * @see org.springframework.session.data.gemfire.support.SessionIdHolder 44 | * @since 2.0.0 45 | */ 46 | public final class SessionIdHolder extends AbstractSession { 47 | 48 | private final String sessionId; 49 | 50 | /*** 51 | * Factory method to create an instance of the {@link SessionIdHolder} initialized with 52 | * the given {@link String session ID}. 53 | * 54 | * @param sessionId {@link String} containing the session ID used to initialize 55 | * the new instance of {@link SessionIdHolder}. 56 | * @return a new instance of {@link SessionIdHolder} initialized with 57 | * the given {@link String session ID}. 58 | * @throws IllegalArgumentException if session ID is {@literal null} or empty. 59 | * @see #SessionIdHolder(String) 60 | */ 61 | public static SessionIdHolder create(String sessionId) { 62 | return new SessionIdHolder(sessionId); 63 | } 64 | 65 | /** 66 | * Constructs a new instance of the {@link SessionIdHolder} initialized with 67 | * the given {@link String session ID}. 68 | * 69 | * @param sessionId {@link String} containing the session ID used to initialize 70 | * the new instance of {@link SessionIdHolder}. 71 | * @throws IllegalArgumentException if session ID is {@literal null} or empty. 72 | */ 73 | public SessionIdHolder(String sessionId) { 74 | 75 | this.sessionId = Optional.ofNullable(sessionId) 76 | .filter(StringUtils::hasText) 77 | .orElseThrow(() -> newIllegalArgumentException("Session ID [%s] is required", sessionId)); 78 | } 79 | 80 | /** 81 | * Returns the {@link String ID} of this {@link Session}. 82 | * 83 | * @return the {@link String ID} of this {@link Session}. 84 | */ 85 | @Override 86 | public String getId() { 87 | return this.sessionId; 88 | } 89 | 90 | @Override 91 | public boolean equals(Object obj) { 92 | 93 | if (this == obj) { 94 | return true; 95 | } 96 | 97 | if (!(obj instanceof Session)) { 98 | return false; 99 | } 100 | 101 | Session that = (Session) obj; 102 | 103 | return ObjectUtils.nullSafeEquals(this.getId(), that.getId()); 104 | } 105 | 106 | @Override 107 | public int hashCode() { 108 | 109 | int hashValue = 17; 110 | 111 | hashValue = 37 * hashValue + ObjectUtils.nullSafeHashCode(getId()); 112 | 113 | return hashValue; 114 | } 115 | 116 | @Override 117 | public String toString() { 118 | return getId(); 119 | } 120 | } 121 | --------------------------------------------------------------------------------