diff --git a/spring-geode-docs/src/docs/asciidoc/guides/caching-http-session.adoc b/spring-geode-docs/src/docs/asciidoc/guides/caching-http-session.adoc new file mode 100644 index 00000000..e8b14869 --- /dev/null +++ b/spring-geode-docs/src/docs/asciidoc/guides/caching-http-session.adoc @@ -0,0 +1,268 @@ +[[geode-samples-caching-http-session]] += HTTP Session State Caching with Spring +:images-dir: ../images +:apache-geode-version: 16 +:apache-geode-docs: https://geode.apache.org/docs/guide/{apache-geode-version} +:apache-geode-javadoc: https://geode.apache.org/releases/latest/javadoc +:spring-boot-docs: https://docs.spring.io/spring-boot/docs/current/reference/html +:spring-boot-javadoc: https://docs.spring.io/spring-boot/docs/current/api +:spring-data-geode-docs: https://docs.spring.io/spring-data/geode/docs/current/reference/html +:spring-data-geode-javadoc: https://docs.spring.io/spring-data/geode/docs/current/api +:spring-framework-docs: https://docs.spring.io/spring/docs/current/spring-framework-reference +:spring-framework-javadoc: https://docs.spring.io/spring/docs/current/javadoc-api +:spring-session-docs: https://docs.spring.io/spring-session/docs/current/reference/html5 +:spring-session-javadoc: https://docs.spring.io/spring-session/docs/current/api +:spring-session-website: https://spring.io/projects/spring-session + +This guide walks you through building a simple Spring Boot application using {spring-session-website}[Spring Session] +backed by Apache Geode to manage HTTP Session State. + +It is assumed that the reader is familiar with the Spring _programming model_ as well as the Java Servlet API. +No prior knowledge of Spring Session or Apache Geode is required to utilize HTTP Session State Caching in your +Spring Boot applications. + +Let's begin. + +link:../index.html#geode-samples[Back] + +[[geode-samples-caching-http-session-background]] +== Background + +HTTP Session State Caching is probably 1 of the most useful forms of caching in an enterprise application, especially +given the proliferation of Web applications in the enterprise. + +HTTP Sessions are used primarily to manage conversational state with users of your applications between HTTP requests +given that HTTP is a stateless protocol. This is primarily due to the fact that HTTP connections are not persistent. +When an HTTP client makes a request, the client opens a connection, sends an HTTP request to the server, waits for the +server to process the request, receives a response and then closes the connection. Each time an HTTP request is sent, +the same procedure is followed. + +Of course, there are alternatives to HTTP when making Web Service requests. For instance, if you are using +https://en.wikipedia.org/wiki/WebSocket[WebSockets] in your applications, then you would have persistent connections +and would most likely be using either the https://stomp.github.io/[STOMP] or https://wamp-proto.org/[WAMP] protocols. + +TIP: The core Spring Framework has {spring-framework-docs}/web.html#websocket[first-class support] for _WebSockets_ +over the STOMP protocol. + +TIP: Spring Session additionally {spring-session-docs}/#websocket[supports] Session State Management for _WebSockets_. + +As mentioned above, it is useful to use the HTTP Session to manage conversational state with users of your application +so that they can experience continuity between separate interactions (i.e. HTTP requests). In order to maintain that +continuity and provide a consistent, uninterrupted experience, the HTTP Session must be preserved in a reliable manner. + +1 way to do this is to employ a data management solution in your application architecture that 1) makes the HTTP Session +highly available and 2) makes the HTTP Session resilient to failures in the system architecture. + +Apache Geode is ideal for managing HTTP Session state given that it can distribute data/state across a scaled-out, +highly-available architecture by replicating data in a redundant and organized (partitioned) manner thereby making +the data resilient to failures, such as network or hardware failures. + +This is an ideal arrangement in a cloud environment given that you most likely will be running multiple instances +of your application in order to serve the demand, especially during peak loads. In these cases, you will undoubtedly +face failures and each application will need to be prepared to take over in a moments notice to provide the consistent, +uninterrupted experience to which we alluded to above. These applications instances will need access to +the same HTTP Session. + +An application architecture with HTTP Session State Caching appears as follows: + +image::../images/HTTP-Session-Caching.png[] + +Essentially, anytime an `HttpSession` is requested by your Spring Boot Web Application, the Servlet Container +(e.g. Apache Tomcat) delegates to Spring Session to provide the implementation of `javax.servlet.http.HttpSession`. +After all, `javax.servlet.http.HttpServlet` is an interface that can have many implementations. + +Effectively, Spring Session provides it's own implementation of the `javax.servlet.http.HttpSession` interface through +a Servlet `Filter` that gets registered by Spring Session programmatically when Spring Session is on the application +classpath. + +Spring Session's implementation of the `javax.servlet.http.HttpSession` interface can backed by many different providers +that implement the Spring Session framework's `SessionRepository` interface: + +The Spring Session framework architecture can be depicted as follows: + +image::../images/Spring-Session-Framework-Architecture.png[] + +Again, the `SessionRepository` interface is the central component of the framework for adapting any backend data store +provider for managing the HTTP Session. + +This is effectively how https://github.com/spring-projects/spring-session-data-geode[Spring Session for Apache Geode +& Pivotal GemFire] works. + +[[geode-samples-caching-http-session-example]] +== Example + +For our example, we are going to keep the Web application relatively simple. Essentially, we just want to show you +how easy it is to use Spring Session in your Spring Boot, Web applications, without a lot of ceremony and fuss. + +So, we are going to switch from Servlet Container (e.g. Apache Tomcat) to Spring Session managed HTTP Sessions with a +single-line configuration change. + +First, let's introduce the Spring Web MVC `Controller` in our Spring Boot, Web application. + +[[geode-samples-caching-http-session-example-controller]] +== Controller + +Our Spring Web MVC `Controller` class is implemented as follows: + +.Spring Boot, Web Application Controller +[source,java] +---- +include::{samples-dir}/caching/http-session/src/main/java/example/app/caching/session/http/controller/CounterController.java[tags=class] +---- + +The main Web Service endpoint in our Spring Boot, Web application is the `/session` endpoint, which is accessible from +http//:localhost:8080/session. + +The `/session` endpoint outputs 3 bits of information: + +1) The `javax.servlet.http.HttpSession` class type. +2) Current HTTP Session count. +3) Current HTTP Request count. + +The `HttpSession` class type lets us know the strategy (e.g. Servlet Container vs. Spring Session) is being used to +manage the HTTP Session state. + +The HTTP Request count is simply incremented every time a client HTTP Request is made to the HTTP server (e.g. Servlet +Container) before the HTTP Session expires. If the HTTP Session expires before another client HTTP Request is made, +then the HTTP Session count is incremented and the HTTP Request count resets to 1. + +[[geode-samples-caching-http-session-example-configuration]] +=== Configuration + +.Spring Boot, Web Application Configuration +[source,java] +---- +include::{samples-dir}/caching/http-session/src/main/resources/application.properties[] +---- + +The configuration is quite simple. In this case, we have set the HTTP Session `timeout`, using the +`server.servlet.session.timeout` property to *15 seconds*. This property is to configure the HTTP Session timeout +whether the HTTP Session is being managed by the Servlet Container (e.g. Apache Tomcat) or by Spring Session. + +Additionally, we have configured the data management policy used by Apache Geode to manage the HTTP Session state +in a `LOCAL` only cache (a.k.a. Region). This was done by setting the +`spring.session.data.gemfire.cache.client.region.shortcut` property to `LOCAL`. + +The other configuration properties in Spring Boot's `application.properties` file were not strictly necessary. + +TIP: In most production deployments, you will likely be using a client/server topology, where the HTTP Session +is managed by a cluster of Apache Geode or Pivotal GemFire servers so that the HTTP Session can be shared across +multiple instances of the Spring Boot, Web application, especially in a cloud environment when utilizing Microservices +architecture. However, for example purposes, we tried to keep the sample as simple as possible. + +NOTE: The default data management policy for the client cache (a.k.a. Region) used to manage HTTP Session state is a +`PROXY`, which is the basis for the client/server topology. Therefore, the default configuration assumes you will be +using the client/server topology in most of your arrangements. + +[[geode-samples-caching-http-session-example-classpath]] +=== Classpath + +The only essential components of the application classpath is a compile-time dependency on `spring-boot-starter-web`: + +.`spring-boot-starter-web` compile-time dependency declaration +[source,xml] +---- + + org.springframework.boot + spring-boot-starter-web + +---- + +Along with a runtime dependency on `spring-boot-starter-tomcat` (or another Servlet Container, e.g. +`spring-boot-starter-jetty`): + +.`spring-boot-starter-tomcat` runtime dependency declaration +[source,xml] +---- + + org.springframework.boot + spring-boot-starter-tomcat + +---- + +Spring Boot will detect Apache Tomcat on the application classpath and bootstrap an embedded, Apache Tomcat Servlet +Container using a derived `WebApplicationContext`. + +[[geode-samples-caching-http-session-example-run]] +== Run the Example + +Let's run the example: + +image::../images/HttpSessionCachingApplication.png[] + +When we navigate to the `/session` Web service endpoint: + +image::../images/HttpSessionCachingApplication-ServletContainerSession.png[] + +We see that the Servlet Container's implementing class for the `javax.servlet.http.HttpSession` interface is +`org.apache.catalina.session.StandardSession`. + +If we continue to hit refresh in the Web browser, thereby causing additional client HTTP requests to be made to +the HTTP server, then our HTTP Request count increments. If we wait for 15 seconds, then the HTTP Session will expire, +and we will see the HTTP Session count increment along with the HTTP Request count reset to 1: + +image::../images/HttpSessionCachingApplication-ServletContainerSessionExpiration.png[] + +Now, we can repeat this exercise, but this time, with Spring Session. + +[[geode-samples-caching-http-session-example-run-spring-session]] +=== Run the Example with Spring Session + +First, we must add Spring Session to the application's classpath. We do this simply by adding the +`spring-geode-starter-session` runtime dependency to the classpath of our example application: + +.`spring-geode-starter-session` runtime dependency declaration +[source,xml] +---- + + org.springframework.geode + spring-geode-starter-session + runtime + +---- + +The `spring-geode-starter-session` dependency adds Spring Session to the application's classpath at runtime +and positions Apache Geode as the provider used to manage the HTTP Session state. + +With Apache Geode, we gain all the benefits of using a highly concurrent, highly distributed data management solution +that provides high availability (HA) and resiliency in a cloud environment. + +That's it! This is all we have to do to replace the Servlet's Container's HTTP Session management facilities with a +robust, highly available, highly resilient, clustered solution provided by Spring Session. + +When we run the example again, and access the `/session` Web service endpoint, we will see: + +image::../images/HttpSessionCachingApplication-SpringSession.png[] + +Now we see the implementing class for the `javax.servlet.http.HttpSession` is +`org.springframework.session.web.http.SessionRepositoryFilter$SessionRepositoryRequestWrapper$HttpSessionWrapper`. + +Easy! + +Of course, the ability to scale-out and optimize the data management policies around HTTP Session management +is very provider-specific (e.g. Apache Geode) and highly dependent on the use case and application requirements, +therefore is beyond the scope of this guide. + +[[geode-samples-caching-http-session-summary] +== Summary + +Spring Session is a powerful framework for managing your HTTP Session state. Not only does it allow you to plugin +different backend data management providers (as of this writing): + +* https://github.com/spring-projects/spring-session-data-geode#spring-session-for-apache-geode--pivotal-gemfire[_Apache Geode (or Pivotal GemFire)_] +* {spring-session-website}[_Hazelast_] +* {spring-session-website}[_JDBC_] +* https://spring.io/projects/spring-session-data-mongodb[_MongoDB_] +* {spring-session-website}[_Redis_] + +Spring Session also allows you to manage different types of Sessions depending on the context: + +* {spring-session-docs}/#httpsession[_HttpSession_] +* {spring-session-docs}/#websocket[_WebSocket_] +* {spring-session-docs}#websession[_WebSession_ (Reactive)] + +Therefore, it makes it a simple matter to switch providers, or adopt additional Session management capabilities as your +application requirements change and/or your use cases grow. + +Finally, (HTTP) Session state caching is 1 of the most effective and common ways to utilize caching in your Spring Boot, +Web applications, and make the users experience first-class. diff --git a/spring-geode-docs/src/docs/asciidoc/images/HTTP-Session-Caching.png b/spring-geode-docs/src/docs/asciidoc/images/HTTP-Session-Caching.png new file mode 100644 index 00000000..fdeafab2 Binary files /dev/null and b/spring-geode-docs/src/docs/asciidoc/images/HTTP-Session-Caching.png differ diff --git a/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-ServletContainerSession.png b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-ServletContainerSession.png new file mode 100644 index 00000000..fa6a45e4 Binary files /dev/null and b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-ServletContainerSession.png differ diff --git a/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-ServletContainerSessionExpiration.png b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-ServletContainerSessionExpiration.png new file mode 100644 index 00000000..679c8e60 Binary files /dev/null and b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-ServletContainerSessionExpiration.png differ diff --git a/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-SpringSession.png b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-SpringSession.png new file mode 100644 index 00000000..d1fae055 Binary files /dev/null and b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication-SpringSession.png differ diff --git a/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication.png b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication.png new file mode 100644 index 00000000..d0067551 Binary files /dev/null and b/spring-geode-docs/src/docs/asciidoc/images/HttpSessionCachingApplication.png differ diff --git a/spring-geode-docs/src/docs/asciidoc/images/Spring-Session-Framework-Architecture.png b/spring-geode-docs/src/docs/asciidoc/images/Spring-Session-Framework-Architecture.png new file mode 100644 index 00000000..d3a0379e Binary files /dev/null and b/spring-geode-docs/src/docs/asciidoc/images/Spring-Session-Framework-Architecture.png differ