Edit and clean up the Sample User Guides.

This commit is contained in:
John Blum
2018-08-20 18:34:46 -07:00
parent 71392b2461
commit e1b5b1c5b5
12 changed files with 346 additions and 533 deletions

View File

@@ -2,13 +2,13 @@
John Blum
:toc:
This guide describes how to build a _Spring Boot_ Web application configured with _Spring Session_ to transparently
manage a Web application's `javax.servlet.http.HttpSession` using Apache Geode in a clustered (distributed),
replicated, highly available and optionally, durable manner.
This guide describes how to build a Spring Boot Web application configured with Spring Session to transparently
manage a Web application's `javax.servlet.http.HttpSession` using Apache Geode in a clustered (distributed)
and replicated.
In addition, this samples explores the effects of using _Spring Session_ and Apache Geode to manage the `HttpSession`
when the _Spring Boot_ Web application also declares both "_session_" and "_request_" scope bean definitions to process
client HTTP requests.
In addition, this samples explores the effects of using Spring Session and Apache Geode to manage the `HttpSession`
when the Spring Boot Web application also declares both "_session_" and "_request_" scoped bean definitions
to process client HTTP requests.
This sample is based on a https://stackoverflow.com/questions/45674137/can-session-scope-beans-be-used-with-spring-session-and-gemfire[_StackOverflow_ post],
which posed the following question...
@@ -17,22 +17,22 @@ which posed the following question...
The poster of the question when on to state and ask...
> When using Spring Session for "session" scope beans, Spring creates an extra HttpSession for this bean.
> When using Spring Session for "session" scope beans, Spring creates an extra `HttpSession` for this bean.
Is this an existing issue? What is the solution for this?
The answer to the first question is most definitely, *yes*. And, the second statement/question is not correct/valid,
as explained in the answer.
The answer to the first question is most definitely, *yes*. And, the second statement/question is not correct,
nor even valid, as explained in the answer.
This sample uses Apache Geode's client/server topology with a pair of _Spring Boot_ applications, one to configure
and run a Apache Geode server, and another to configure and run a Apache Geode client, which is also a _Spring_ MVC Web application
making use of an `HttpSession`.
This sample uses Apache Geode's client/server topology with a pair of Spring Boot applications, one to configure
and run an Apache Geode server, and another to configure and run an Apache Geode client, which is also
a Spring Web MVC application making use of an `HttpSession`.
NOTE: The completed guide can be found below, in section
<<spring-session-sample-boot-geode-with-scoped-proxies,Sample Spring Boot Web Application using Apache Geode-managed HttpSessions with Request and Session Scoped Proxy Beans>>.
== Updating Dependencies
Before using _Spring Session_, you must ensure that the required dependencies are included.
Before using Spring Session, you must ensure that the required dependencies are included.
If you are using _Maven_, include the following `dependencies` in your `pom.xml`:
.pom.xml
@@ -59,7 +59,7 @@ NOTE: If you are using Pivotal GemFire instead of Apache Geode, you may substitu
artifact for `spring-session-data-geode`.
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to add the _Spring_ Snapshot Maven Repository.
Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -77,7 +77,7 @@ If you are using _Maven_, include the following `repository` declaration in your
endif::[]
ifeval::["{version-milestone}" == "true"]
Since we are using a Milestone version, we need to add the _Spring_ Milestone Maven Repository.
Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -98,66 +98,54 @@ endif::[]
[[httpsession-spring-java-configuration-gemfire-boot]]
== Spring Boot Configuration
After adding the required dependencies and repository declarations, we can create the _Spring_ configuration
for both our Apache Geode client and server using _Spring Boot_. The _Spring_ configuration is responsible for
creating a `Servlet Filter` that replaces the `HttpSession` with an implementation backed by _Spring Session_
After adding the required dependencies and repository declarations, we can create the Spring configuration
for both our Apache Geode client and server using Spring Boot. The Spring configuration is responsible for
creating a Servlet `Filter` that replaces the `HttpSession` with an implementation backed by Spring Session
and Apace Geode.
=== Spring Boot, Apache Geode Cache Server
We start with a _Spring Boot_ application to configure and bootstrap the Apache Geode server process...
We start with a Spring Boot application to configure and bootstrap the Apache Geode server:
[source,java]
----
include::{samples-dir}boot/gemfire-with-scoped-proxies/src/main/java/sample/server/GemFireServer.java[tags=class]
----
<1> First, we annotate the `GemFireServer` class with `@SpringBootApplication` declaring that this is a _Spring Boot_
application, which allows us to leverage all of _Spring Boot's_ features (e.g. _auto-configuration_).
<2> Next, we also annotate the `GemFireServer` class with _Spring Data Geode's_ `@CacheServerApplication`,
which creates a peer, cache server allowing cache clients to connect.
<3> (_Optional_) Then, we declare the `@EnableGemFireHttpSession` annotation to create the necessary server-side `Region`
(by default, "_ClusteredSpringSessions_") used to store the `HttpSession` state. This step is optional since
the Region used to store session state could be manually created. Using `@EnableGemFireHttpSession` is easy
and convenient, and ensures that our client and server-side Regions match by name, which is required by Apache Geode.
<4> (_Optional_) Additionally, we also enable Apache Geode's embedded Management service, which allows JMX clients
(e.g. Apache Geode's _Gfsh_ shell tool) to connect to the server in order to manage the server or the entire cluster.
<5> Finally, we adjust the port that the `CacheServer` uses to listen for cache client connections by declaring
a `CacheServerConfigurer` bean, which gives us access to SDG's `CacheServerFactoryBean` in order to modify the port.
Property placeholders can be used to externalize the cache server port configuration. The cache server port
defaults to *40404* if not explicitly configured.
<1> First, we annotate the `GemFireServer` class with `@SpringBootApplication` to declare that this is a Spring Boot
application, allowing us to leverage all of Spring Boot's features (e.g. _auto-configuration_).
<2> Next, we use the Spring Data for Apache Geode configuration annotation `@CacheServerApplication` to simplify
the creation of a peer cache instance containing a `CacheServer` for cache clients to connect.
<3> (Optional) Then, the `@EnableGemFireHttpSession` annotation is used to create the necessary server-side `Region`
(by default, "_ClusteredSpringSessions_") to store the `HttpSessions` state. This step is optional since the
Session `Region` could be created manually, perhaps even using external means. Using `@EnableGemFireHttpSession`
is convenient and quick.
=== Spring Boot, Apache Geode Cache Client Web application
Now, we create a _Spring Boot_ Web application exposing our Web service with _Spring_ MVC, running as an Apache Geode
cache client connected to our _Spring Boot_, Apache Geode server. The Web application will use _Spring Session_
backed by Apache Geode to manage `HttpSession` state in a clustered (i.e. distributed), replicated and highly available
manner.
Now, we create a Spring Boot Web application exposing our Web service with Spring Web MVC, running as an Apache Geode
cache client connected to our Spring Boot, Apache Geode server. The Web application will use Spring Session
backed by Apache Geode to manage `HttpSession` state in a clustered (distributed) and replicated manner.
[source,java]
----
include::{samples-dir}boot/gemfire-with-scoped-proxies/src/main/java/sample/client/Application.java[tags=class]
----
<1> Like the server, we declare our Web application to be a _Spring Boot_ application
<1> Like the server, we declare our Web application to be a Spring Boot application
by annotating our `Application` class with `@SpringBootApplication`.
<2> `@Controller` is a _Spring_ Web MVC annotation enabling our MVC request mapping handler methods (i.e. methods
annotated with `@RequestMapping`) to process client HTTP requests (e.g. <6>)
<2> `@Controller` is a Spring Web MVC annotation enabling our MVC handler mapping methods (i.e. methods
annotated with `@RequestMapping`) to process HTTP requests (e.g. <6>)
<3> We also declare our Web application to be an Apache Geode cache client by annotating our `Application` class
with `@ClientCacheApplication`. Additionally, we adjust a few basic, "DEFAULT" client Pool settings.
<4> Next, we declare that the Web application will use _Spring Session_ backed by Apache Geode to manage
with `@ClientCacheApplication`. Additionally, we adjust a few basic, "DEFAULT" `Pool` settings (e.g. `readTimeout`).
<4> Next, we declare that the Web application will use Spring Session backed by Apache Geode to manage
the `HttpSession's` state by annotating the nested `ClientCacheConfiguration` class with `@EnableGemFireHttpSession`.
This will create the necessary client-side `PROXY` Region (by default, "_ClusteredSpringSessions_") corresponding to
the same server Region by name. All session state will be sent from the client to the server through Region
data access operations. The client-side Region uses the "DEFAULT" Pool (of connections) to communicate
with the server.
<5> Then, we adjust the port used by the client Pool to connect to the cache server using _Spring Data Geode's_
`ClientCacheConfigurer`. This callback interface is similar in purpose to the `CacheServerConfigurer` we saw
in the server's configuration. In this case, the `ClientCacheConfigurer` gives us access to the underlying
SDG `ClientCacheFactoryBean` in order to adjust the configuration of the Apache Geode `ClientCache`.
<6> We adjust the _Spring_ Web MVC configuration to set the home page, and finally...
<7> We declare the `/counts` HTTP request mapping handler method to keep track of the number of instances
created by the _Spring_ container for both "_request_" and "_session_" scoped proxy beans, of types
data access operations. The client-side Region uses the "DEFAULT" `Pool`.
<5> We adjust the Spring Web MVC configuration to set the home page, and finally...
<6> We declare the `/counts` HTTP request mapping handler method to keep track of the number of instances
created by the Spring container for both "_request_" and "_session_" scoped proxy beans, of types
`RequestScopedProxyBean` and `SessionScopedProxyBean`, respectively, each and every time a request is processed by
the handler method.
@@ -165,62 +153,58 @@ TIP: In typical Apache Geode production deployments, where the cluster includes
of servers (a.k.a. data nodes), it is more common for clients to connect to 1 or more Apache Geode Locators running
in the same cluster. A Locator passes meta-data to clients about the servers available in the cluster, the individual
server load and which servers have the client's data of interest, which is particularly important for direct,
single-hop data access and latency-sensitive operations. See more details about the
http://geode.apache.org/docs/guide/12/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
single-hop data access and latency-sensitive applications. See more details about the
{data-store-docs}/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
in the Apache Geode User Guide.
NOTE: For more information on configuring _Spring Data Geode_, refer to the
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[Reference Guide].
NOTE: For more information on configuring _Spring Data for Apache Geode_, refer to the {sdg-docs}[Reference Guide].
==== Enabling Pivotal GemFire HttpSession Management
`@EnableGemFireHttpSession` enables a developer to configure certain aspects of both _Spring Session_ and Apache Geode
out-of-the-box using the following attributes:
The `@EnableGemFireHttpSession` annotation enables developers to configure certain aspects of both Spring Session
and Apache Geode out-of-the-box using the following attributes:
* `clientRegionShortcut` - specifies the Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
used on the client with http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
* `clientRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the client with the {data-store-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(default is `PROXY`). This attribute is only used when configuring the client `Region`.
* `indexableSessionAttributes` - Identifies session attributes by name that should be indexed for querying purposes.
Only session attributes explicitly identified by name will be indexed. This is useful in situations where your application
is looking up the `HttpSession` by the currently authenticated principal's name, for example.
* `maxInactiveIntervalInSeconds` - controls `HttpSession` _idle-timeout expiration_ (TTI; defaults to **30 minutes**).
* `poolName` - name of the dedicated Apache Geode Pool used by a client to connect to a cluster of servers (defaults to
"_gemfirePool_").
* `regionName` - specifies the name of the Apache Geode Region used to store and manage `HttpSession` state
(defaults to "_ClusteredSpringSessions_").
* `serverRegionShortcut` - specifies the Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
used on the server with http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server Regions, or when Apache Geode's P2P
topology is employed.
* `sessionSerializerBeanName` - refers to the name of the bean that handles serialization of the `HttpSession` state
between the client and the server.
* `indexableSessionAttributes` - Identifies the Session attributes by name that should be indexed for querying purposes.
Only Session attributes explicitly identified by name will be indexed.
* `maxInactiveIntervalInSeconds` - controls _HttpSession_ idle-timeout expiration (defaults to **30 minutes**).
* `poolName` - name of the dedicated Apache Geode `Pool` used to connect a client to the cluster of servers.
This attribute is only used when the application is a cache client. Defaults to `gemfirePool`.
* `regionName` - specifies the name of the Apache Geode `Region` used to store and manage `HttpSession` state
(default is "*ClusteredSpringSessions*").
* `serverRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the server with the {data-store-javadoc}/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server `Regions`,
or when a P2P topology is employed.
NOTE: It is important to remember that the Apache Geode client Region name must match a server Region by the same name
if the client Region is either a `PROXY` or `CACHING_PROXY`. Client and server Region names are not required to match
if the client Region used to store session state is `LOCAL` only. However, keep in mind that session state will not
be propagated to the server when the client Region is only `LOCAL` to the client. Additionally, you lose all benefits
of using Apache Geode to store and manage session state on servers in a clustered, replicated and highly available
manner.
NOTE: It is important to remember that the Apache Geode client `Region` name must match a server `Region`
by the same name if the client `Region` is a `PROXY` or `CACHING_PROXY`. Client and server `Region` names
are not required to match if the client `Region` used to store session state is `LOCAL`. However, keep in mind
that Session state will not be propagated to the server and you lose all the benefits of using Apache Geode
to store and manage distributed, replicated session state information on the servers in a distributed,
replicated manner.
=== Session-scoped Proxy Bean
The _Spring Boot_ Apache Geode cache client Web application defines the `SessionScopedProxyBean` domain class.
The Spring Boot Apache Geode cache client Web application defines the `SessionScopedProxyBean` domain class.
[source,java]
----
include::{samples-dir}boot/gemfire-with-scoped-proxies/src/main/java/sample/client/model/SessionScopedProxyBean.java[tags=class]
----
<1> First, the `SessionScopedProxyBean` domain class is stereotyped as a _Spring_ `@Component` to be picked up by
_Spring's classpath component-scan_.
<1> First, the `SessionScopedProxyBean` domain class is stereotyped as a Spring `@Component` picked up by
Spring's classpath component-scan.
<2> Additionally, instances of this class are scoped to the `HttpSession`. Therefore, each time a client request
results in a new `HttpSession` (such as during a login event), a single instance of this class is created and will last
for the duration of the `HttpSession`. When the `HttpSession` ends or expires, this instance is destroyed by
the _Spring_ container. If the client re-establishes a new `HttpSession`, then another, new instance of this class
will be provided to the application's beans. However only ever 1 instance of this class exists for the duration of
the `HttpSession` and no more!
<3> Finally, this class keeps track of how many instances of this type are created by the _Spring_ container throughout
the entire application lifecycle.
results in creating a new `HttpSession` (such as during a login event), a single instance of this class is created
and will last for the duration of the `HttpSession`. When the `HttpSession` expires or is invalidated, this instance
is destroyed by the Spring container. If the client re-establishes a new `HttpSession`, then another, new instance of
this class will be provided to the application's beans. However only ever 1 instance of this class exists for
the duration of the `HttpSession`; no more!
<3> Finally, this class keeps track of how many instances of this type are created by the Spring container
throughout the entire application lifecycle.
TIP: More information on Spring's `@SessionScope` (i.e. "_session_" scope proxy beans) can be found in the
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-other[Reference Documentation],
@@ -228,24 +212,23 @@ along with https://docs.spring.io/spring/docs/current/spring-framework-reference
=== Request-scoped Proxy Bean
The _Spring Boot_ Apache Geode cache client Web application additionally defines the `RequestScopedProxyBean`
domain class.
The Spring Boot Apache Geode cache client Web application additionally defines the `RequestScopedProxyBean` domain class.
[source,java]
----
include::{samples-dir}boot/gemfire-with-scoped-proxies/src/main/java/sample/client/model/RequestScopedProxyBean.java[tags=class]
----
<1> First, this `RequestScopedProxyBean` domain class is stereotyped as a _Spring_ `@Component` to be picked up by
_Spring's classpath component-scan_.
<1> First, the `RequestScopedProxyBean` domain class is stereotyped as a Spring `@Component` picked up by
Spring's classpath component-scan.
<2> Additionally, instances of this class are scoped to the `HttpServletRequest`. Therefore, each time a client HTTP
request is sent (e.g. to process a Thread-scoped transaction), a single instance of this class will be created
and will last for the duration of the `HttpServletRequest`. When the request ends, this instance is destroyed
by the _Spring_ container. Any subsequent client `HttpServletRequests` results in another, new instance of this
by the Spring container. Any subsequent client `HttpServletRequests` results in another, new instance of this
class, which will be provided to the application's beans. However, only ever 1 instance of this class exists
for the duration of the `HttpServletRequest` and no more!
<3> Finally, this class keeps track of how many instances of this type are created by the _Spring_ container throughout
the entire application lifecycle.
for the duration of the `HttpServletRequest`; no more!
<3> Finally, this class keeps track of how many instances of this class are created by the Spring container
throughout the entire application lifecycle.
TIP: More information on Spring's `@RequestScope` (i.e. "_request_" scope proxy beans) can be found in the
https://docs.spring.io/spring/docs/current/spring-framework-reference/core.html#beans-factory-scopes-other[Reference Documentation],
@@ -281,14 +264,13 @@ image::{samples-dir}/boot/gemfire-with-scoped-proxies/sample-boot-gemfire-with-s
The table shows 1 row with 3 columns of information.
The `Session ID` and `Session Count` columns show current `HttpSession` information including the current
`HttpSession's` ID along with the number of `HttpSessions` created during the (client) application's current run.
`HttpSession's` ID and the number of `HttpSessions` created during the application's current run.
Additionally, the current `Request Count` is shown to indicate how many requests have been made by the client,
which in this case is your web browser.
You can use your web browser's refresh button to increase both the session and request count.
However, the session count only increases after the current session ends or times out and a new session
has been created for the client.
You can use your web browser's refresh button to increase both the session and request count. However, the session count
only increases after the current session expires and a new session has been created for the client.
The session will time out after *10 seconds*, which was configured on the server using the `@EnableGemFireHttpSession`
annotation as we saw before (#3)...
@@ -307,9 +289,9 @@ public class GemFireServer {
Here, you see that `maxInactiveIntervalInSeconds` is set to *10 seconds*. After 10 seconds, Apache Geode will expire
the `HttpSession`, and upon refreshing your web browser, a new session will be created and the session count
will increase.
will be incremented.
However, every request naturally results in incrementing the request count.
Naturally, every request results in incrementing the request count.
=== How does it work?
@@ -329,12 +311,12 @@ public String requestAndSessionInstanceCount(HttpServletRequest request, HttpSes
}
----
We see that we have injected a reference to the `HttpSession` as a request mapping method handler parameter.
We see that we have injected a reference to the `HttpSession` as a request mapping handler method parameter.
This will result in a new `HttpSession` on the client's first HTTP request. Subsequent requests from the same client
within the duration of the existing, current `HttpSession` will result in the same `HttpSession` being injected.
Of course, an `HttpSession` is identified by the session's identifier, which is stored in a Cookie sent between
the client and server during HTTP request processing.
the client and the server during HTTP request processing.
Additionally, we also see that we have injected references to the `SessionScopedProxyBean` and `RequestScopedProxyBean`
in our `@Controller` class...
@@ -350,9 +332,9 @@ private SessionScopedProxyBean sessionBean;
----
Based on the class definitions of these two types, as previously shown, these bean instances are scoped according
to _Spring's_ "_request_" and "_session_" scopes, respectively. The 2 scopes can only be used in Web applications.
to Spring's "_request_" and "_session_" scopes, respectively. The 2 scopes can only be used in Web applications.
For each and every HTTP request sent by the client (i.e. on each web browser refresh), _Spring_ will create
For each and every HTTP request sent by the client (i.e. on each web browser refresh), Spring will create
a new instance of the `RequestScopedProxyBean`. This is why the request count increases with every refresh,
which effectively is sending another HTTP request to the server to access and pull the content.
@@ -360,7 +342,7 @@ Furthermore, after each new `HttpSession`, a new instance of `SessionScopedProxy
persists for the duration of the session. If the `HttpSession` remains inactive (i.e. no request has been made)
for longer than *10 seconds*, the client's current `HttpSession` will expire. Therefore, on any subsequent client
HTTP request, a new `HttpSession` will be created by the Web container (e.g. Tomcat), which is replaced by
_Spring Session_ and backed with Apache Geode.
Spring Session and backed with Apache Geode.
Additionally, this "_session_" scope bean is stored in the `HttpSession`, referenced by a session attribute.
Therefore, you will also notice that the `SessionScopedProxyBean` class, unlike the `RequestScopedProxyBean` class,
@@ -380,4 +362,4 @@ This class is `Serializable` since it is stored in the `HttpSession`, which will
the `HttpSession` when sent to the Apache Geode cluster to be managed. Therefore, the type must be `Serializable`.
Any `RequestScopedProxyBeans` are not stored in the `HttpSession` and therefore will not be sent to the server,
and as such, do not need to be `Serializable`.
and as such, do not need to implement `java.io.Serializable`.

View File

@@ -2,10 +2,10 @@
John Blum
:toc:
This guide describes how to build a _Spring Boot_ application configured with _Spring Session_ to transparently leverage
This guide describes how to build a Spring Boot application configured with Spring Session to transparently leverage
Apache Geode to manage a web application's `javax.servlet.http.HttpSession`.
In this sample, Apache Geode's client/server topology is employed using a pair of _Spring Boot_ applications, one to
In this sample, Apache Geode's client/server topology is employed using a pair of Spring Boot applications, one to
configure and run a Apache Geode Server and another to configure and run the cache client, Spring MVC-based web application
making use of the `HttpSession`.
@@ -14,7 +14,7 @@ NOTE: The completed guide can be found in the
== Updating Dependencies
Before using _Spring Session_, you must ensure that the required dependencies are included.
Before using Spring Session, you must ensure that the required dependencies are included.
If you are using _Maven_, include the following `dependencies` in your `pom.xml`:
.pom.xml
@@ -38,7 +38,7 @@ If you are using _Maven_, include the following `dependencies` in your `pom.xml`
----
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to add the _Spring_ Snapshot Maven Repository.
Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -56,7 +56,7 @@ If you are using _Maven_, include the following `repository` declaration in your
endif::[]
ifeval::["{version-milestone}" == "true"]
Since we are using a Milestone version, we need to add the _Spring_ Milestone Maven Repository.
Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -77,98 +77,93 @@ endif::[]
[[httpsession-spring-java-configuration-gemfire-boot]]
== Spring Boot Configuration
After adding the required dependencies and repository declarations, we can create the _Spring_ configuration
for both our Apache Geode client and server using _Spring Boot_. The _Spring_ configuration is responsible for
creating a `Servlet Filter` that replaces the `HttpSession` with an implementation backed by _Spring Session_
and Apace Geode.
After adding the required dependencies and repository declarations, we can create the Spring configuration
for both our Apache Geode client and server using Spring Boot. The Spring configuration is responsible for creating
a Servlet `Filter` that replaces the `HttpSession` with an implementation backed by Spring Session and Apace Geode.
=== Spring Boot, Apache Geode Cache Server
We start with a _Spring Boot_ application to configure and bootstrap the Apache Geode Server process...
We start with a Spring Boot application to configure and bootstrap the Apache Geode Server:
[source,java]
----
include::{samples-dir}boot/gemfire/src/main/java/sample/server/GemFireServer.java[tags=class]
----
<1> First, we annotate the Apache Geode Server configuration class with `@SpringBootApplication` to indicate that
this will be a _Spring Boot_ application in order to leverage all of _Spring Boot's_ features (e.g. _auto-configuration_).
<2> Next, we use the **new** _Spring Data Geode_ configuration annotation `@CacheServerApplication` to simplify
the creation of a peer cache instance along with a `CacheServer` for cache clients to connect.
<3> (Optional) Then, the `@EnableGemFireHttpSession` annotation is declared to create the necessary server-side `Region`
(by default, "_ClusteredSpringSessions_") used to store the `HttpSessions` state. This step is optional since the
Session `Region` could be created manually, perhaps using external means. Using `@EnableGemFireHttpSession` is convenient.
<4> Additionally, we enable the Apache Geode Manager embedded service, which allows JMX clients (e.g. Apache Geode's
_Gfsh_ shell tool) to connect to the server and inspect the configuration.
<5> Finally, we adjust the port that the `CacheServer` will use to listen for cache clients by declaring
a `CacheServerConfigurer` bean to modify the SDG `CacheServerFactoryBean` using property placeholders.
The sample also makes use of _Spring's_ `PropertySourcesPlaceholderConfigurer` in order to externalize
the sample application's configuration using a properties file or with JVM System properties, which ever.
<1> First, we annotate the Apache Geode Server configuration class (`GemFireServer`) with `@SpringBootApplication`
to indicate that this is a Spring Boot application leveraging all of _Spring Boot's_ features
(e.g. _auto-configuration_).
<2> Next, we use the Spring Data for Apache Geode configuration annotation `@CacheServerApplication` to simplify
the creation of a peer cache instance containing a `CacheServer` for cache clients to connect.
<3> (Optional) Then, the `@EnableGemFireHttpSession` annotation is used to create the necessary server-side `Region`
(by default, "_ClusteredSpringSessions_") to store the `HttpSessions` state. This step is optional since the
Session `Region` could be created manually, perhaps even using external means. Using `@EnableGemFireHttpSession`
is convenient and quick.
=== Spring Boot, Apache Geode Cache Client Web application
Now, we create a _Spring Boot_ Web application to expose our Web service with _Spring_ MVC, running as an Apache Geode
cache client connected to our _Spring Boot_, Apache Geode Server. The Web application will use _Spring Session_
backed by Apache Geode to manage Session state in a clustered (distributed), replicated fashion.
Now, we create a Spring Boot Web application to expose our Web service with Spring Web MVC, running as an Apache Geode
cache client connected to our Spring Boot, Apache Geode Server. The Web application will use Spring Session
backed by Apache Geode to manage `HttpSession` state in a clustered (distributed) and replicated manner.
[source,java]
----
include::{samples-dir}boot/gemfire/src/main/java/sample/client/Application.java[tags=class]
----
<1> Again, we declare our Web application to be a _Spring Boot_ application by annotating our application class
with the `@SpringBootApplication` annotation.
<2> `@Controller` is a _Spring_ Web MVC annotation enabling our MVC handler mapping methods (i.e. methods annotated
with `@RequestMapping`) to process HTTP requests (e.g. <6>)
<3> We also declare our Web application to be a Apache Geode cache client by annotating our application class with
`@ClientCacheApplication`. Additionally, we adjust a few basic, "DEFAULT" `Pool` settings.
<4> Next, we declare that the Web application will use _Spring Session_ backed by Apache Geode by annotating the
<1> Again, we declare our Web application to be a Spring Boot application by annotating our application class
with `@SpringBootApplication`.
<2> `@Controller` is a Spring Web MVC annotation enabling our MVC handler mapping methods (i.e. methods annotated
with `@RequestMapping`) to process HTTP requests (e.g. <7>)
<3> We also declare our Web application to be an Apache Geode cache client by annotating our application class with
`@ClientCacheApplication`. Additionally, we adjust a few basic, "DEFAULT" `Pool` settings (e.g. `readTimeout`).
<4> Next, we declare that the Web application will use Spring Session backed by Apache Geode by annotating the
`ClientCacheConfiguration` class with `@EnableGemFireHttpSession`. This will create the necessary client-side `Region`
(by default, "ClusteredSpringSessions`, which is a `PROXY` `Region`) corresponding to the same server-side `Region`
by name. All Session state will be sent from the cache client Web application to the server through `Region`
data access operations. The client-side `Region` will use the "DEFAULT" `Pool`.
<5> Then, we adjust the port used by the cache client `Pool` to connect to the `CacheServer`
using a SDG `ClientCacheConfigurer`.
<6> We adjust the _Spring_ Web MVC configuration to set the home page, and...
<7> Finally, we declare the `/sessions` HTTP request handler method to set a HTTP Session attribute and increment
a count for the number of HTTP requests.
(by default, "ClusteredSpringSessions` as a `PROXY` `Region`) corresponding to the same server-side `Region`
by name. All `HttpSession` state will be sent from the cache client Web application to the server through `Region`
data access operations. The client-side `Region` uses the "DEFAULT" `Pool`.
<5> Then, we wait to ensure the Apache Geode Server is up and running before we proceed. This is only really useful
for automated (integration) testing purposes.
<6> We adjust the Spring Web MVC configuration to set the home page, and...
<7> Finally, we declare the `/sessions` HTTP request handler method to set an HTTP Session attribute
and increment a count for the number of HTTP requests.
There are many other useful utility methods, so please refer to the actual source code for full details.
TIP: In typical Apache Geode production deployments, where the cluster includes potentially hundreds or thousands
of Apache Geode servers (data nodes), it is more common for clients to connect to 1 or more Apache Geode Locators running
in the cluster. A Locator passes meta-data to clients about the servers available in the cluster, the server load
and which servers have the client's data of interest, which is particularly important for direct, single-hop data access
and latency-sensitive operations. See more details about the
http://geode.apache.org/docs/guide/12/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
of servers (a.k.a. data nodes), it is more common for clients to connect to 1 or more Apache Geode Locators running
in the same cluster. A Locator passes meta-data to clients about the servers available in the cluster, the individual
server load and which servers have the client's data of interest, which is particularly important for direct,
single-hop data access and latency-sensitive applications. See more details about the
{data-store-docs}/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
in the Apache Geode User Guide.
NOTE: For more information on configuring _Spring Data Geode, refer to the
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[Reference Guide].
NOTE: For more information on configuring Spring Data Geode, refer to the {sdg-docs}[Reference Guide].
`@EnableGemFireHttpSession` enables a developer to configure certain aspects of both _Spring Session_ and Apache Geode
out-of-the-box using the following attributes:
The `@EnableGemFireHttpSession` annotation enables developers to configure certain aspects of both Spring Session
and Apache Geode out-of-the-box using the following attributes:
* `clientRegionShortcut` - specifies Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
on the client with a Apache Geode http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(default is `PROXY`). This attribute is only used when configuring client `Region`.
* `indexableSessionAttributes` - Identifies the Session attributes by name that should be indexed for querying operations.
Only Session attributes identified by name will be indexed.
* `clientRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the client with the {data-store-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(default is `PROXY`). This attribute is only used when configuring the client `Region`.
* `indexableSessionAttributes` - Identifies the Session attributes by name that should be indexed for querying purposes.
Only Session attributes explicitly identified by name will be indexed.
* `maxInactiveIntervalInSeconds` - controls _HttpSession_ idle-timeout expiration (defaults to **30 minutes**).
* `poolName` - name of the dedicated Apache Geode `Pool` used to connect a client to the cluster of servers. The attribute
is only used when the application is a cache client. Defaults to `gemfirePool`.
* `poolName` - name of the dedicated Apache Geode `Pool` used to connect a client to the cluster of servers.
This attribute is only used when the application is a cache client. Defaults to `gemfirePool`.
* `regionName` - specifies the name of the Apache Geode `Region` used to store and manage `HttpSession` state
(default is "*ClusteredSpringSessions*").
* `serverRegionShortcut` - specifies Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
on the server using a Apache Geode http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server `Regions`, or when a P2P topology is employed.
* `serverRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the server with the {data-store-javadoc}/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server `Regions`,
or when a P2P topology is employed.
NOTE: It is important to remember that the Apache Geode client `Region` name must match a server `Region`
by the same name if the client `Region` is a `PROXY` or `CACHING_PROXY`. Client and server `Region` names
are not required to match if the client `Region` used to store Sessions is `LOCAL`. However, keep in mind
are not required to match if the client `Region` used to store session state is `LOCAL`. However, keep in mind
that Session state will not be propagated to the server and you lose all the benefits of using Apache Geode
to store and manage distributed, replicated Session state information on the servers in a cluster.
to store and manage distributed, replicated session state information on the servers in a distributed,
replicated manner.
[[spring-session-sample-boot-geode]]
== Spring Boot Sample Web Application with an Apache Geode managed HttpSession
@@ -191,7 +186,7 @@ $ ./gradlew :spring-session-sample-boot-gemfire:bootRun [-Dgemfire.log-level=con
You should now be able to access the application at http://localhost:8080/.
In this sample, the Web application is the _Spring Boot_, Apache Geode cache client
In this sample, the Web application is the Spring Boot, Apache Geode cache client
and the server is standalone, separate (JVM) process.
=== Exploring the Boot Sample Application
@@ -225,45 +220,6 @@ public String session(HttpSession session, ModelMap modelMap,
----
Instead of using the embedded HTTP server's `HttpSession`, we are actually persisting the Session state in Apache Geode.
_Spring Session_ creates a cookie named SESSION in your browser that contains the id of your Session.
Spring Session creates a cookie named SESSION in your browser that contains the id of your Session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome]
or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
NOTE: The following instructions assume you have a local Apache Geode installation. For more information on installation,
see http://geode.apache.org/docs/guide/12/prereq_and_install.html[Prerequisites and Installation Instructions].
If you like, you can easily remove the Session using `gfsh`.
For example, on a Linux-based system type the following at the command-line:
$ gfsh
Then, enter the following commands in _Gfsh_, ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value
of your SESSION cookie, or the Session id returned by the Apache Geode OQL query (which should match):
....
gfsh>connect --jmx-manager=localhost[1099]
gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet'
Result : true
startCount : 0
endCount : 20
Rows : 1
Result
------------------------------------
70002719-3c54-4c20-82c3-e7faa6b718f3
NEXT_STEP_NAME : END
gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3"
....
NOTE: The _Apache Geode User Guide_ contains more detailed instructions on using
http://geode.apache.org/docs/guide/12/tools_modules/gfsh/chapter_overview.html[gfsh].
Now visit the application at `http://localhost:8080/` again and observe the attribute we added is no longer displayed.
Alternatively, you can wait **20 seconds** for the Session to timeout and expire and then refresh the page.
The attribute we added should no longer be displayed in the table.

View File

@@ -0,0 +1,40 @@
NOTE: The following instructions assume you have installed a local Apache Geode installation. For more information
on installation, see {data-store-docs}/prereq_and_install.html[Prerequisites and Installation Instructions].
If you like, you can easily remove the session using `gfsh`.
For example, on a Linux-based system type the following at the command-line:
$ gfsh
Then, enter the following commands in _Gfsh_, ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value
from your SESSION cookie, or the session id returned by the Apache Geode OQL query (which should match):
....
gfsh>connect --jmx-manager=localhost[1099]
gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet'
Result : true
startCount : 0
endCount : 20
Rows : 1
Result
------------------------------------
70002719-3c54-4c20-82c3-e7faa6b718f3
NEXT_STEP_NAME : END
gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3"
....
NOTE: The Apache Geode User Guide contains more detailed instructions on using
{data-store-docs}/tools_modules/gfsh/chapter_overview.html[gfsh].
Now visit the application at `http://localhost:8080/` again and observe the attribute we added is no longer displayed.
Alternatively, you can wait **20 seconds** for the session to timeout/expire and then refresh the page. The attribute
we added should no longer be displayed in the table. However, keep in mind, by refreshing the page, you will
inadvertently create a new (empty) session. If you run the query again, you will also see two session ids,
the new and the old, since Apache Geode keeps a "tombstone" of the old session around (for consistency purposes).

View File

@@ -2,7 +2,7 @@
John Blum
:toc:
This guide describes how to configure _Spring Session_ to transparently leverage Apache Geode to manage
This guide describes how to configure Spring Session to transparently leverage Apache Geode to manage
a Web application's `javax.servlet.http.HttpSession` using Java Configuration.
NOTE: The completed guide can be found in the
@@ -10,7 +10,7 @@ NOTE: The completed guide can be found in the
== Updating Dependencies
Before using _Spring Session_, you must ensure that the required dependencies are included.
Before using Spring Session, you must ensure that the required dependencies are included.
If you are using _Maven_, include the following `dependencies` in your `pom.xml`:
.pom.xml
@@ -35,7 +35,7 @@ If you are using _Maven_, include the following `dependencies` in your `pom.xml`
----
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to add the _Spring_ Snapshot Maven Repository.
Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -53,7 +53,7 @@ If you are using _Maven_, include the following `repository` declaration in your
endif::[]
ifeval::["{version-milestone}" == "true"]
Since we are using a Milestone version, we need to add the _Spring_ Milestone Maven Repository.
Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -74,99 +74,95 @@ endif::[]
[[httpsession-spring-java-configuration]]
== Spring Java Configuration
After adding the required dependencies and repository declarations, we can create the _Spring_ configuration.
The _Spring_ configuration is responsible for creating a `Servlet Filter` that replaces the `HttpSession`
with an implementation backed by _Spring Session_ and Apache Geode.
After adding the required dependencies and repository declarations, we can create the Spring configuration.
The Spring configuration is responsible for creating a Servlet `Filter` that replaces the `HttpSession`
with an implementation backed by Spring Session and Apache Geode.
=== Client Configuration
Add the following _Spring_ configuration:
Add the following Spring configuration:
[source,java]
----
include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/ClientConfig.java[tags=class]
----
<1> First, we declare our Web application to be a Apache Geode cache client by annotating our `ClientConfig` class
with `@ClientCacheApplication`. Additionally, we adjust a few basic, "DEFAULT" `Pool` settings.
<2> `@EnableGemFireHttpSession` creates a _Spring_ bean named `springSessionRepositoryFilter` that implements
`javax.servlet.Filter`. The filter is what replaces the `HttpSession` with an implementation provided by _Spring Session_
and backed by Apache Geode. This will also create the necessary client-side `Region` (by default, "ClusteredSpringSessions`,
which is a `PROXY` `Region`) corresponding to the same server-side `Region` by name. All Session state will be sent
from the cache client Web application to the server through `Region` data access operations. The client-side `Region`
will use the "DEFAULT" `Pool`.
<3> Then, we adjust the port used by the cache client `Pool` to connect to the `CacheServer`
using a SDG `ClientCacheConfigurer`.
<1> First, we declare our Web application to be an Apache Geode cache client by annotating our `ClientConfig` class
with `@ClientCacheApplication`. Additionally, we adjust a few basic, "DEFAULT" `Pool` settings (e.g. `readTimeout`).
<2> `@EnableGemFireHttpSession` creates a Spring bean named `springSessionRepositoryFilter` that implements
`javax.servlet.Filter`. The filter replaces the `HttpSession` with an implementation provided by Spring Session
and backed by Apache Geode. Additionall, the configuration will also create the necessary client-side `Region`
(by default, "ClusteredSpringSessions`, which is a `PROXY` `Region`) corresponding to the same server-side `Region`
by name. All session state is sent from the client to the server through `Region` data access operations.
The client-side `Region` use the "DEFAULT" `Pool`.
<3> Then, we wait to ensure the Apache Geode Server is up and running before we proceed. This is only really useful
for automated (integration) testing purposes.
TIP: In typical Apache Geode production deployments, where the cluster includes potentially hundreds or thousands
of Apache Geode servers (data nodes), it is more common for clients to connect to 1 or more Apache Geode Locators running
in the cluster. A Locator passes meta-data to clients about the servers available in the cluster, the server load
and which servers have the client's data of interest, which is particularly important for direct, single-hop data access
and latency-sensitive operations. See more details about the
http://geode.apache.org/docs/guide/12/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
of servers (a.k.a. data nodes), it is more common for clients to connect to 1 or more Apache Geode Locators running
in the same cluster. A Locator passes meta-data to clients about the servers available in the cluster, the individual
server load and which servers have the client's data of interest, which is particularly important for direct,
single-hop data access and latency-sensitive applications. See more details about the
{data-store-docs}/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
in the Apache Geode User Guide.
NOTE: For more information on configuring _Spring Data Geode, refer to the
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[Reference Guide].
NOTE: For more information on configuring Spring Data Geode, refer to the {sdg-docs}[Reference Guide].
`@EnableGemFireHttpSession` enables a developer to configure certain aspects of both _Spring Session_ and Apache Geode
out-of-the-box using the following attributes:
The `@EnableGemFireHttpSession` annotation enables developers to configure certain aspects of both Spring Session
and Apache Geode out-of-the-box using the following attributes:
* `clientRegionShortcut` - specifies Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
on the client with a Apache Geode http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(default is `PROXY`). This attribute is only used when configuring a client `Region`.
* `indexableSessionAttributes` - Identifies the Session attributes by name that should be indexed for querying operations.
Only Session attributes identified by name will be indexed.
* `clientRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the client with the {data-store-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(default is `PROXY`). This attribute is only used when configuring the client `Region`.
* `indexableSessionAttributes` - Identifies the Session attributes by name that should be indexed for querying purposes.
Only Session attributes explicitly identified by name will be indexed.
* `maxInactiveIntervalInSeconds` - controls _HttpSession_ idle-timeout expiration (defaults to **30 minutes**).
* `poolName` - name of the dedicated Apache Geode `Pool` used to connect a client to the cluster of servers. The attribute
is only used when the application is a cache client. Defaults to `gemfirePool`.
* `poolName` - name of the dedicated Apache Geode `Pool` used to connect a client to the cluster of servers.
This attribute is only used when the application is a cache client. Defaults to `gemfirePool`.
* `regionName` - specifies the name of the Apache Geode `Region` used to store and manage `HttpSession` state
(default is "*ClusteredSpringSessions*").
* `serverRegionShortcut` - specifies Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
on the server using a Apache Geode http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server `Regions`, or when a P2P topology is employed.
* `serverRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the server with the {data-store-javadoc}/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server `Regions`,
or when a P2P topology is employed.
NOTE: It is important to remember that the Apache Geode client `Region` name must match a server `Region`
by the same name if the client `Region` is a `PROXY` or `CACHING_PROXY`. Client and server `Region` names
are not required to match if the client `Region` used to store Sessions is `LOCAL`. However, keep in mind
are not required to match if the client `Region` used to store session state is `LOCAL`. However, keep in mind
that Session state will not be propagated to the server and you lose all the benefits of using Apache Geode
to store and manage distributed, replicated Session state information on the servers in a cluster.
to store and manage distributed, replicated session state information on the servers in a distributed,
replicated manner.
=== Server Configuration
So far, we only covered one side of the equation. We also need an Apache Geode Server for our cache client to talk to
and send Session state to the server to manage.
and send session state to the server to manage.
In this sample, we will use the following Java configuration to spin up an Apache Geode Server:
In this sample, we will use the following Java configuration to configure and run an Apache Geode Server:
[source,java]
----
include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/ServerConfig.java[tags=class]
----
<1> First, we use the **new** _Spring Data Geode_ configuration annotation `@CacheServerApplication` to simplify
the creation of a peer cache instance along with a `CacheServer` for cache clients to connect.
<1> First, we use the `@CacheServerApplication` annotation to simplify the creation of a peer cache instance
containing with a `CacheServer` for cache clients to connect.
<2> (Optional) Then, the `ServerConfig` class is annotated with `@EnableGemFireHttpSession` to create the necessary
server-side `Region` (by default, "_ClusteredSpringSessions_") used to store the `HttpSessions` state. This step is
server-side `Region` (by default, "_ClusteredSpringSessions_") used to store `HttpSession` state. This step is
optional since the Session `Region` could be created manually, perhaps using external means.
Using `@EnableGemFireHttpSession` is convenient.
<3> Finally, we adjust the port that the `CacheServer` will use to listen for cache clients by declaring
a `CacheServerConfigurer` bean to modify the SDG `CacheServerFactoryBean` using property placeholders.
The sample makes use of _Spring's_ `PropertySourcesPlaceholderConfigurer` in order to externalize the sample
application's configuration using a properties file or with JVM System properties, which ever.
Using `@EnableGemFireHttpSession` is convenient and quick.
== Java Servlet Container Initialization
Our <<httpsession-spring-java-configuration,Spring Java Configuration>> created a _Spring_ bean named `springSessionRepositoryFilter`
Our <<httpsession-spring-java-configuration,Spring Java Configuration>> created a Spring bean named `springSessionRepositoryFilter`
that implements `javax.servlet.Filter`. The `springSessionRepositoryFilter` bean is responsible for replacing the
`javax.servlet.http.HttpSession` with a custom implementation backed by _Spring Session_ and Apache Geode.
`javax.servlet.http.HttpSession` with a custom implementation backed by Spring Session and Apache Geode.
In order for our `Filter` to do its magic, _Spring_ needs to load the `ClientConfig` class. We also need to ensure our
In order for our `Filter` to do its magic, Spring needs to load the `ClientConfig` class. We also need to ensure our
Servlet container (i.e. Tomcat) uses our `springSessionRepositoryFilter` for every request.
Fortunately, _Spring Session_ provides a utility class named `AbstractHttpSessionApplicationInitializer` to make both
of these steps extremely easy.
Fortunately, Spring Session provides a utility class named `AbstractHttpSessionApplicationInitializer` to make both
steps extremely easy.
You can find an example below:
@@ -179,9 +175,9 @@ include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/Initi
NOTE: The name of our class (`Initializer`) does not matter. What is important is that we extend
`AbstractHttpSessionApplicationInitializer`.
<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`. This ensures that a _Spring_ bean named
<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`. This ensures that a Spring bean named
`springSessionRepositoryFilter` is registered with our Servlet container and used on every HTTP request.
<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily allow _Spring_ to load
<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily allow Spring to load
our `ClientConfig`.
// end::config[]
@@ -230,47 +226,6 @@ include::{samples-dir}javaconfig/gemfire-clientserver/src/main/java/sample/Sessi
Instead of using Tomcat's `HttpSession`, we are actually persisting the Session in Apache Geode.
_Spring Session_ creates a cookie named SESSION in your browser that contains the id of your Session.
Spring Session creates a cookie named SESSION in your browser that contains the id of your Session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome]
or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
NOTE: The following instructions assume you have a local Apache Geode installation. For more information on installation,
see http://geode.apache.org/docs/guide/12/prereq_and_install.html[Prerequisites and Installation Instructions].
If you like, you can easily remove the Session using `gfsh`.
For example, on a Linux-based system type the following at the command-line:
$ gfsh
Then, enter the following commands in _Gfsh_, ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value
of your SESSION cookie, or the Session id returned by the Apache Geode OQL query (which should match):
....
gfsh>connect --jmx-manager=localhost[1099]
gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet'
Result : true
startCount : 0
endCount : 20
Rows : 1
Result
------------------------------------
70002719-3c54-4c20-82c3-e7faa6b718f3
NEXT_STEP_NAME : END
gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3"
....
NOTE: The _Apache Geode User Guide_ contains more detailed instructions on using
http://geode.apache.org/docs/guide/12/tools_modules/gfsh/chapter_overview.html[gfsh].
Now visit the application at `http://localhost:8080/` again and observe the attribute we added is no longer displayed.
Alternatively, you can wait **20 seconds** for the Session to timeout and expire and then refresh the page.
The attribute we added should no longer be displayed in the table. However, keep in mind, by refreshing the page,
you will inadvertently create a new (empty) Session. If you run the query again, you will also see two Session ids,
the new and the old, since Apache Geode keeps a "tombstone" of the old Session around.

View File

@@ -2,14 +2,14 @@
John Blum
:toc:
This guide describes how to configure Apache Geode as a provider in _Spring Session_ to transparently manage
This guide describes how to configure Apache Geode as a provider in Spring Session to transparently manage
a Web application's `javax.servlet.http.HttpSession` using Java configuration.
NOTE: The completed guide can be found in the <<spring-session-sample-java-gemfire-p2p,HttpSession with Apache Geode (P2P) Sample Application>>.
== Updating Dependencies
Before using _Spring Session_, you must ensure that the required dependencies are included.
Before using Spring Session, you must ensure that the required dependencies are included.
If you are using _Maven_, include the following `dependencies` in your `pom.xml`:
.pom.xml
@@ -34,7 +34,7 @@ If you are using _Maven_, include the following `dependencies` in your `pom.xml`
----
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to add the _Spring_ Snapshot Maven Repository.
Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -52,7 +52,7 @@ If you are using _Maven_, include the following `repository` declaration in your
endif::[]
ifeval::["{version-milestone}" == "true"]
Since we are using a Milestone version, we need to add the _Spring_ Milestone Maven Repository.
Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -73,56 +73,55 @@ endif::[]
[[httpsession-spring-java-configuration-gemfire-p2p]]
== Spring Java Configuration
After adding the required dependencies and repository declarations, we can create the _Spring_ configuration.
After adding the required dependencies and repository declarations, we can create the Spring configuration.
The _Spring_ configuration is responsible for creating a `Servlet` `Filter` that replaces the `javax.servlet.http.HttpSession`
with an implementation backed by _Spring Session_ and Apache Geode.
The Spring configuration is responsible for creating a `Servlet` `Filter` that replaces the
`javax.servlet.http.HttpSession` with an implementation backed by Spring Session and Apache Geode.
Add the following _Spring_ configuration:
Add the following Spring configuration:
[source,java]
----
include::{samples-dir}javaconfig/gemfire-p2p/src/main/java/sample/Config.java[tags=class]
----
<1> First, we use the **new** _Spring Data Geode_ configuration annotation `@PeerCacheApplication` to simplify
the creation of a peer cache instance.
<1> First, we use the `@PeerCacheApplication` annotation to simplify the creation of a peer cache instance.
<2> Then, the `Config` class is annotated with `@EnableGemFireHttpSession` to create the necessary server-side `Region`
(by default, "_ClusteredSpringSessions_") used to store the `HttpSessions` state.
<3> (Optionally) Finally, we annotated the `Config` class with `@EnableManager` to start an embedded Apache Geode Manager
service to allow JMX clients (e.g. Apache Geode's _Gfsh_ shell tool) to connect and inspect the server.
(by default, "_ClusteredSpringSessions_") used to store `HttpSession` state.
NOTE: For more information on configuring _Spring Data Geode, refer to the
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[Reference Guide].
NOTE: For more information on configuring Spring Data for Apache Geode, refer to the
{sdg-docs}[Reference Guide].
`@EnableGemFireHttpSession` enables a developer to configure certain aspects of both _Spring Session_ and Apache Geode
out-of-the-box using the following attributes:
The `@EnableGemFireHttpSession` annotation enables developers to configure certain aspects of both Spring Session
and Apache Geode out-of-the-box using the following attributes:
* `clientRegionShortcut` - specifies Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
on the client with a Apache Geode http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(default is `PROXY`). This attribute is only used when configuring a client `Region`.
* `indexableSessionAttributes` - Identifies the Session attributes by name that should be indexed for querying operations.
Only Session attributes identified by name will be indexed.
* `clientRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the client with the {data-store-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(default is `PROXY`). This attribute is only used when configuring the client `Region`.
* `indexableSessionAttributes` - Identifies the Session attributes by name that should be indexed for querying purposes.
Only Session attributes explicitly identified by name will be indexed.
* `maxInactiveIntervalInSeconds` - controls _HttpSession_ idle-timeout expiration (defaults to **30 minutes**).
* `poolName` - name of the dedicated Apache Geode `Pool` used to connect a client to the cluster of servers. The attribute
is only used when the application is a cache client. Defaults to `gemfirePool`.
* `poolName` - name of the dedicated Apache Geode `Pool` used to connect a client to the cluster of servers.
This attribute is only used when the application is a cache client. Defaults to `gemfirePool`.
* `regionName` - specifies the name of the Apache Geode `Region` used to store and manage `HttpSession` state
(default is "*ClusteredSpringSessions*").
* `serverRegionShortcut` - specifies Apache Geode http://geode.apache.org/docs/guide/12/developing/region_options/region_types.html[data management policy]
on the server using a Apache Geode http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server `Regions`, or when a P2P topology is employed.
* `serverRegionShortcut` - specifies Apache Geode {data-store-docs}/developing/region_options/region_types.html[data management policy]
on the server with the {data-store-javadoc}/org/apache/geode/cache/RegionShortcut.html[RegionShortcut]
(default is `PARTITION`). This attribute is only used when configuring server `Regions`,
or when a P2P topology is employed.
== Java Servlet Container Initialization
Our <<[httpsession-spring-java-configuration-gemfire-p2p,Spring Java Configuration>> created a _Spring_ bean named
`springSessionRepositoryFilter` that implements `javasx.servlet.Filter`. The `springSessionRepositoryFilter` bean
is responsible for replacing the `javax.servlet.http.HttpSession` with a custom implementation backed by _Spring Session_
and Apache Geode.
Our <<[httpsession-spring-java-configuration-gemfire-p2p,Spring Java Configuration>> created a Spring bean named
`springSessionRepositoryFilter` that implements `javax.servlet.Filter`. The `springSessionRepositoryFilter` bean
is responsible for replacing the `javax.servlet.http.HttpSession` with a custom implementation backed by
Spring Session and Apache Geode.
In order for our `Filter` to do its magic, _Spring_ needs to load our `Config` class. We also need to ensure our Servlet container (i.e. Tomcat) uses our `springSessionRepositoryFilter` on every HTTP request.
In order for our `Filter` to do its magic, Spring needs to load our `Config` class. We also need to ensure our
Servlet container (i.e. Tomcat) uses our `springSessionRepositoryFilter` on every HTTP request.
Fortunately, _Spring Session_ provides a utility class named `AbstractHttpSessionApplicationInitializer` to make both
of these steps extremely easy.
Fortunately, Spring Session provides a utility class named `AbstractHttpSessionApplicationInitializer` to make both
steps extremely easy.
You can find an example below:
@@ -135,9 +134,9 @@ include::{samples-dir}javaconfig/gemfire-p2p/src/main/java/sample/Initializer.ja
NOTE: The name of our class (`Initializer`) does not matter. What is important is that we extend
`AbstractHttpSessionApplicationInitializer`.
<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`. This ensures that a _Spring_ bean named
<1> The first step is to extend `AbstractHttpSessionApplicationInitializer`. This ensures that a Spring bean named
`springSessionRepositoryFilter` is registered with our Servlet container and used on every HTTP request.
<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily allow _Spring_ to load
<2> `AbstractHttpSessionApplicationInitializer` also provides a mechanism to easily allow Spring to load
our `Config` class.
// end::config[]
@@ -175,42 +174,6 @@ include::{samples-dir}javaconfig/gemfire-p2p/src/main/java/sample/SessionServlet
Instead of using Tomcat's `HttpSession`, we are actually persisting the Session in Apache Geode.
_Spring Session_ creates a cookie named SESSION in your browser that contains the id of your Session.
Spring Session creates a cookie named SESSION in your browser that contains the id of your Session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome]
or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
NOTE: The following instructions assume you have a local Apache Geode installation. For more information on installation,
see http://geode.apache.org/docs/guide/12/prereq_and_install.html[Prerequisites and Installation Instructions].
If you like, you can easily remove the Session using `gfsh`.
For example, on a Linux-based system type the following at the command-line:
$ gfsh
Then, enter the following into _Gfsh_, ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value
of your SESSION cookie, or the Session id returned by the Apache Geode OQL query (which should match):
....
gfsh>connect --jmx-manager=localhost[1099]
gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet'
Result : true
startCount : 0
endCount : 20
Rows : 1
Result
------------------------------------
70002719-3c54-4c20-82c3-e7faa6b718f3
NEXT_STEP_NAME : END
gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3"
....
NOTE: The _Apache Geode User Guide_ contains more detailed instructions on using
http://geode.apache.org/docs/guide/12/tools_modules/gfsh/chapter_overview.html[gfsh].
Now visit the application at `http://localhost:8080/` again and observe the attribute we added is no longer displayed.

View File

@@ -2,14 +2,14 @@
John Blum
:toc:
This guide describes how to configure _Spring Session_ to transparently leverage Apache Geode to manage
This guide describes how to configure Apache Geode as a provider in Spring Session to transparently manage
a Web application's `javax.servlet.http.HttpSession` using XML Configuration.
NOTE: The completed guide can be found in the <<spring-session-sample-xml-geode-clientserver,Spring XML Configuation>>.
== Updating Dependencies
Before using _Spring Session_, you must ensure that the required dependencies are included.
Before using Spring Session, you must ensure that the required dependencies are included.
If you are using _Maven_, include the following `dependencies` in your `pom.xml`:
.pom.xml
@@ -34,7 +34,7 @@ If you are using _Maven_, include the following `dependencies` in your `pom.xml`
----
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to add the _Spring_ Snapshot Maven Repository.
Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -52,7 +52,7 @@ If you are using _Maven_, include the following `repository` declaration in your
endif::[]
ifeval::["{version-milestone}" == "true"]
Since we are using a Milestone version, we need to add the _Spring_ Milestone Maven Repository.
Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -73,13 +73,13 @@ endif::[]
[[spring-session-sample-xml-geode-clientserver]]
== Spring XML Configuration
After adding the required dependencies and repository declarations, we can create the _Spring_ configuration.
The _Spring_ configuration is responsible for creating a `Servlet` `Filter` that replaces the `javax.servlet.http.HttpSession`
with an implementation backed by _Spring Session_ and Apache Geode.
After adding the required dependencies and repository declarations, we can create the Spring configuration.
The Spring configuration is responsible for creating a `Servlet` `Filter` that replaces the
`javax.servlet.http.HttpSession` with an implementation backed by Spring Session and Apache Geode.
=== Client Configuration
Add the following _Spring_ configuration:
Add the following Spring configuration:
[source,xml]
----
@@ -87,30 +87,29 @@ include::{samples-dir}xml/gemfire-clientserver/src/main/webapp/WEB-INF/spring/se
----
<1> (Optional) First, we can include a `Properties` bean to configure certain aspects of the Apache Geode `ClientCache`
using http://geode.apache.org/docs/guide/12/reference/topics/gemfire_properties.html[Pivotal GemFire Properties].
In this case, we are just setting Apache Geode's "`log-level`" from a application-specific System property,
defaulting to "`warning`" if unspecified.
<2> We must create an instance of an Apache Geode `ClientCache` initialized with our `gemfireProperties`.
<3> Then we configure a `Pool` of client connections to talk to the Apache Geode Server in our Client/Server topology.
using {data-store-docs}/reference/topics/gemfire_properties.html[Pivotal GemFire Properties]. In this case, we are just
setting Apache Geode's "`log-level`" using an application-specific System property, defaulting to "`warning`"
if unspecified.
<2> We must create an instance of an Apache Geode `ClientCache`. We initialize it with our `gemfireProperties`.
<3> Then we configure a `Pool` of connections to talk to the Apache Geode Server in our Client/Server topology.
In our configuration, we use sensible settings for timeouts, number of connections and so on. Also, our `Pool`
has been configured to connect directly to the server.
<4> Finally, a `GemFireHttpSessionConfiguration` bean is registered to enable _Spring Session_ functionality.
has been configured to connect directly to the server (using the nested `gfe:server` element).
<4> Finally, a `GemFireHttpSessionConfiguration` bean is registered to enable Spring Session functionality.
TIP: In typical Apache Geode production deployments, where the cluster includes potentially hundreds or thousands
of Apache Geode servers (data nodes), it is more common for clients to connect to 1 or more Apache Geode Locators running
in the cluster. A Locator passes meta-data to clients about the servers available in the cluster, the server load
and which servers have the client's data of interest, which is particularly important for direct, single-hop data access
and latency-sensitive operations. See more details about the
http://geode.apache.org/docs/guide/12/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
of servers (a.k.a. data nodes), it is more common for clients to connect to 1 or more Apache Geode Locators running
in the same cluster. A Locator passes meta-data to clients about the servers available in the cluster, the individual
server load and which servers have the client's data of interest, which is particularly important for direct,
single-hop data access and latency-sensitive applications. See more details about the
{data-store-docs}/topologies_and_comm/cs_configuration/standard_client_server_deployment.html[Client/Server Deployment]
in the Apache Geode User Guide.
NOTE: For more information on configuring _Spring Data Geode, refer to the
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[Reference Guide].
NOTE: For more information on configuring Spring Data for Apache Geode, refer to the {sdg-docs}[Reference Guide].
=== Server Configuration
So far, we only covered one side of the equation. We also need an Apache Geode Server for our cache client to talk to
and send Session state to the server to manage.
and send session state to the server to manage.
In this sample, we will use the following XML configuration to spin up an Apache Geode Server:
@@ -120,14 +119,14 @@ include::{samples-dir}xml/gemfire-clientserver/src/main/resources/META-INF/sprin
----
<1> (Optional) First, we can include a `Properties` bean to configure certain aspects of the Apache Geode peer `Cache`
using http://geode.apache.org/docs/guide/12/reference/topics/gemfire_properties.html[Pivotal GemFire Properties].
In this case, we are just setting Apache Geode's "`log-level`" from a application-specific System property,
defaulting to "`warning`" if unspecified.
<2> We must configure an Apache Geode peer `Cache` instance initialized with the Apache Geode properties.
using {data-store-docs}/reference/topics/gemfire_properties.html[Pivotal GemFire Properties]. In this case, we are just
setting Apache Geode's "`log-level`" using an application-specific System property, defaulting to "`warning`"
if unspecified.
<2> We must configure an Apache Geode peer `Cache` instance. We initialize it with the Apache Geode properties.
<3> Next, we define a `CacheServer` with sensible configuration for `bind-address` and `port` used by our cache client
application to connect to the server to pass Session state.
<4> Finally, we enable the same _Spring Session_ functionality we declared in the client XML configuration
by registering an instance of `GemFireHttpSessionConfiguration`, except we set the Session expiration timeout
application to connect to the server and send session state.
<4> Finally, we enable the same Spring Session functionality we declared in the client XML configuration
by registering an instance of `GemFireHttpSessionConfiguration`, except we set the session expiration timeout
to **30 seconds**. We explain what this means later.
The Apache Geode Server gets bootstrapped with the following:
@@ -137,19 +136,20 @@ The Apache Geode Server gets bootstrapped with the following:
include::{samples-dir}xml/gemfire-clientserver/src/main/java/sample/ServerConfig.java[tags=class]
----
TIP: Rather than defining a simple Java class with a `main` method, you might consider using _Spring Boot_ instead.
TIP: Rather than defining a simple Java class with a `main` method, you might consider using Spring Boot instead.
<1> The `@Configuration` annotation designates this Java class as a source of _Spring_ configuration meta-data using
7.9. Annotation-based container configuration[_Spring's_ annotation configuration support].
<1> The `@Configuration` annotation designates this Java class as a source of Spring configuration meta-data using
7.9. Annotation-based container configuration[Spring's annotation configuration support].
<2> Primarily, the configuration comes from the `META-INF/spring/session-server.xml` file.
== XML Servlet Container Initialization
Our <<httpsession-spring-xml-configuration,Spring XML Configuration>> created a _Spring_ bean named `springSessionRepositoryFilter`
that implements `javax.servlet.Filter` intervace. The `springSessionRepositoryFilter` bean is responsible for replacing
the `javax.servlet.http.HttpSession` with a custom implementation that is provided by _Spring Session_ and Apache Geode.
Our <<httpsession-spring-xml-configuration,Spring XML Configuration>> created a Spring bean named `springSessionRepositoryFilter`
that implements `javax.servlet.Filter` interface. The `springSessionRepositoryFilter` bean is responsible for replacing
the `javax.servlet.http.HttpSession` with a custom implementation that is provided by Spring Session and Apache Geode.
In order for our `Filter` to do its magic, we need to instruct _Spring_ to load our `session-client.xml` configuration file.
In order for our `Filter` to do its magic, we need to instruct Spring to load
our `session-client.xml` configuration file.
We do this with the following configuration:
@@ -201,8 +201,8 @@ $ ./gradlew :spring-session-sample-javaconfig-gemfire-clientserver:tomcatRun [-g
You should now be able to access the application at http://localhost:8080/.
In this sample, the web application is the Apache Geode cache client
and the server is standalone, separate (JVM) process.
In this sample, the Web application is the Apache Geode cache client and the server is a standalone, separate
JVM process.
=== Exploring the httpsession-gemfire-clientserver-xml Sample Application
@@ -225,47 +225,6 @@ include::{samples-dir}xml/gemfire-clientserver/src/main/java/sample/SessionServl
Instead of using Tomcat's `HttpSession`, we are actually persisting the Session in Apache Geode.
_Spring Session_ creates a cookie named SESSION in your browser that contains the id of your Session.
Spring Session creates a cookie named SESSION in your browser that contains the id of your Session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome]
or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
NOTE: The following instructions assume you have a local Apache Geode installation. For more information on installation,
see http://geode.apache.org/docs/guide/12/prereq_and_install.html[Prerequisites and Installation Instructions].
If you like, you can easily remove the session using `gfsh`.
For example, on a Linux-based system type the following at the command-line:
$ gfsh
Then, enter the following commands in _Gfsh_, ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value
of your SESSION cookie, or the Session id returned by the Apache Geode OQL query (which should match):
....
gfsh>connect --jmx-manager=localhost[1099]
gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet'
Result : true
startCount : 0
endCount : 20
Rows : 1
Result
------------------------------------
70002719-3c54-4c20-82c3-e7faa6b718f3
NEXT_STEP_NAME : END
gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3"
....
NOTE: The _Apache Geode User Guide_ contains more detailed instructions on using
http://geode.apache.org/docs/guide/12/tools_modules/gfsh/chapter_overview.html[gfsh].
Now visit the application at `http://localhost:8080/` again and observe the attribute we added is no longer displayed.
Alternatively, you can wait **20 seconds** for the Session to timeout and expire and then refresh the page.
The attribute we added should no longer be displayed in the table. However, keep in mind, by refreshing the page,
you will inadvertently create a new (empty) Session. If you run the query again, you will also see two Session ids,
the new and the old, since Apache Geode keeps a "tombstone" of the old Session around.

View File

@@ -2,7 +2,7 @@
John Blum
:toc:
This guide describes how to configure Apache Geode as a provider in _Spring Session_ to transparently manage
This guide describes how to configure Apache Geode as a provider in Spring Session to transparently manage
a Web application's `javax.servlet.http.HttpSession` using XML configuration.
NOTE: The completed guide can be found in the
@@ -10,7 +10,7 @@ NOTE: The completed guide can be found in the
== Updating Dependencies
Before using _Spring Session_, you must ensure that the required dependencies are included.
Before using Spring Session, you must ensure that the required dependencies are included.
If you are using _Maven_, include the following `dependencies` in your `pom.xml`:
.pom.xml
@@ -35,7 +35,7 @@ If you are using _Maven_, include the following `dependencies` in your `pom.xml`
----
ifeval::["{version-snapshot}" == "true"]
Since we are using a SNAPSHOT version, we need to add the _Spring_ Snapshot Maven Repository.
Since we are using a SNAPSHOT version, we need to add the Spring Snapshot Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -53,7 +53,7 @@ If you are using _Maven_, include the following `repository` declaration in your
endif::[]
ifeval::["{version-milestone}" == "true"]
Since we are using a Milestone version, we need to add the _Spring_ Milestone Maven Repository.
Since we are using a Milestone version, we need to add the Spring Milestone Maven Repository.
If you are using _Maven_, include the following `repository` declaration in your `pom.xml`:
.pom.xml
@@ -74,10 +74,10 @@ endif::[]
[[httpsession-spring-xml-configuration]]
== Spring XML Configuration
After adding the required dependencies and repository declarations, we can create the _Spring_ configuration.
After adding the required dependencies and repository declarations, we can create the Spring configuration.
The _Spring_ configuration is responsible for creating a `Servlet` `Filter` that replaces the `javax.servlet.http.HttpSession`
with an implementation backed by _Spring Session_ and Apache Geode.
The Spring configuration is responsible for creating a `Servlet` `Filter` that replaces the
`javax.servlet.http.HttpSession` with an implementation backed by Spring Session and Apache Geode.
Add the following Spring configuration:
@@ -88,25 +88,21 @@ include::{samples-dir}xml/gemfire-p2p/src/main/webapp/WEB-INF/spring/session.xml
----
<1> (Optional) First, we can include a `Properties` bean to configure certain aspects of the Apache Geode peer `Cache`
using http://geode.apache.org/docs/guide/12/reference/topics/gemfire_properties.html[Pivotal GemFire Properties].
In this case, we are just setting Apache Geode's "`log-level`" from a application-specific System property,
defaulting to "`warning`" if unspecified.
<2> We must configure an Apache Geode peer `Cache` instance initialized with the Apache Geode properties.
<3> Finally, we enable _Spring Session_ functionality by registering an instance of `GemFireHttpSessionConfiguration`.
using {data-store-docs}/reference/topics/gemfire_properties.html[Pivotal GemFire Properties]. In this case, we are just
setting Apache Geode's "`log-level`" using an application-specific System property, defaulting to "`warning`"
if unspecified.
<2> We must configure an Apache Geode peer `Cache` instance. We initialize it with the Apache Geode properties.
<3> Finally, we enable Spring Session functionality by registering an instance of `GemFireHttpSessionConfiguration`.
TIP: Additionally, we have configured this data node (server) as a Apache Geode Manager as well using Apache Geode-specific
JMX properties that enable JMX client (e.g. _Gfsh_) to connect to this running server.
NOTE: For more information on configuring _Spring Data Geode, refer to the
http://docs.spring.io/spring-data-gemfire/docs/current/reference/html/[Reference Guide].
NOTE: For more information on configuring Spring Data for Apache Geode, refer to the {sdg-docs}[Reference Guide].
== XML Servlet Container Initialization
The <<httpsession-spring-xml-configuration,Spring XML Configuration>> created a _Spring_ bean named `springSessionRepositoryFilter`
that implements `javax.servlet.Filter`. The `springSessionRepositoryFilter` bean is responsible for replacing
the `javax.servlet.http.HttpSession` with a custom implementation that is backed by _Spring Session_ and Apache Geode.
The <<httpsession-spring-xml-configuration,Spring XML Configuration>> created a Spring bean named `springSessionRepositoryFilter`
that implements `javax.servlet.Filter`. The `springSessionRepositoryFilter` bean is responsible for replacing the
`javax.servlet.http.HttpSession` with a custom implementation that is backed by Spring Session and Apache Geode.
In order for our `Filter` to do its magic, we need to instruct _Spring_ to load our `session.xml` configuration file.
In order for our `Filter` to do its magic, we need to instruct Spring to load our `session.xml` configuration file.
We do this with the following configuration:
@@ -168,44 +164,8 @@ We interact with the standard `HttpSession` in the `SessionServlet` shown below:
include::{samples-dir}xml/gemfire-p2p/src/main/java/sample/SessionServlet.java[tags=class]
----
Instead of using Tomcat's `HttpSession`, we are actually persisting the Session in Apache Geode.
Instead of using Tomcat's `HttpSession`, we are actually persisting the session in Apache Geode.
_Spring Session_ creates a cookie named SESSION in your browser that contains the id of your session.
Spring Session creates a cookie named SESSION in your browser that contains the id of your session.
Go ahead and view the cookies (click for help with https://developer.chrome.com/devtools/docs/resources#cookies[Chrome]
or https://getfirebug.com/wiki/index.php/Cookies_Panel#Cookies_List[Firefox]).
NOTE: The following instructions assume you have a local Apache Geode installation. For more information on installation,
see http://geode.apache.org/docs/guide/12/prereq_and_install.html[Prerequisites and Installation Instructions].
If you like, you can easily remove the session using `gfsh`.
For example, on a Linux-based system type the following at the command-line:
$ gfsh
Then, enter the following into _Gfsh_, ensuring to replace `70002719-3c54-4c20-82c3-e7faa6b718f3` with the value
of your SESSION cookie, or the Session id returned by the Apache Geode OQL query (which should match):
....
gfsh>connect --jmx-manager=localhost[1099]
gfsh>query --query='SELECT * FROM /ClusteredSpringSessions.keySet'
Result : true
startCount : 0
endCount : 20
Rows : 1
Result
------------------------------------
70002719-3c54-4c20-82c3-e7faa6b718f3
NEXT_STEP_NAME : END
gfsh>remove --region=/ClusteredSpringSessions --key="70002719-3c54-4c20-82c3-e7faa6b718f3"
....
NOTE: The _Apache Geode User Guide_ contains more detailed instructions on using
http://geode.apache.org/docs/guide/12/tools_modules/gfsh/chapter_overview.html[gfsh].
Now visit the application at `http://localhost:8080/` again and observe the attribute we added is no longer displayed.

View File

@@ -69,7 +69,7 @@ public class Application {
}
@ClientCacheApplication(name = "SpringSessionDataGeodeBootSampleWithScopedProxiesClient", logLevel = "error",
pingInterval = 5000L, readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true) // <3>
readTimeout = 15000, retryAttempts = 1, subscriptionEnabled = true) // <3>
@EnableGemFireHttpSession(poolName = "DEFAULT") // <4>
static class ClientCacheConfiguration { }

View File

@@ -35,7 +35,7 @@ import org.springframework.session.data.gemfire.config.annotation.web.http.Enabl
*/
// tag::class[]
@SpringBootApplication // <1>
@CacheServerApplication(name = "SpringSessionDataGeodeBootSampleServer", logLevel = "config") // <2>
@CacheServerApplication(name = "SpringSessionDataGeodeBootSampleServer", logLevel = "error") // <2>
@EnableGemFireHttpSession(maxInactiveIntervalInSeconds = 20) // <3>
public class GemFireServer {

View File

@@ -16,8 +16,6 @@
package sample;
import java.io.IOException;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
@@ -28,7 +26,7 @@ import org.springframework.session.data.gemfire.config.annotation.web.http.Enabl
public class ServerConfig {
@SuppressWarnings("resource")
public static void main(String[] args) throws IOException {
public static void main(String[] args) {
new AnnotationConfigApplicationContext(ServerConfig.class).registerShutdownHook();
}
}

View File

@@ -20,7 +20,7 @@ import org.springframework.data.gemfire.config.annotation.PeerCacheApplication;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
// tag::class[]
@PeerCacheApplication(name = "SpringSessionSampleJavaConfigGemFireP2p", logLevel = "error") // <1>
@PeerCacheApplication(name = "SpringSessionDataGeodeJavaConfigP2pSample", logLevel = "error") // <1>
@EnableGemFireHttpSession // <2>
public class Config {

View File

@@ -18,12 +18,12 @@
<!--1-->
<util:properties id="gemfireProperties">
<prop key="name">SpringSessionSampleXmlGemFireP2p</prop>
<prop key="name">SpringSessionDataGeodeXmlP2pSample</prop>
<prop key="log-level">${spring.session.data.geode.log-level:error}</prop>
</util:properties>
<!--2-->
<gfe:cache properties-ref="gemfireProperties" use-bean-factory-locator="false"/>
<gfe:cache properties-ref="gemfireProperties"/>
<!--3-->
<bean class="org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration"/>