Update to Spring Boot 1.4.1.RELEASE
* Upgrade to Spring Data GemFire 1.8.4.RELEASE * Upgrade to Spring Data MongoDB 1.9.4.RELEASE * Upgrade to Spring Framework 4.3.3.RELEASE (Upgrade to Spring Data Redis 1.7.4.RELEASE failed) Fixes gh-632
This commit is contained in:
@@ -89,16 +89,17 @@ We start with the _Spring Boot_ application for configuring and bootstrapping a
|
||||
include::{samples-dir}httpsession-gemfire-boot/src/main/java/sample/server/GemFireServer.java[tags=class]
|
||||
----
|
||||
|
||||
<1> The `@EnableGemFireHttpSession` annotation is used on the GemFire Server mainly to define the corresponding
|
||||
<1> The `@EnableGemFireHttpSession` annotation is used on the GemFire Server to mainly define the corresponding
|
||||
Region (e.g. `ClusteredSpringSessions`, the default) in which Session state information will be stored
|
||||
and managed by GemFire. As well, we have specified an arbitrary expiration attribute (i.e. `maxInactiveIntervalInSeconds`)
|
||||
for when the Session will timeout, which is triggered by a GemFire Region entry expiration event that also invalidates
|
||||
the Session object in the Region.
|
||||
<2> Next, we define a few `Properties` allowing us to configure certain aspects of the GemFire Server using
|
||||
<2> Next, we define a few `Properties` that allow us to configure certain aspects of the GemFire Server using
|
||||
http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html[GemFire's System properties].
|
||||
<3> Then, we create an instance of the GemFire Cache using our defined `Properties`.
|
||||
<4> Finally, we setup a Cache Server instance running in the GemFire Server to listen for connections from cache clients.
|
||||
The Cache Server `Socket` will be used to connect our GemFire client cache, _Spring Boot_ web application to the server.
|
||||
<3> Then, we create an instance of the GemFire `Cache` using our defined `Properties`.
|
||||
<4> Finally, we configure and start a `CacheServer` running in the GemFire Server to listen for connections
|
||||
from cache clients. The `CacheServer's` `Socket` will be used to connect our GemFire cache client,
|
||||
_Spring Boot_ web application to the server.
|
||||
|
||||
The sample also makes use of a `PropertySourcesPlaceholderConfigurer` bean in order to externalize the sample application
|
||||
configuration to affect GemFire and application configuration/behavior from the command-line (e.g. such as GemFire's
|
||||
@@ -106,9 +107,9 @@ configuration to affect GemFire and application configuration/behavior from the
|
||||
|
||||
=== Spring Boot-based GemFire cache client Web application
|
||||
|
||||
Now, we create the _Spring Boot_ web application (a GemFire cache client), exposing our Web service
|
||||
using Spring MVC along with _Spring Session_ backed by GemFire, connected to our _Spring Boot_-based GemFire Server,
|
||||
in order to manage Session state in a cluster/replicated-enabled fashion.
|
||||
Now, we create our _Spring Boot_ Web application exposing our Web service with Spring MVC, running as a
|
||||
GemFire cache client connected to our _Spring Boot_-based GemFire Server, using Spring Session backed by GemFire
|
||||
to manage Session state in a clustered, replicated fashion.
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -116,28 +117,29 @@ include::{samples-dir}httpsession-gemfire-boot/src/main/java/sample/client/Appli
|
||||
----
|
||||
|
||||
<1> Here, again, we use the `@EnableGemFireHttpSession` annotation to not only configure the GemFire cache client,
|
||||
but also to override the (HTTP) Web application container's `HttpSession` and replace it with a Session implementation
|
||||
backed by _Spring Session_ in conjunction with GemFire. Also notice, we did not define any Session expiration timeout
|
||||
with the `maxInactiveIntervalInSeconds` attribute this time. That is because the Session expiration is managed
|
||||
by GemFire, which will appropriately notify the cache client when the Session times out. Again, we have just resorted
|
||||
to using the default Region, `ClusteredSpringSessions`. Of course, we can change the Region name, but we must do so
|
||||
on both the client and the server. That is a GemFire requirement, not a _Spring Session Data GemFire_ requirement.
|
||||
<2> Similary to the server configuration, we set a few basic GemFire System `Properties` on the client.
|
||||
<3> Although, this time, an instance of `ClientCache` is created with the `ClientCacheFactoryBean` from _Spring Data GemFire_.
|
||||
<4> However, in order to connect to the GemFire Server we must define a GemFire `Pool` bean containing pre-populated
|
||||
connections to the server. Whenever a client Region entry operation corresponding to a Session update occurs,
|
||||
but to also override the (HTTP) Web application container's `HttpSession` and replace it with a Session implementation
|
||||
backed by _Spring Session_ and GemFire. Also notice, we did not define any Session expiration timeout with the
|
||||
`maxInactiveIntervalInSeconds` attribute this time. That is because the Session expiration is managed by GemFire,
|
||||
on the server, which will appropriately notify the cache client when the Session times out. Again, we have just
|
||||
resorted to using the default named Region, `ClusteredSpringSessions`. Of course, we can change the Region name,
|
||||
but we must do so on both the client and the server. That is a GemFire requirement, not a
|
||||
_Spring Session Data GemFire_ requirement.
|
||||
<2> Similarly to the server configuration, we set a few basic GemFire System `Properties` on the client.
|
||||
<3> Although, this time, an instance of `ClientCache` is created with the `ClientCacheFactoryBean`
|
||||
from _Spring Data GemFire_.
|
||||
<4> However, in order to connect to the GemFire Server we must define a GemFire `Pool` bean containing a
|
||||
pool of connections to the server. Whenever a client Region entry operation corresponding to a Session update occurs,
|
||||
the client-side Region will use an existing, pooled connection to route the operation to the server.
|
||||
<5> The following _Spring_ `BeanPostProcessor` (along with some utility methods) are only needed for testing purposes
|
||||
and is not required by any production code. Specifically, the `BeanPostProcessor` along with the code referenced in *6*
|
||||
and are not required by any production code. Specifically, the `BeanPostProcessor` along with the code referenced in *6*
|
||||
is useful in integration test cases where the client and server processes are forked by the test framework. It is pretty
|
||||
easy to figure out that a race condition is imminent without proper coordination between the client and the server,
|
||||
therefore, the BPP and `ClientMembershipListener` help sync the interaction between the client and the server
|
||||
on startup during automated testing.
|
||||
<6> See <5> above.
|
||||
<7> Navigates the Web application to the home page (`index.html`), which uses **Thymeleaf** templates for server-side
|
||||
<6> Navigates the Web application to the home page (`index.html`), which uses **Thymeleaf** templates for server-side
|
||||
pages.
|
||||
<8> Heartbeat web service endpoint (useful for manual testing purposes).
|
||||
<9> Web service endpoint for adding a Session attributes defined by the user using the Web application UI. In addition,
|
||||
<7> Heartbeat Web service endpoint (useful for manual testing purposes).
|
||||
<8> Web service endpoint allowing the user to add a Session attribute using the Web application UI. In addition,
|
||||
the webapp stores an additional Session attribute (`requestCount`) to keep track of how many HTTP requests the user
|
||||
has sent during the current "session".
|
||||
|
||||
@@ -159,11 +161,13 @@ and GemFire out-of-the-box using the following attributes:
|
||||
* `clientRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy]
|
||||
with a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
|
||||
(default is `PROXY`). This attribute is only used when configuring client Region.
|
||||
* `poolName` - name of the dedicated GemFire Pool used to connect a client to the cluster of servers. The attribute
|
||||
is only used when the application is a GemFire cache client. Defaults to `gemfirePool`.
|
||||
* `serverRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy]
|
||||
using a GemFire http://data-docs-samples.cfapps.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/RegionShortcut.html[RegionShortcut]
|
||||
(default is `PARTITION`). This attribute is only used when configuring server Regions, or when a p2p topology is employed.
|
||||
|
||||
NOTE: It is important to note that the GemFire client Region name must match a server Region by the same name if
|
||||
NOTE: It is important to remember that the GemFire client Region name must match a server Region by the same name if
|
||||
the client Region is a `PROXY` or `CACHING_PROXY`. Client and server Region names are not required to match if
|
||||
the client Region used to store Spring Sessions is `LOCAL`. However, keep in mind that your session state will not
|
||||
be propagated to the server and you lose all the benefits of using GemFire to store and manage distributed, replicated
|
||||
|
||||
@@ -83,23 +83,23 @@ Add the following Spring Configuration:
|
||||
include::{samples-dir}httpsession-gemfire-clientserver-xml/src/main/webapp/WEB-INF/spring/session-client.xml[tags=beans]
|
||||
----
|
||||
|
||||
<1> First, a `Properties` bean is created to reference GemFire configuration common to both the client and server,
|
||||
stored in the `META-INF/spring/application.properties` file.
|
||||
<2> The `application.properties` are used along with the `PropertySourcesPlaceholderConfigurer` bean to replace
|
||||
placeholders in the Spring XML configuration meta-data with property values.
|
||||
<3> Spring annotation configuration support is enabled with `<context:annotation-config/>` element so that any
|
||||
<1> Spring annotation configuration support is enabled with `<context:annotation-config/>` element so that any
|
||||
Spring beans declared in the XML config that are annotated with either Spring or Standard Java annotations supported
|
||||
by Spring will be configured appropriately.
|
||||
<4> `GemFireHttpSessionConfiguration` is registered to enable Spring Session functionality.
|
||||
<5> Then, a Spring `BeanPostProcessor` is registered to determine whether a GemFire Server at the designated host/port
|
||||
is running, blocking client startup until the server is available.
|
||||
<6> Next, we include a `Properties` bean to configure certain aspects of the GemFire client cache using
|
||||
http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html[GemFire's System properties].
|
||||
In this case, we are just setting GemFire's `log-level` from a sample application-specific System property, defaulting
|
||||
<2> The `META-INF/spring/application.properties` file are used along with the `PropertySourcesPlaceholderConfigurer`
|
||||
bean to replace placeholders in the Spring XML configuration meta-data with the approrpriate property values.
|
||||
<3> Then the `GemFireCacheSeverReadyBeanPostProcessor`is registered to determine whether a GemFire Server
|
||||
at the designated host/port is running and listening for client connections, blocking client startup until
|
||||
the server is available and ready.
|
||||
<4> Next, we include a `Properties` bean to configure certain aspects of the GemFire client cache using
|
||||
http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html[GemFire's System Properties].
|
||||
In this case, we are just setting GemFire's `log-level` from a application-specific System property, defaulting
|
||||
to `warning` if unspecified.
|
||||
<7> Finally, we create the GemFire client cache and configure a Pool of client connections to talk to the GemFire Server
|
||||
in our Client/Server topology. In our configuration, we use sensible settings for timeouts, number of connections
|
||||
and so on. Also, our `Pool` has been configured to connect directly to a server.
|
||||
<5> Then we create a instance of a GemFire `ClientCache` initialized with our `gemfireProperties`.
|
||||
<6> We configure a Pool of client connections to talk to the GemFire Server in our Client/Server topology.
|
||||
In our configuration, we use sensible settings for timeouts, number of connections and so on. Also, our `Pool`
|
||||
has been configured to connect directly to a server.
|
||||
<7> Finally, the `GemFireHttpSessionConfiguration` is registered to enable Spring Session functionality.
|
||||
|
||||
TIP: In typical GemFire deployments, where the cluster includes potentially hundreds of GemFire data nodes (servers),
|
||||
it is more common for clients to connect to one or more GemFire Locators running in the cluster. A Locator passes meta-data
|
||||
@@ -110,8 +110,8 @@ NOTE: For more information on configuring _Spring Data GemFire_, refer to the ht
|
||||
|
||||
=== Server Configuration
|
||||
|
||||
Now, we have only covered one side of the equation. We also need a GemFire Server for our client to talk to and pass
|
||||
session state information up to the server to manage.
|
||||
We have only covered one side of the equation. We also need a GemFire Server for our client to talk to and send
|
||||
session state information to the server to manage.
|
||||
|
||||
In this sample, we will use the following GemFire Server Java Configuration:
|
||||
|
||||
@@ -124,15 +124,16 @@ include::{samples-dir}httpsession-gemfire-clientserver-xml/src/main/resources/ME
|
||||
Spring beans declared in the XML config that are annotated with either Spring or Standard Java annotations supported
|
||||
by Spring will be configured appropriately.
|
||||
<2> A `PropertySourcesPlaceholderConfigurer` is registered to replace placeholders in our Spring XML configuration
|
||||
meta-data with property values from `META-INF/spring/application.properties`.
|
||||
<3> We enable the same Spring Session functionality that we used on the client by registering an instance of `GemFireHttpSessionConfiguration`,
|
||||
except that we set the session expiration timeout to **30 seconds**. We will explain later what this means.
|
||||
<4> Next, we configure the GemFire Server using GemFire System properties very much like our P2P samples.
|
||||
meta-data with property values in the `META-INF/spring/application.properties` file.
|
||||
<3> Next, we configure the GemFire Server using GemFire System Properties very much like our P2P samples.
|
||||
With the `mcast-port` set to 0 and no `locators` property specified, our server will be standalone. We also allow a
|
||||
JMX client (e.g. _Gfsh_) to connect to our server with the use of the GemFire-specific JMX System properties.
|
||||
<5> Then, we create an instance of the GemFire peer cache using our GemFire System properties.
|
||||
<6> And finally, we also setup a GemFire `CacheServer` instance running on *localhost*, listening on port **11235**,
|
||||
to accept our client connection.
|
||||
<4> Then we create an instance of a GemFire peer `Cache` initialized with our GemFire System Properties.
|
||||
<5> We also setup a GemFire `CacheServer` instance running on *localhost*, listening to port **11235**,
|
||||
ready to accept our client connection.
|
||||
<6> Finally, we enable the same Spring Session functionality we used on the client by registering an instance of
|
||||
`GemFireHttpSessionConfiguration`, except that we set the session expiration timeout to **30 seconds**.
|
||||
We will explain later what this means.
|
||||
|
||||
The GemFire Server configuration gets bootstrapped with the following:
|
||||
|
||||
|
||||
@@ -84,33 +84,26 @@ include::{samples-dir}httpsession-gemfire-clientserver/src/main/java/sample/Clie
|
||||
----
|
||||
|
||||
<1> The `@EnableGemFireHttpSession` annotation creates a Spring bean named `springSessionRepositoryFilter` that
|
||||
implements `Filter`. The filter is what replaces the `HttpSession` with an implementation backed by Spring Session.
|
||||
In this instance, Spring Session is backed by GemFire.
|
||||
implements `Filter`. The filter is what replaces the `HttpSession` with an implementation backed by Spring Session
|
||||
and GemFire.
|
||||
<2> Next, we register a `Properties` bean that allows us to configure certain aspects of the GemFire client cache
|
||||
using http://gemfire.docs.pivotal.io/docs-gemfire/reference/topics/gemfire_properties.html[GemFire's System properties].
|
||||
<3> Then, we configure a `Pool` of client connections to talk to the GemFire Server in our Client/Server topology. In our
|
||||
<3> We use the `Properties` to configure an instance of a GemFire `ClientCache`.
|
||||
<4> Then, we configure a `Pool` of client connections to talk to the GemFire Server in our Client/Server topology. In our
|
||||
configuration, we have used sensible settings for timeouts, number of connections and so on. Also, the `Pool` has been
|
||||
configured to connect directly to a server. Learn more about various `Pool` configuration settings from the
|
||||
http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/client/PoolFactory.html[PoolFactory API].
|
||||
<4> After configuring a `Pool`, we create an instance of the GemFire client cache using the GemFire `Properties`
|
||||
and `Pool` to communicate with the server and perform cache data access operations.
|
||||
<5> Finally, we include a Spring `BeanPostProcessor` to block the client until our GemFire Server is up and running,
|
||||
<56> Finally, we include a Spring `BeanPostProcessor` to block the client until our GemFire Server is up and running,
|
||||
listening for and accepting client connections.
|
||||
|
||||
The `gemfireCacheServerReadyBeanPostProcessor` is necessary in order to coordinate the client and server in
|
||||
an automated fashion during testing, but unnecessary in situations where the GemFire cluster is already presently
|
||||
running, such as in production. This `BeanPostProcessor` implements 2 approaches to ensure our server has adequate
|
||||
time to startup.
|
||||
running, such as in production.
|
||||
|
||||
The first approach uses a timed wait, checking at periodic intervals to determine whether a client `Socket` connection
|
||||
can be made to the server's `CacheServer` endpoint.
|
||||
|
||||
The second approach uses a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/management/membership/ClientMembershipListener.html[ClientMembershipListener]
|
||||
The `BeanPostProcessor` uses a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/management/membership/ClientMembershipListener.html[ClientMembershipListener]
|
||||
that will be notified when the client has successfully connected to the server. Once a connection has been established,
|
||||
the listener releases the latch that the `BeanPostProcessor` will wait on (up to the specified timeout) in the
|
||||
`postProcessAfterInitialization` callback to block the client. Either one of these approaches are sufficient
|
||||
by themselves, but both are demonstrated here to illustrate how this might work and to give you ideas, or other options
|
||||
in practice.
|
||||
`postProcessAfterInitialization` callback to block the client.
|
||||
|
||||
TIP: In typical GemFire deployments, where the cluster includes potentially hundreds of GemFire data nodes (servers),
|
||||
it is more common for clients to connect to one or more GemFire Locators running in the cluster. A Locator passes meta-data
|
||||
@@ -122,11 +115,16 @@ NOTE: For more information on configuring _Spring Data GemFire_, refer to the ht
|
||||
The `@EnableGemFireHttpSession` annotation enables a developer to configure certain aspects of both Spring Session
|
||||
and GemFire out-of-the-box using the following attributes:
|
||||
|
||||
* `maxInactiveIntervalInSeconds` - controls HttpSession idle-timeout expiration (defaults to **30 minutes**).
|
||||
* `regionName` - specifies the name of the GemFire Region used to store `HttpSession` state (defaults is "_ClusteredSpringSessions_").
|
||||
* `clientRegionShort` - specifies GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policies]
|
||||
* `maxInactiveIntervalInSeconds` - controls _HttpSession_ idle-timeout expiration (defaults to **30 minutes**).
|
||||
* `regionName` - specifies the name of the GemFire Region used to store `HttpSession` state (defaults is "*ClusteredSpringSessions*").
|
||||
* `clientRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy]
|
||||
with a GemFire http://gemfire.docs.pivotal.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
|
||||
(default is `PROXY`).
|
||||
(default is `PROXY`). This attribute is only used when configuring client Region.
|
||||
* `poolName` - name of the dedicated GemFire Pool used to connect a client to the cluster of servers. The attribute
|
||||
is only used when the application is a GemFire cache client. Defaults to `gemfirePool`.
|
||||
* `serverRegionShort` - specifies GemFire's http://gemfire.docs.pivotal.io/docs-gemfire/latest/developing/management_all_region_types/chapter_overview.html[data management policy]
|
||||
using a GemFire http://data-docs-samples.cfapps.io/docs-gemfire/latest/javadocs/japi/com/gemstone/gemfire/cache/RegionShortcut.html[RegionShortcut]
|
||||
(default is `PARTITION`). This attribute is only used when configuring server Regions, or when a p2p topology is employed.
|
||||
|
||||
NOTE: It is important to note that the GemFire client Region name must match a server Region by the same name if
|
||||
the client Region is a `PROXY` or `CACHING_PROXY`. Names are not required to match if the client Region used to
|
||||
@@ -134,13 +132,13 @@ store Spring Sessions is `LOCAL`, however, keep in mind that your session state
|
||||
and you lose all benefits of using GemFire to store and manage distributed, replicated session state information
|
||||
in a cluster.
|
||||
|
||||
NOTE: `serverRegionShort` is ignored in a client/server cache configuration and only applies when a peer-to-peer (P2P) topology,
|
||||
and more specifically, a GemFire peer cache is used.
|
||||
NOTE: `serverRegionShort` is ignored in a client/server cache configuration and only applies when
|
||||
a peer-to-peer (P2P) topology, and more specifically, a GemFire peer cache is used.
|
||||
|
||||
=== Server Configuration
|
||||
|
||||
Now, we have only covered one side of the equation. We also need a GemFire Server for our client to talk to and pass
|
||||
session state up to the server to manage.
|
||||
We have only covered one side of the equation. We also need a GemFire Server for our client to talk to and send
|
||||
session state to the server to manage.
|
||||
|
||||
In this sample, we will use the following GemFire Server Java Configuration:
|
||||
|
||||
@@ -149,15 +147,15 @@ In this sample, we will use the following GemFire Server Java Configuration:
|
||||
include::{samples-dir}httpsession-gemfire-clientserver/src/main/java/sample/ServerConfig.java[tags=class]
|
||||
----
|
||||
|
||||
<1> On the server, we also configure Spring Session using the `@EnableGemFireHttpSession` annotation. For one, this
|
||||
ensures that the Region names on both the client and server match (in this sample, we use the default "_ClusteredSpringSessions_").
|
||||
<1> On the server, we also configure Spring Session using the `@EnableGemFireHttpSession` annotation. This ensures
|
||||
the Region names on both the client and server match (in this sample, we use the default "_ClusteredSpringSessions_").
|
||||
We have also set the session timeout to **30 seconds**. Later, we will see how this timeout is used.
|
||||
<2> Next, we configure the GemFire Server using GemFire System properties very much like our P2P samples.
|
||||
<2> Next, we configure the GemFire Server using GemFire System Properties very much like our P2P samples.
|
||||
With the `mcast-port` set to 0 and no `locators` property specified, our server will be standalone. We also allow a
|
||||
JMX client (e.g. _Gfsh_) to connect to our server with the use of the GemFire-specific JMX System properties.
|
||||
<3> Then, we create an instance of the GemFire peer cache using our GemFire System properties.
|
||||
<4> We also setup a GemFire `CacheServer` instance running on **localhost**, listening on port **12480**,
|
||||
to accept our client connection.
|
||||
<3> Then, we create an instance of a GemFire peer `Cache` initialized with our GemFire System Properties.
|
||||
<4> We also setup a GemFire `CacheServer` instance running on **localhost**, listening to port **12480**,
|
||||
ready to accept our client connection.
|
||||
<5> Finally, we declare a `main` method as an entry point for launching and running our GemFire Server
|
||||
from the command-line.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user