diff --git a/spring-geode-docs/src/docs/asciidoc/guides/boot-configuration.adoc b/spring-geode-docs/src/docs/asciidoc/guides/boot-configuration.adoc index afb89b59..049bf648 100644 --- a/spring-geode-docs/src/docs/asciidoc/guides/boot-configuration.adoc +++ b/spring-geode-docs/src/docs/asciidoc/guides/boot-configuration.adoc @@ -301,12 +301,12 @@ as the application is scaled out to meet demand. [[geode-samples-boot-configuration-clientserver]] == Switching to Client/Server -We continue with our example by switching from local to a client/server architecture. +We continue with our example by switching from local to a client/server topology. If you are rapidly prototyping your application and want to lift off the ground quickly, then it is useful to start -locally and gradually migrate to a client/server topology. +locally and gradually migrate to a client/server architecture. -To switch to the client/server architecture, all you need to do is remove the `clientRegionShortcut` attribute: +To switch to client/server, all you need to do is remove the `clientRegionShortcut` attribute: .Client/Server Topology Region Configuration [source,java] @@ -315,7 +315,7 @@ To switch to the client/server architecture, all you need to do is remove the `c ---- The default value for the `clientRegionShortcut` attribute is `ClientRegionShortcut.PROXY`. This means no data -is kept locally. All data is sent from the client to 1 or more servers in a cluster. +is stored locally. All data will be sent from the client to 1 or more servers in a cluster. However, if we try to run the application, it will fail: @@ -338,20 +338,21 @@ Caused by: org.apache.geode.cache.client.NoAvailableServersException at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:783) ~[spring-boot-2.0.9.RELEASE.jar:2.0.9.RELEASE] ---- -The client is expecting there to be a cluster of servers to communicate with and to store/access data. +The client is expecting there to be a cluster of servers to communicate with and to store/access data. Clearly, there +are no servers running yet. -There are several ways in which to to start a cluster of GemFire/Geode servers. For example, you may use Spring -to configure and bootstrap the cluster, which is demonstrated <>. +There are several ways in which to start a cluster. For example, you may use Spring to configure and bootstrap +the cluster, which has been demonstrated <>. -For this sample, we are going to use the tools provided with Apache Geode or Pivotal GemFire, e.g. _Gfsh_ +Although, for this example, we are going to use the tools provided with Apache Geode, or Pivotal GemFire, i.e. _Gfsh_ (GemFire/Geode Shell) for reasons that will become apparent later. NOTE: You need to https://geode.apache.org/releases/[download] and {apache-geode-docs}/prereq_and_install.html[install] a full distribution of Apache Geode to make use of the provided tools. After installation, you will need to set -the GEODE (or GEMFIRE) environment variable to the location of your installation. Additionally, add $GEODE/bin -to your system $PATH. +the `GEODE` (or `GEMFIRE`) environment variable to the location of your installation. Additionally, add `$GEODE/bin` +to your system `$PATH`. -Once Apache Geode is successfully installed, you can open a command prompt (terminal) and do: +Once Apache Geode has been successfully installed, you can open a command prompt (terminal) and do: .Running Gfsh [source,txt] @@ -359,7 +360,8 @@ Once Apache Geode is successfully installed, you can open a command prompt (term $ echo $GEMFIRE /Users/jblum/pivdev/apache-geode-1.2.1 -jblum-mbpro-2:lab jblum$ gfsh + +$ gfsh _________________________ __ / _____/ ______/ ______/ /____/ / / / __/ /___ /_____ / _____ / @@ -372,18 +374,18 @@ gfsh> You are set to go. -For convenience, this sample provides a _Gfsh_ shell script to start the cluster: +For your convenience, a _Gfsh_ shell script is provided to start a cluster: link:{samples-dir}/boot/configuration/src/main/resources/geode/bin/start-simple-cluster.gfsh[] Specifically, we are starting 1 Locator and 1 Server, all running with the default ports. -Then you can execute the Gfsh shell script using: +Execute the _Gfsh_ shell script using: -.Run the start-simple-cluster.gfsh +.Run Gfsh shell script [source,txt] ---- -gfsh>run --file=/Users/jblum/pivdev/spring-boot-data-geode/samples/boot/configuration/src/main/resources/geode/bin/start-simple-cluster.gfsh +gfsh>run --file=/path/to/spring-boot-data-geode/samples/boot/configuration/src/main/resources/geode/bin/start-simple-cluster.gfsh 1. Executing - start locator --name=LocatorOne --log-level=config Starting a Geode Locator in /Users/jblum/pivdev/lab/LocatorOne... @@ -415,11 +417,12 @@ JVM Arguments: -Dgemfire.default.locators=10.99.199.24[10334] -Dgemfire.use-clus Class-Path: /Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-core-1.2.1.jar:/Users/jblum/pivdev/apache-geode-1.2.1/lib/geode-dependencies.jar ---- -NOTE: You will need to change the path to spring-boot-data-geode/samples/boot/configuration directory in the -`run --file=...` _Gfsh_ command above based on where you cloned the `spring-boot-data-geode` project on your computer. +NOTE: You will need to change the path to the `spring-boot-data-geode/samples/boot/configuration` directory in the +`run --file=...` _Gfsh_ command above based on where you git cloned the `spring-boot-data-geode` project +to your computer. -Now, our simple cluster with an Apache Geode Locator and (Cache) Server is running. We can verify by -listing and describing members: +Now, our simple cluster with an Apache Geode Locator and (Cache) Server is running. We can verify by listing +and describing the members: .List and Describe Members [source,txt] @@ -451,9 +454,7 @@ Running : true Client Connections : 0 ---- -What happens if we try to run our application now? - -It will fail: +What happens if we try to run the application now? .RegionNotFoundException [source,txt] @@ -511,7 +512,7 @@ The application fails to run because we (deliberately) did not create a correspo In order for a client to send data via a client `PROXY` Region (a Region with no local state) to a server in a cluster, at least one server in the cluster must have a matching Region by name (i.e. "Customers"). -Indeed, we have no Regions in the cluster: +Indeed, there are no Regions in the cluster: .List Regions [source,txt] @@ -527,12 +528,13 @@ Of course, you could have created the matching server-side, "Customers" Region u gfsh>create region --name=Customers --type=PARTITION ---- -But, what if you have hundreds of domain objects, which is not unreasonable in a practical enterprise application? +But, what if you have hundreds of domain objects each requiring a Region for persistence? It is not an unusual or +unreasonable requirement in any practical enterprise application. -While it is not a "convention" in Spring Boot for Apache Geode, Spring Data for Apache Geode (SDG) comes to our rescue. -We simply only need to enable cluster configuration from the client: +While it is not a "convention" in Spring Boot for Apache Geode (SBDG), Spring Data for Apache Geode (SDG) comes to +our rescue. We simply only need to enable cluster configuration from the client: -.Enable Cluster Configuration from the Client +.Enable Cluster Configuration [source,java] ---- @SpringBootApplication @@ -548,14 +550,14 @@ Additionally, we have set the `useHttp` attribute to `true`. This sends the conf to the cluster via GemFire/Geode's Management REST API. This is useful when your GemFire/Geode cluster may be running behind a firewall, such as on public cloud infrastructure. -However, there are other benefits to using HTTP as well. As stated, the client send configuation meta-data to +However, there are other benefits to using HTTP as well. As stated, the client sends configuration meta-data to GemFire/Geode's Management REST interface, which is a facade for the server-side Cluster Configuration Service. If -another member (e.g. server) is added to the cluster as a peer, then this member will get the same configuration. If -the entire cluster goes down, it will have the same configuration when it restarts. +another peer (e.g. server) is added to the cluster as a member, then this member will get the same configuration. If +the entire cluster goes down, it will have the same configuration when it is restarted. -SDG is careful not to stomp on existing Regions since those Regions might have data in them. Declaring the -`@EnableClusterConfiguration` annotation is a useful development-time utility, but it is recommended to explicitly -define and declare your Regions in production environments, either using _Gfsh_ or Spring confg. +SDG is careful not to stomp on existing Regions since those Regions may have data already. Declaring the +`@EnableClusterConfiguration` annotation is a useful development-time feature, but it is recommended that you +explicitly define and declare your Regions in production environments, either using _Gfsh_ or Spring confg. Now, we can run our application again, and this time, it works! @@ -602,7 +604,9 @@ Region | size | 1 | data-policy | PARTITION ---- -We see that the "Customers" Region has a size of 1. We can even query the "Customers" Region: +We see that the "Customers" Region has a size of 1, containing "Jon Doe". + +We can verify this by querying the "Customers" Region: .Query for all Customers [source,java] @@ -617,16 +621,21 @@ Result Jon Doe ---- +That was easy! + [[geode-samples-boot-configuration-clientserver-autoconfig]] == Auto-configuration for Apache Geode, Take Two What may not be apparent in this example up to this point is how the data got from the client to the server. Certainly, -our client did send `Jon Doe` to the server, but our `Customer` class is not `java.io.Serializable`. +our client did send `Jon Doe` to the server, but our `Customer` class is not `java.io.Serializable`. So, how was an +instance of `Customer` streamed from the client to the server then (it is using a Socket)? -Any object that is sent over a network, between two Java processes, or streamed to/from disk, must be serializable. +Any object sent over a network, between two Java processes, or streamed to/from disk, must be serializable. -Additionally, when we started the cluster, we also did not include any application domain classes on the classpath -of any member in the cluster. As further evidence, we an adjust our query slightly: +Furthermore, when we started the cluster, we did not include any application domain classes on the classpath +of any server in the cluster. + +As further evidence, we an adjust our query slightly: .Invalid Query [source,txt] @@ -636,7 +645,7 @@ Message : Could not create an instance of a class example.app.crm.model.Customer Result : false ---- -If we tried to perform a `get`, we would hit a similar error: +If you tried to perform a `get`, you would hit a similar error: .Region.get(key) [source,txt] @@ -653,18 +662,20 @@ Well, Apache Geode and Pivotal GemFire provide 2 proprietary serialization forma and {apache-geode-docs}/developing/data_serialization/gemfire_pdx_serialization.html[PDX], or _Portable Data Exchange_. While _Data Serialization_ is more efficient, PDX is more flexible (i.e. "portable"). PDX enables data to be queried -in serialized form and is the format used to support both Java and native clients (C++, C#). Therefore, PDX is -auto-configured by Spring Boot Data Geode (SBDG), by default. +in serialized form and is the format used to support both Java and native clients (C++, C#) simultaneously. Therefore, +PDX is auto-configured in Spring Boot Data Geode (SBDG) by default. This is convenient since you may not want to implement `java.io.Serializable` for all your application domain model -types that you store in Apache Geode. In other cases, you may not have control over the types referred to by your -application domain model types, such as when using a 3rd party library. +types that you store in Apache Geode. In other cases, you may not even have control over the types referred to by your +application domain model types to make they `Serializable`, such as when using a 3rd party library. So, SBDG auto-configures PDX and uses Spring Data Geode's `MappingPdxSerializer` as the `PdxSerializer` to de/serialize all application domain types. -If we disable PDX _auto-configuration_, we can see the effects of trying to serialize a non-serializable type, `Customer`. -First, let's destroy the server-side "Customers" Region: +If we disable PDX _auto-configuration_, we will see the effects of trying to serialize a non-serializable type, +`Customer`. + +First, let's back up a few steps and destroy the server-side "Customers" Region: .Destroy "Customers" Region [source,txt] @@ -750,8 +761,11 @@ Region | size | 0 | data-policy | PARTITION ---- -So, SBDG can take care of all your serialization needs without you having to configure serialization or implement -`java.io.Serializable` on all your application domain types, including types your application domain types refer to. +So, SBDG takes care of all your serialization needs without you having to configure serialization or implement +`java.io.Serializable` in all your application domain types, including types your application domain types refer to, +which may not be possible. + +If you were not using SBDG, then you would need to enable PDX serialization explicitly. The PDX _auto-configuration_ provided by SBDG is equivalent to: @@ -768,13 +782,14 @@ public class CustomerServiceApplication { } ---- -`@EnablePdx` is responsible for configuring PDX serialization and registering SDG's `MappingPdxSerializer`. +In addition to the `@ClientCacheApplication` annotation, you would need to include the `@EnablePdx` annotation, which is +responsible for configuring PDX serialization and registering SDG's `MappingPdxSerializer`. [[geode-samples-boot-configuration-clientserver-security]] == Securing the Client & Server The last bit of _auto-configuration_ provided by SBDG that we will look at in this guide involves Security, -and specifically Authentication/Authorization (Auth) and Transport Layer Security (TLS) using SSL. +and specifically, Authentication/Authorization (Auth) as well as Transport Layer Security (TLS) using SSL. In today's age, Security is no laughing matter and making sure your applications are secure is a first-class concern. This is why SBDG takes Security very seriously and attempts to make this as simple as possible. You are definitely