From a4f0984f87d23826b11aa2adcd81036516d8edd5 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 6 Jul 2021 13:03:51 -0700 Subject: [PATCH] Polish documentation edits. Resolves gh-109. --- .../src/docs/asciidoc/_includes/actuator.adoc | 419 ++++++----- .../src/docs/asciidoc/_includes/appendix.adoc | 245 ++++--- .../src/docs/asciidoc/_includes/caching.adoc | 685 +++++++++--------- .../_includes/clientcache-applications.adoc | 339 +++++---- .../docs/asciidoc/_includes/cloudfoundry.adoc | 422 ++++++----- .../_includes/configuration-annotations.adoc | 328 +++++---- .../_includes/configuration-auto.adoc | 512 +++++++------ .../_includes/configuration-declarative.adoc | 599 ++++++++------- .../_includes/configuration-externalized.adoc | 117 +-- .../_includes/configuration-properties.adoc | 355 +++++---- .../asciidoc/_includes/continuous-query.adoc | 58 +- .../_includes/data-serialization.adoc | 133 ++-- .../src/docs/asciidoc/_includes/data.adoc | 430 ++++++----- .../src/docs/asciidoc/_includes/docker.adoc | 171 +++-- .../docs/asciidoc/_includes/functions.adoc | 86 ++- .../_includes/gemfire-properties.adoc | 177 +++-- .../asciidoc/_includes/geode-api-ext.adoc | 216 +++--- .../src/docs/asciidoc/_includes/logging.adoc | 262 ++++--- .../docs/asciidoc/_includes/repositories.adoc | 44 +- .../src/docs/asciidoc/_includes/samples.adoc | 44 +- .../src/docs/asciidoc/_includes/security.adoc | 172 ++--- .../src/docs/asciidoc/_includes/session.adoc | 230 +++--- .../docs/asciidoc/_includes/templates.adoc | 301 ++++---- .../src/docs/asciidoc/_includes/testing.adoc | 108 +-- 24 files changed, 3479 insertions(+), 2974 deletions(-) diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/actuator.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/actuator.adoc index 38ec36b0..eaf1fa9a 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/actuator.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/actuator.adoc @@ -2,62 +2,63 @@ == Spring Boot Actuator -Spring Boot for {apache-geode-name} and {pivotal-gemfire-name} (SBDG) adds {spring-boot-docs-html}/production-ready.html[Spring Boot Actuator] -support and dedicated `HealthIndicators` for {apache-geode-name} and {pivotal-gemfire-name}. Equally, the provided -`HealthIndicators` will even work with Pivotal Cloud Cache, which is backed by {pivotal-gemfire-name}, when pushing your -Spring Boot applications to Pivotal CloudFoundry (PCC). +Spring Boot for {apache-geode-name} (SBDG) adds {spring-boot-docs-html}/production-ready.html[Spring Boot Actuator] +support and dedicated `HealthIndicators` for {apache-geode-name}. Equally, the provided `HealthIndicators` even work +with Tanzu Cache (which is backed by {pivotal-gemfire-name}) when you push your Spring Boot applications +using {apache-geode-name} to {VMware Tanzu Application Service (TAS)} platform. -Spring Boot `HealthIndicators` provide details about the runtime operation and behavior of your {apache-geode-name} -based Spring Boot applications. For instance, by querying the right `HealthIndicator` endpoint, you would be able to -get the current hit/miss count for your `Region.get(key)` data access operations. +Spring Boot `HealthIndicators` provide details about the runtime operation and behavior of your {apache-geode-name}-based +Spring Boot applications. For instance, by querying the right `HealthIndicator` endpoint, you can get the current +hit/miss count for your `Region.get(key)` data access operations. -In addition to vital health information, SBDG provides basic, pre-runtime configuration meta-data about the -{apache-geode-name} components that are monitored by Spring Boot Actuator. This makes it easier to see how -the application was configured all in one place, rather than in properties files, Spring config, XML, etc. +In addition to vital health information, SBDG provides basic, pre-runtime configuration metadata about the +{apache-geode-name} components that are monitored by Spring Boot Actuator. This makes it easier to see how +the application was configured all in one place, rather than in properties files, Spring configuration, XML, +and so on. -The provided Spring Boot `HealthIndicators` fall under one of three categories: +The provided Spring Boot `HealthIndicators` fall into three categories: * Base `HealthIndicators` that apply to all {apache-geode-name}, Spring Boot applications, regardless of cache type, -such as Regions, Indexes and DiskStores. -* Peer `Cache` based `HealthIndicators` that are only applicable to peer `Cache` applications, such as -`AsyncEventQueues`, `CacheServers`, `GatewayReceivers` and `GatewaySenders`. -* And finally, `ClientCache` based `HealthIndicators` that are only applicable to `ClientCache` applications, such as -`ContinuousQueries` and connection `Pools`. +such as `Regions`, `Indexes`, and `DiskStores`. +* Peer `Cache`-based `HealthIndicators` that apply only to peer `Cache` applications, such as `AsyncEventQueues`, +`CacheServers`, `GatewayReceivers`, and `GatewaySenders`. +* `ClientCache`-based `HealthIndicators` that apply only to `ClientCache` applications, such as `ContinuousQuery` +and connection `Pools`. The following sections give a brief overview of all the available Spring Boot `HealthIndicators` provided for -{apache-geode-name} out-of-the-box. +{apache-geode-name}. -TIP: Refer to the corresponding Sample link:guides/boot-actuator.html[Guide] and {github-samples-url}/boot/actuator[Code] -to see the Spring Boot Actuator for {apache-geode-name} in action! +TIP: See the corresponding sample link:guides/boot-actuator.html[guide] and {github-samples-url}/boot/actuator[code] +to see Spring Boot Actuator for {apache-geode-name} in action. [[actuator-base-healthindicators]] -=== Base `HealthIndicators` +=== Base HealthIndicators -The following section covers Spring Boot `HealthIndicators` that apply to both peer `Cache` and `ClientCache`, -Spring Boot applications. That is, these `HealthIndicators` are not specific to the cache type. +This section covers Spring Boot `HealthIndicators` that apply to both {apache-geode-name} peer `Cache` and `ClientCache`, +Spring Boot applications. That is, these `HealthIndicators` are not specific to the cache type. -In {apache-geode-name}, the cache instance is either a peer `Cache` instance, which makes your Spring Boot application -part of a {apache-geode-name} cluster, or more commonly, a `ClientCache` instance that talks to an existing cluster. +In {apache-geode-name}, the cache instance is either a peer `Cache` instance (which makes your Spring Boot application +part of a {apache-geode-name} cluster) or, more commonly, a `ClientCache` instance (which talks to an existing cluster). Your Spring Boot application can only be one cache type or the other and can only have a single instance of that cache type. [[actuator-base-healthindicators-cache]] ==== GeodeCacheHealthIndicator -The `GeodeCacheHealthIndicator` provides essential details about the (single) cache instance (Client or Peer) along with -the underlying `DistributedSystem`, the `DistributedMember` and configuration details of the `ResourceManager`. +`GeodeCacheHealthIndicator` provides essential details about the (single) cache instance (client or peer) +and the underlying `DistributedSystem`, the `DistributedMember` and configuration details of the `ResourceManager`. When your Spring Boot application creates an instance of a peer {apache-geode-javadoc}/org/apache/geode/cache/Cache.html[`Cache`], the {apache-geode-javadoc}/org/apache/geode/distributed/DistributedMember.html[`DistributedMember`] object represents -your application as a peer member/node of the {apache-geode-javadoc}/org/apache/geode/distributed/DistributedSystem.html[`DistributedSystem`] -formed from a collection of connected peers (i.e. the cluster), to which your application also has -{apache-geode-javadoc}/org/apache/geode/cache/GemFireCache.html#getDistributedSystem--[access], -indirectly via the cache instance. +your application as a peer member or node of the {apache-geode-javadoc}/org/apache/geode/distributed/DistributedSystem.html[`DistributedSystem`]. +The distributed system (that is, the cluster) is formed from a collection of connected peers, to which your application +also has {apache-geode-javadoc}/org/apache/geode/cache/GemFireCache.html#getDistributedSystem--[access] -- indirectly, +through the cache instance. This is no different for a `ClientCache` even though the client is technically not part of the peer/server cluster. -But, it still creates instances of the `DistributedSystem` and `DistributedMember` objects, respectively. +However, it still creates instances of the `DistributedSystem` and `DistributedMember` objects, respectively. -The following configuration meta-data and health details about each object is covered: +Each object has the following configuration metadata and health details: .Cache Details [width="90%",cols="^3,<10",options="header"] @@ -66,7 +67,7 @@ The following configuration meta-data and health details about each object is co | geode.cache.name | Name of the member in the distributed system. | geode.cache.closed | Determines whether the cache has been closed. -| geode.cache.cancel-in-progress | Cancellation of operations in progress. +| geode.cache.cancel-in-progress | Indicates whether cancellation of operations is in progress. |===================================================================================================================== @@ -75,7 +76,7 @@ The following configuration meta-data and health details about each object is co |===================================================================================================================== | Name | Description -| geode.distributed-member.id | DistributedMember identifier (used in logs internally). +| geode.distributed-member.id | `DistributedMember` identifier (used in logs internally). | geode.distributed-member.name | Name of the member in the distributed system. | geode.distributed-members.groups | Configured groups to which the member belongs. | geode.distributed-members.host | Name of the machine on which the member is running. @@ -88,9 +89,9 @@ The following configuration meta-data and health details about each object is co |===================================================================================================================== | Name | Description -| geode.distributed-system.member-count | Total number of members in the cluster (1 for clients). | geode.distributed-system.connected | Indicates whether the member is currently connected to the cluster. +| geode.distributed-system.member-count | Total number of members in the cluster (1 for clients). | geode.distributed-system.reconnecting | Indicates whether the member is in a reconnecting state, which happens when a network partition occurs and the member gets disconnected from the cluster. | geode.distributed-system.properties-location | Location of the @@ -110,70 +111,69 @@ becoming inoperable. | geode.resource-manager.critical-off-heap-percentage | Percentage of off-heap at which the cache is in danger of becoming inoperable. | geode.resource-manager.eviction-heap-percentage | Percentage of heap at which eviction begins on Regions -configured with a Heap LRU Eviction policy. +configured with a heap LRU eviction policy. | geode.resource-manager.eviction-off-heap-percentage | Percentage of off-heap at which eviction begins on Regions -configured with a Heap LRU Eviction policy. +configured with a heap LRU eviction policy. |===================================================================================================================== - [[actuator-base-healthindicators-regions]] ==== GeodeRegionsHealthIndicator -The `GeodeRegionsHealthIndicator` provides details about all the configured and known `Regions` in the cache. -If the cache is a client, then details will include all LOCAL, PROXY and CACHING_PROXY `Regions`. If the cache -is a peer, then the details will include all LOCAL, PARTITION and REPLICATE `Regions`. +`GeodeRegionsHealthIndicator` provides details about all the configured and known `Regions` in the cache. +If the cache is a client, details include all `LOCAL`, `PROXY`, and `CACHING_PROXY` `Regions`. If the cache is a peer +then details include all `LOCAL`, `PARTITION`, and `REPLICATE` `Region` instances. -While the configuration meta-data details are not exhaustive, essential details along with basic performance metrics -are covered: +The following table describes the essential details and basic performance metrics: .Region Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.cache.regions..cloning-enabled | Whether Region values are cloned on read (e.g. `cloning-enabled` +| geode.cache.regions..cloning-enabled | Whether Region values are cloned on read (for example, `cloning-enabled` is `true` when cache transactions are used to prevent in-place modifications). -| geode.cache.regions..data-policy | Policy used to manage the data in the Region -(e.g. PARTITION, REPLICATE, etc). -| geode.cache.regions..initial-capacity | Initial number of entries that can be held by a Region before -it needs to be resized. -| geode.cache.regions..load-factor | Load factor used to determine when to resize the Region -when it nears capacity. +| geode.cache.regions..data-policy | Policy used to manage data in the Region (`PARTITION`, `REPLICATE`, +and others). +| geode.cache.regions..initial-capacity | Initial number of entries that can be held by a Region before it needs +to be resized. +| geode.cache.regions..load-factor | Load factor used to determine when to resize the Region when it nears +capacity. | geode.cache.regions..key-constraint | Type constraint for Region keys. -| geode.cache.regions..off-heap | Determines whether this Region will store values in off-heap memory -(NOTE: Keys are always kept on Heap). -| geode.cache.regions..pool-name | If this Region is a client Region, then this property determines -the configured connection `Pool` (NOTE: Regions can have and use dedicated `Pools` for their data access operations.) +| geode.cache.regions..off-heap | Determines whether this Region stores values in off-heap memory +(NOTE: Keys are always kept on the JVM heap). +| geode.cache.regions..pool-name | If this Region is a client Region, this property determines +the configured connection `Pool`. (NOTE: Regions can have and use dedicated `Pools` for their data access operations.) | geode.cache.regions..pool-name | Determines the `Scope` of the Region, which plays a factor in -the Regions consistency-level, as it pertains to acknowledgements for writes. +the Region's consistency-level, as it pertains to acknowledgements for writes. | geode.cache.regions..value-constraint | Type constraint for Region values. |===================================================================================================================== -Additionally, when the Region is a peer `Cache` `PARTITION` Region, then the following details are also covered: +The following details also apply when the Region is a peer `Cache` `PARTITION` Region: .Partition Region Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.cache.regions..partition.collocated-with | Indicates this Region is collocated with another -PARTITION Region, which is necessary when performing equi-joins queries (NOTE: distributed joins are not supported). -| geode.cache.regions..partition.local-max-memory | Total amount of Heap memory allowed to be used by +| geode.cache.regions..partition.collocated-with | Indicates whether this Region is collocated with +another `PARTITION` Region, which is necessary when performing equi-joins queries (NOTE: distributed joins +are not supported). +| geode.cache.regions..partition.local-max-memory | Total amount of heap memory allowed to be used by this Region on this node. -| geode.cache.regions..partition.redundant-copies | Number of replicas for this PARTITION Region, -which is useful in High Availability (HA) use cases. -| geode.cache.regions..partition.total-max-memory | Total amount of Heap memory allowed to be used by +| geode.cache.regions..partition.redundant-copies | Number of replicas for this `PARTITION` Region, +which is useful in high availability (HA) use cases. +| geode.cache.regions..partition.total-max-memory | Total amount of heap memory allowed to be used by this Region across all nodes in the cluster hosting this Region. -| geode.cache.regions..partition.total-number-of-buckets | Total number of buckets (shards) that this Region -is divided up into (NOTE: defaults to 113). +| geode.cache.regions..partition.total-number-of-buckets | Total number of buckets (shards) into which this Region +is divided (defaults to 113). |===================================================================================================================== -Finally, when statistics are enabled (e.g. using `@EnableStatistics`, -(see {spring-data-geode-docs-html}/#bootstrap-annotation-config-statistics[here] -for more details), the following details are available: +Finally, when statistics are enabled (for example, when you use `@EnableStatistics` -- +(see {spring-data-geode-docs-html}/#bootstrap-annotation-config-statistics[doc] for more details), +the following metadata is available: .Region Statistic Details [width="90%",cols="^3,<10",options="header"] @@ -182,21 +182,20 @@ for more details), the following details are available: | geode.cache.regions..statistics.hit-count | Number of hits for a Region entry. | geode.cache.regions..statistics.hit-ratio | Ratio of hits to the number of `Region.get(key)` calls. -| geode.cache.regions..statistics.last-accessed-time | For an entry, determines the last time it was accessed +| geode.cache.regions..statistics.last-accessed-time | For an entry, indicates the last time it was accessed with `Region.get(key)`. -| geode.cache.regions..statistics.last-modified-time | For an entry, determines the time a Region's entry value -was last modified. +| geode.cache.regions..statistics.last-modified-time | For an entry, indicates the time when a Region's entry +value was last modified. | geode.cache.regions..statistics.miss-count | Returns the number of times that a `Region.get` was performed and no value was found locally. |===================================================================================================================== - [[actuator-base-healthindicators-indexes]] ==== GeodeIndexesHealthIndicator -The `GeodeIndexesHealthIndicator` provides details about the configured Region `Indexes` used in OQL query -data access operations. +`GeodeIndexesHealthIndicator` provides details about the configured Region `Indexes` used by OQL query data access +operations. The following details are covered: @@ -206,30 +205,29 @@ The following details are covered: | Name | Description | geode.index..from-clause | Region from which data is selected. -| geode.index..indexed-expression | The Region value fields/properties used in the Index expression. -| geode.index..projection-attributes | For all other Indexes, returns "*", but for Map Indexes, returns either "*" -or the specific Map keys that were indexed. +| geode.index..indexed-expression | Region value fields and properties used in the Index expression. +| geode.index..projection-attributes | For `Map` `Indexes`, returns either `*` or the specific Map keys +that were indexed. For all other `Indexes`, returns `*`. | geode.index..region | Region to which the Index is applied. |===================================================================================================================== -Additionally, when statistics are enabled (e.g. using `@EnableStatistics`; -(see {spring-data-geode-docs-html}/#bootstrap-annotation-config-statistics[here] -for more details), the following details are available: +Additionally, when statistics are enabled (for example, when you use `@EnableStatistics` -- +see {spring-data-geode-docs-html}/#bootstrap-annotation-config-statistics["`Configuring Statistics`"] for more details), +the following metadata is available: .Index Statistic Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.index..statistics.number-of-bucket-indexes | Number of bucket Indexes created in a Partitioned Region. +| geode.index..statistics.number-of-bucket-indexes | Number of bucket Indexes created in a PARTITION Region. | geode.index..statistics.number-of-keys | Number of keys in this Index. -| geode.index..statistics.number-of-map-indexed-keys | Number of keys in this Index at the highest-level. +| geode.index..statistics.number-of-map-indexed-keys | Number of keys in this Index at the highest level. | geode.index..statistics.number-of-values | Number of values in this Index. | geode.index..statistics.number-of-updates | Number of times this Index has been updated. | geode.index..statistics.read-lock-count | Number of read locks taken on this Index. -| geode.index..statistics.total-update-time | Total amount of time (ns) spent updating -this Index. +| geode.index..statistics.total-update-time | Total amount of time (ns) spent updating this Index. | geode.index..statistics.total-uses | Total number of times this Index has been accessed by an OQL query. @@ -238,9 +236,9 @@ an OQL query. [[actuator-base-healthindicators-diskstores]] ==== GeodeDiskStoresHealthIndicator -The `GeodeDiskStoresHealthIndicator` provides details about the configured `DiskStores` in the system/application. -Remember, `DiskStores` are used to overflow and persist data to disk, including type meta-data tracked by PDX -when the values in the Region(s) have been serialized with PDX and the Region(s) are persistent. +The `GeodeDiskStoresHealthIndicator` provides details about the configured `DiskStores` in the system or application. +Remember, `DiskStores` are used to overflow and persist data to disk, including type metadata tracked by PDX when the +values in the Regions have been serialized with PDX and the Regions are persistent. Most of the tracked health information pertains to configuration: @@ -251,21 +249,22 @@ Most of the tracked health information pertains to configuration: | geode.disk-store..allow-force-compaction | Indicates whether manual compaction of the DiskStore is allowed. -| geode.disk-store..auto-compact | Indicates if compaction occurs automatically. -| geode.disk-store..compaction-threshold | Percentage at which the oplog will become compactable. +| geode.disk-store..auto-compact | Indicates whether compaction occurs automatically. +| geode.disk-store..compaction-threshold | Percentage at which the oplog becomes compactible. | geode.disk-store..disk-directories | Location of the oplog disk files. | geode.disk-store..disk-directory-sizes | Configured and allowed sizes (MB) for the disk directory -storing the disk files. +that stores the disk files. | geode.disk-store..disk-usage-critical-percentage | Critical threshold of disk usage proportional to the total disk volume. | geode.disk-store..disk-usage-warning-percentage | Warning threshold of disk usage proportional to the total disk volume. | geode.disk-store..max-oplog-size | Maximum size (MB) allowed for a single oplog file. -| geode.disk-store..queue-size | Size of the queue used to batch writes flushed to disk. +| geode.disk-store..queue-size | Size of the queue used to batch writes that are flushed +to disk. | geode.disk-store..time-interval | Time to wait (ms) before writes are flushed to disk from the queue if the size limit has not be reached. -| geode.disk-store..uuid | Universally Unique Identifier for the DiskStore across -Distributed System. +| geode.disk-store..uuid | Universally unique identifier for the DiskStore across a +distributed system. | geode.disk-store..write-buffer-size | Size the of write buffer the DiskStore uses to write data to disk. @@ -274,30 +273,30 @@ to disk. [[actuator-clientcache-healthindicators]] === `ClientCache` `HealthIndicators` -The `ClientCache` based `HealthIndicators` provide additional details specifically for Spring Boot, cache client -applications. These `HealthIndicators` are only available when the Spring Boot application creates a `ClientCache` -instance (i.e. is a cache client), which is the default. +The `ClientCache`-based `HealthIndicators` provide additional details specifically for Spring Boot, cache client +applications. These `HealthIndicators` are available only when the Spring Boot application creates a `ClientCache` +instance (that is, the application is a cache client), which is the default. [[actuator-clientcache-healthindicators-cq]] ==== GeodeContinuousQueriesHealthIndicator -The `GeodeContinuousQueriesHealthIndicator` provides details about registered client Continuous Queries (CQ). -CQs enable client applications to receive automatic notification about events that satisfy some criteria. That criteria -can be easily expressed using the predicate of an OQL query (e.g. "`SELECT * FROM /Customers c WHERE c.age > 21`"). -Anytime data of interests is inserted or updated, and matches the criteria specified in the OQL query predicate, -an event is sent to the registered client. +`GeodeContinuousQueriesHealthIndicator` provides details about registered client Continuous Queries (CQs). CQs let +client applications receive automatic notification about events that satisfy some criteria. That criteria can be easily +expressed by using the predicate of an OQL query (for example, `SELECT * FROM /Customers c WHERE c.age > 21`). +When data is inserted or updated and the data matches the criteria specified in the OQL query predicate +("data of interests"), an event is sent to the registered client. The following details are covered for CQs by name: -.Continuous Query(CQ) Details +.Continuous Query (CQ) Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description | geode.continuous-query..oql-query-string | OQL query constituting the CQ. | geode.continuous-query..closed | Indicates whether the CQ has been closed. -| geode.continuous-query..closing | Indicates whether the CQ is the process of closing. -| geode.continuous-query..durable | Indicates whether the CQ events will be remembered +| geode.continuous-query..closing | Indicates whether the CQ is in the process of closing. +| geode.continuous-query..durable | Indicates whether the CQ events are remembered between client sessions. | geode.continuous-query..running | Indicates whether the CQ is currently running. | geode.continuous-query..stopped | Indicates whether the CQ has been stopped. @@ -306,34 +305,31 @@ between client sessions. In addition, the following CQ query and statistical data is covered: -.Continuous Query(CQ), Query Details +.Continuous Query (CQ), Query Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description | geode.continuous-query..query.number-of-executions | Total number of times the query has been executed. | geode.continuous-query..query.total-execution-time | Total amount of time (ns) spent executing the query. -| geode.continuous-query..statistics.number-of-deletes | |===================================================================================================================== - .Continuous Query(CQ), Statistic Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.continuous-query..statistics.number-of-deletes | Number of Delete events qualified by this CQ. +| geode.continuous-query..statistics.number-of-deletes | Number of delete events qualified by this CQ. | geode.continuous-query..statistics.number-of-events | Total number of events qualified by this CQ. -| geode.continuous-query..statistics.number-of-inserts | Number of Insert events qualified by this CQ. -| geode.continuous-query..statistics.number-of-updates | Number of Update events qualified by this CQ. +| geode.continuous-query..statistics.number-of-inserts | Number of insert events qualified by this CQ. +| geode.continuous-query..statistics.number-of-updates | Number of update events qualified by this CQ. |===================================================================================================================== -In a more general sense, the {apache-geode-name} Continuous Query system is tracked with the following, -additional details on the client: +The {apache-geode-name} Continuous Query system is also tracked with the following additional details on the client: -.Continuous Query(CQ), Statistic Details +.Continuous Query (CQ), Additional Statistic Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description @@ -351,8 +347,8 @@ additional details on the client: [[actuator-clientcache-healthindicators-pools]] ==== GeodePoolsHealthIndicator -The `GeodePoolsHealthIndicator` provide details about all the configured client connection `Pools`. -This `HealthIndicator` primarily provides configuration meta-data for all the configured `Pools`. +`GeodePoolsHealthIndicator` provides details about all the configured client connection `Pools`. This `HealthIndicator` +primarily provides configuration metadata for all the configured `Pools`. The following details are covered: @@ -365,53 +361,53 @@ The following details are covered: | geode.pool..destroyed | Indicates whether the Pool has been destroyed. | geode.pool..free-connection-timeout | Configured amount of time to wait for a free connection from the Pool. -| geode.pool..idle-timeout | The amount of time to wait before closing unused, -idle connections not exceeding the configured number of minimum required connections. -| geode.pool..load-conditioning-interval | Controls how frequently the Pool will check to see -if a connection to a given server should be moved to a different server to improve the load balance. +| geode.pool..idle-timeout | The amount of time to wait before closing unused, idle +connections, not exceeding the configured number of minimum required connections. +| geode.pool..load-conditioning-interval | How frequently the Pool checks to see whether a connection +to a given server should be moved to a different server to improve the load balance. | geode.pool..locators | List of configured Locators. | geode.pool..max-connections | Maximum number of connections obtainable from the Pool. | geode.pool..min-connections | Minimum number of connections contained by the Pool. -| geode.pool..multi-user-authentication | Determines whether the Pool can be used by -multiple authenticated users. +| geode.pool..multi-user-authentication | Determines whether the Pool can be used by multiple +authenticated users. | geode.pool..online-locators | Returns a list of living Locators. -| geode.pool..pending-event-count | Approximate number of pending subscription events -maintained at server for this durable client Pool at the time it (re)connected to the server. +| geode.pool..pending-event-count | Approximate number of pending subscription events maintained +at the server for this durable client Pool at the time it (re)connected to the server. | geode.pool..ping-interval | How often to ping the servers to verify they are still alive. -| geode.pool..pr-single-hop-enabled | Whether the client will acquire a direct connection to -the server containing the data of interests. +| geode.pool..pr-single-hop-enabled | Whether the client acquires a direct connection to +the server. | geode.pool..read-timeout | Number of milliseconds to wait for a response from a server before timing out the operation and trying another server (if any are available). -| geode.pool..retry-attempts | Number of times to retry a request after timeout/exception. -| geode.pool..server-group | Configures the group in which all servers this Pool -connects to must belong. +| geode.pool..retry-attempts | Number of times to retry a request after a timeout +or an exception. +| geode.pool..server-group | All servers must belong to the same group, and this value +sets the name of that group. | geode.pool..servers | List of configured servers. | geode.pool..socket-buffer-size | Socket buffer size for each connection made in this Pool. | geode.pool..statistic-interval | How often to send client statistics to the server. | geode.pool..subscription-ack-interval | Interval in milliseconds to wait before sending acknowledgements to the cache server for events received from the server subscriptions. | geode.pool..subscription-enabled | Enabled server-to-client subscriptions. -| geode.pool..subscription-message-tracking-timeout | Time-to-Live period (ms), for subscription events +| geode.pool..subscription-message-tracking-timeout | Time-to-Live (TTL) period (ms) for subscription events the client has received from the server. -| geode.pool..subscription-redundancy | Redundancy level for this Pools server-to-client -subscriptions, which is used to ensure clients will not miss potentially important events. +| geode.pool..subscription-redundancy | Redundancy level for this Pool's server-to-client +subscriptions, which is used to ensure clients do not miss potentially important events. | geode.pool..thread-local-connections | Thread local connection policy for this Pool. |===================================================================================================================== - [[actuator-peercache-healthindicators]] -=== Peer `Cache` `HealthIndicators` +=== Peer Cache HealthIndicators -The peer `Cache` based `HealthIndicators` provide additional details specifically for Spring Boot, peer cache member -applications. These `HealthIndicators` are only available when the Spring Boot application creates a peer `Cache` +The peer `Cache`-based `HealthIndicators` provide additional details specifically for Spring Boot peer cache member +applications. These `HealthIndicators` are available only when the Spring Boot application creates a peer `Cache` instance. NOTE: The default cache instance created by Spring Boot for {apache-geode-name} is a `ClientCache` instance. -TIP: To control what type of cache instance is created, such as a "peer", then you can explicitly declare either the -`@PeerCacheApplication`, or alternatively, the `@CacheServerApplication`, annotation on your `@SpringBootApplication` -annotated class. +TIP: To control what type of cache instance is created, such as a "`peer`", you can explicitly declare either the +`@PeerCacheApplication` or, alternatively, the `@CacheServerApplication` annotation on your +`@SpringBootApplication`-annotated class. [[actuator-peercache-healthindicators-cacheservers]] ==== GeodeCacheServersHealthIndicator @@ -419,69 +415,68 @@ annotated class. The `GeodeCacheServersHealthIndicator` provides details about the configured {apache-geode-name} `CacheServers`. `CacheServer` instances are required to enable clients to connect to the servers in the cluster. -This `HealthIndicator` captures basic configuration meta-data and runtime behavior/characteristics of -the configured `CacheServers`: +This `HealthIndicator` captures basic configuration metadata and the runtime behavior and characteristics of +the configured `CacheServer` instances: .CacheServer Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.cache.server.count | Total number of configured CacheServer instances +| geode.cache.server.count | Total number of configured `CacheServer` instances on this peer member. -| geode.cache.server..bind-address | IP address of the NIC to which the CacheServer `ServerSocket` +| geode.cache.server..bind-address | IP address of the NIC to which the `CacheServer` `ServerSocket` is bound (useful when the system contains multiple NICs). -| geode.cache.server..hostname-for-clients | Name of the host used by clients to connect to the CacheServer +| geode.cache.server..hostname-for-clients | Name of the host used by clients to connect to the `CacheServer` (useful with DNS). -| geode.cache.server..load-poll-interval | How often (ms) to query the load probe on the CacheServer. -| geode.cache.server..max-connections | Maximum number of connections allowed to this CacheServer. -| geode.cache.server..max-message-count | Maximum number of messages that can be enqueued in -a client queue. -| geode.cache.server..max-threads | Maximum number of Threads allowed in this CacheServer +| geode.cache.server..load-poll-interval | How often (ms) to query the load probe on the `CacheServer`. +| geode.cache.server..max-connections | Maximum number of connections allowed to this `CacheServer`. +| geode.cache.server..max-message-count | Maximum number of messages that can be put in a client queue. +| geode.cache.server..max-threads | Maximum number of threads allowed in this `CacheServer` to service client requests. | geode.cache.server..max-time-between-pings | Maximum time between client pings. -| geode.cache.server..message-time-to-live | Time (seconds) in which the client queue will expire. +| geode.cache.server..message-time-to-live | Time (seconds) in which the client queue expires. | geode.cache.server..port | Network port to which the CacheServer `ServerSocket` is bound -and listening for the client connections. -| geode.cache.server..running | Determines whether this CacheServer is currently running +and on which it listens for client connections. +| geode.cache.server..running | Determines whether this `CacheServer` is currently running and accepting client connections. -| geode.cache.server..socket-buffer-size | Configured buffer size of the Socket connection -used by this CacheServer. -| geode.cache.server..tcp-no-delay | Configures the TCP/IP TCP_NO_DELAY setting on outgoing Sockets. +| geode.cache.server..socket-buffer-size | Configured buffer size of the socket connection used by +this CacheServer. +| geode.cache.server..tcp-no-delay | Configures the TCP/IP `TCP_NO_DELAY` setting on outgoing sockets. |===================================================================================================================== -In addition to the configuration settings shown above, the `CacheServer's` `ServerLoadProbe` tracks additional details -about the runtime characteristics of the `CacheServer`, as follows: +In addition to the configuration settings shown in the preceding table, the `ServerLoadProbe` of the `CacheServer` +tracks additional details about the runtime characteristics of the `CacheServer`: .CacheServer Metrics and Load Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.cache.server..load.connection-load | Load on the server due to client to server +| geode.cache.server..load.connection-load | Load on the server due to client-to-server connections. -| geode.cache.server..load.load-per-connection | Estimate of the how much load each new connection -will add to this server. +| geode.cache.server..load.load-per-connection | Estimate of how much load each new connection +adds to this server. | geode.cache.server..load.subscription-connection-load | Load on the server due to subscription connections. -| geode.cache.server..load.load-per-subscription-connection | Estimate of the how much load each new subscriber -will add to this server. +| geode.cache.server..load.load-per-subscription-connection | Estimate of how much load each new subscriber adds +to this server. | geode.cache.server..metrics.client-count | Number of connected clients. | geode.cache.server..metrics.max-connection-count | Maximum number of connections made to this -CacheServer. -| geode.cache.server..metrics.open-connection-count | Number of open connections to this CacheServer. +`CacheServer`. +| geode.cache.server..metrics.open-connection-count | Number of open connections to this `CacheServer`. | geode.cache.server..metrics.subscription-connection-count | Number of subscription connections to this -CacheServer. +`CacheServer`. |===================================================================================================================== [[actuator-peercache-healthindicators-aeq]] ==== GeodeAsyncEventQueuesHealthIndicator -The `GeodeAsyncEventQueuesHealthIndicator` provides details about the configured `AsyncEventQueues`. AEQs can be -attached to Regions to configure asynchronous, write-behind behavior. +`GeodeAsyncEventQueuesHealthIndicator` provides details about the configured `AsyncEventQueues`. AEQs can be attached to +Regions to configure asynchronous write-behind behavior. -This `HealthIndicator` captures configuration meta-data and runtime characteristics for all AEQs, as follows: +This `HealthIndicator` captures configuration metadata and runtime characteristics for all AEQs: .AsyncEventQueue Details [width="90%",cols="^3,<10",options="header"] @@ -491,16 +486,16 @@ This `HealthIndicator` captures configuration meta-data and runtime characteris | geode.async-event-queue.count | Total number of configured AEQs. | geode.async-event-queue..batch-conflation-enabled | Indicates whether batch events are conflated when sent. | geode.async-event-queue..batch-size | Size of the batch that gets delivered over this AEQ. -| geode.async-event-queue..batch-time-interval | Max time interval that can elapse before a batch is sent. -| geode.async-event-queue..disk-store-name | Name of the disk store used to overflow & persist events. -| geode.async-event-queue..disk-synchronous | Indicates whether disk writes are sync or async. -| geode.async-event-queue..dispatcher-threads | Number of Threads used to dispatch events. +| geode.async-event-queue..batch-time-interval | Maximum time interval that can elapse before a batch is sent. +| geode.async-event-queue..disk-store-name | Name of the disk store used to overflow and persist events. +| geode.async-event-queue..disk-synchronous | Indicates whether disk writes are synchronous or asynchronous. +| geode.async-event-queue..dispatcher-threads | Number of threads used to dispatch events. | geode.async-event-queue..forward-expiration-destroy | Indicates whether expiration destroy operations -are forwarded to AsyncEventListener. +are forwarded to `AsyncEventListener`. | geode.async-event-queue..max-queue-memory | Maximum memory used before data needs to be overflowed to disk. | geode.async-event-queue..order-policy | Order policy followed while dispatching the events to -AsyncEventListeners. +`AsyncEventListeners`. | geode.async-event-queue..parallel | Indicates whether this queue is parallel (higher throughput) or serial. | geode.async-event-queue..persistent | Indicates whether this queue stores events to disk. @@ -509,82 +504,82 @@ or serial. |===================================================================================================================== - [[actuator-peercache-healthindicators-gateway-receivers]] ==== GeodeGatewayReceiversHealthIndicator -The `GeodeGatewayReceiversHealthIndicator` provide details about the configured (WAN) `GatewayReceivers`, which are -capable of receiving events from remote clusters when using {apache-geode-name}'s +`GeodeGatewayReceiversHealthIndicator` provides details about the configured (WAN) `GatewayReceivers`, +which are capable of receiving events from remote clusters when using {apache-geode-name}'s {apache-geode-docs}/topologies_and_comm/multi_site_configuration/chapter_overview.html[multi-site, WAN topology]. -This `HealthIndicator` captures configuration meta-data along with the running state for each `GatewayReceiver`: +This `HealthIndicator` captures configuration metadata along with the running state for each `GatewayReceiver`: .GatewayReceiver Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.gateway-receiver.count | Total number of configured GatewayReceivers. -| geode.gateway-receiver..bind-address | IP address of the NIC to which the GatewayReceiver +| geode.gateway-receiver.count | Total number of configured `GatewayReceiver` instances. +| geode.gateway-receiver..bind-address | IP address of the NIC to which the `GatewayReceiver` `ServerSocket` is bound (useful when the system contains multiple NICs). -| geode.gateway-receiver..end-port | End value of the port range from which the GatewayReceiver's -port will be chosen. -| geode.gateway-receiver..host | IP address or hostname that Locators will tell clients -(i.e. GatewaySenders) that this GatewayReceiver is listening on. +| geode.gateway-receiver..end-port | End value of the port range from which the port of +the `GatewayReceiver` is chosen. +| geode.gateway-receiver..host | IP address or hostname that Locators tell clients (that is, +`GatewaySender` instances) on which this `GatewayReceiver` listens. | geode.gateway-receiver..max-time-between-pings | Maximum amount of time between client pings. -| geode.gateway-receiver..port | Port on which this GatewayReceiver listens for clients -(i.e. GatewaySenders). -| geode.gateway-receiver..running | Indicates whether this GatewayReceiver is running -and accepting client connections (from GatewaySenders). -| geode.gateway-receiver..socket-buffer-size | Configured buffer size for the Socket connections used by -this GatewayReceiver. -| geode.gateway-receiver..start-port | Start value of the port range from which the -GatewayReceiver's port will be chosen. +| geode.gateway-receiver..port | Port on which this `GatewayReceiver` listens for clients +(that is, `GatewaySender` instances). +| geode.gateway-receiver..running | Indicates whether this `GatewayReceiver` is running +and accepting client connections (from `GatewaySender` instances). +| geode.gateway-receiver..socket-buffer-size | Configured buffer size for the socket connections used by +this `GatewayReceiver`. +| geode.gateway-receiver..start-port | Start value of the port range from which the port of +the `GatewayReceiver` is chosen. |===================================================================================================================== [[actuator-peercache-healthindicators-gateway-senders]] ==== GeodeGatewaySendersHealthIndicator -The `GeodeGatewaySendersHealthIndicator` provides details about the configured `GatewaySenders`. `GatewaySenders` are -attached to Regions in order to send Region events to remote clusters in {apache-geode-name}'s +The `GeodeGatewaySendersHealthIndicator` provides details about the configured `GatewaySenders`. `GatewaySender` +instances are attached to Regions in order to send Region events to remote clusters in {apache-geode-name}'s {apache-geode-docs}/topologies_and_comm/multi_site_configuration/chapter_overview.html[multi-site, WAN topology]. -This `HealthIndicator` captures essential configuration meta-data and runtime characteristics for each `GatewaySender`: +This `HealthIndicator` captures essential configuration metadata and runtime characteristics for each `GatewaySender`: .GatewaySender Details [width="90%",cols="^3,<10",options="header"] |===================================================================================================================== | Name | Description -| geode.gateway-sender.count | Total number of configured GatewaySenders. +| geode.gateway-sender.count | Total number of configured `GatewaySender` instances. | geode.gateway-sender..alert-threshold | Alert threshold (ms) for entries in this -GatewaySender's queue. +`GatewaySender` instances queue. | geode.gateway-sender..batch-conflation-enabled | Indicates whether batch events are conflated when sent. | geode.gateway-sender..batch-size | Size of the batches sent. -| geode.gateway-sender..batch-time-interval | Max time interval that can elapse before a batch +| geode.gateway-sender..batch-time-interval | Maximum time interval that can elapse before a batch is sent. -| geode.gateway-sender..disk-store-name | Name of the DiskStore used to overflow and persist -queue events. -| geode.gateway-sender..disk-synchronous | Indicates whether disk writes are sync or async. -| geode.gateway-sender..dispatcher-threads | Number of Threads used to dispatch events. -| geode.gateway-sender..max-queue-memory | Maximum amount of memory (MB) usable for this -GatewaySender's queue. +| geode.gateway-sender..disk-store-name | Name of the `DiskStore` used to overflow and persist +queued events. +| geode.gateway-sender..disk-synchronous | Indicates whether disk writes are synchronous +or asynchronous. +| geode.gateway-sender..dispatcher-threads | Number of threads used to dispatch events. | geode.gateway-sender..max-parallelism-for-replicated-region | +| geode.gateway-sender..max-queue-memory | Maximum amount of memory (MB) usable for this +`GatewaySender` instance's queue. | geode.gateway-sender..order-policy | Order policy followed while dispatching the events -to GatewayReceivers. -| geode.gateway-sender..parallel | Indicates whether this GatewaySender is parallel +to `GatewayReceiver` instances. +| geode.gateway-sender..parallel | Indicates whether this `GatewaySender` is parallel (higher throughput) or serial. -| geode.gateway-sender..paused | Indicates whether this GatewaySender is paused. -| geode.gateway-sender..persistent | Indicates whether this GatewaySender persists queue -events to disk. +| geode.gateway-sender..paused | Indicates whether this `GatewaySender` is paused. +| geode.gateway-sender..persistent | Indicates whether this `GatewaySender` persists +queue events to disk. | geode.gateway-sender..remote-distributed-system-id | Identifier for the remote distributed system. -| geode.gateway-sender..running | Indicates whether this GatewaySender +| geode.gateway-sender..running | Indicates whether this `GatewaySender` is currently running. -| geode.gateway-sender..socket-buffer-size | Configured buffer size for the Socket connections -between this GatewaySender and its receiving GatewayReceiver. -| geode.gateway-sender..socket-read-timeout | Amount of time (ms) that a Socket read between -this sending GatewaySender and its receiving GatewayReceiver will block. +| geode.gateway-sender..socket-buffer-size | Configured buffer size for the socket connections +between this `GatewaySender` and the receiving `GatewayReceiver`. +| geode.gateway-sender..socket-read-timeout | Amount of time (ms) that a socket read between this +sending `GatewaySender` and the receiving `GatewayReceiver` blocks. |===================================================================================================================== diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/appendix.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/appendix.adoc index 78f6e057..2177020d 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/appendix.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/appendix.adoc @@ -2,19 +2,16 @@ == Appendix :geode-name: {apache-geode-name} +The following appendices provide additional help while developing Spring Boot applications backed by {geode-name}: -The following appendices provide additional help while developing Spring Boot applications backed by {geode-name}. - -_Table of Contents_ - -1. <> -2. <> -3. <> -4. <> -5. <> -6. <> -7. <> -8. <> +. <> +. <> +. <> +. <> +. <> +. <> +. <> +. <> :!sectnums: include::configuration-annotations.adoc[leveloffset=+1] @@ -25,11 +22,11 @@ include::configuration-properties.adoc[leveloffset=+1] [[geode-auto-configuration-disable]] === Disabling Auto-configuration -If you would like to disable the _auto-configuration_ of any feature provided by Spring Boot for {geode-name}, then you -can specify the _auto-configuration_ class in the `exclude` attribute of the `@SpringBootApplication` annotation, -as follows: +If you would like to disable the auto-configuration of any feature provided by Spring Boot for {geode-name}, you +can specify the auto-configuration class in the `exclude` attribute of the `@SpringBootApplication` annotation: .Disable Auto-configuration of PDX +==== [source,java] ---- @SpringBootApplication(exclude = PdxSerializationAutoConfiguration.class) @@ -40,11 +37,13 @@ public class MySpringBootApplication { } } ---- +==== -Of course, you can disable more than 1 _auto-configuration_ class at a time by specifying each class -in the `exclude` attribute using array syntax, as follows: +You can disable more than one auto-configuration class at a time by specifying each class in the `exclude` attribute +using array syntax: .Disable Auto-configuration of PDX & SSL +==== [source,java] ---- @SpringBootApplication(exclude = { PdxSerializationAutoConfiguration.class, SslAutoConfiguration.class }) @@ -55,11 +54,12 @@ public class MySpringBootApplication { } } ---- +==== [[geode-auto-configuration-disable-classes]] ==== Complete Set of Auto-configuration Classes -The current set of _auto-configuration_ classes in Spring Boot for {geode-name} include: +The current set of auto-configuration classes in Spring Boot for {geode-name} includes: * `CacheNameAutoConfiguration` * `CachingProviderAutoConfiguration` @@ -78,61 +78,70 @@ The current set of _auto-configuration_ classes in Spring Boot for {geode-name} * `SslAutoConfiguration` [[geode-gemfire-switch]] -=== Switching from {geode-name} to Pivotal GemFire or Pivotal Cloud Cache (PCC) +=== Switching from {geode-name} to {pivotal-gemfire-name} or {pivotal-cloudcache-name} -WARNING: This section is now deprecated! Spring Boot for {geode-name} (SBDG) no longer provides the -`spring-gemfire-starter` and related starter modules. As of SBDG 1.4, SBDG is based on {geode-name} 1.13. Standalone -GemFire bits based on {geode-name} are no longer being released by VMware, Inc. after GemFire 9.10. GemFire 9.10 was -based on {geode-name} 1.12, and as such, SBDG can longer properly support standalone GemFire bits (i.e. <= 9.10). +Spring Boot for {geode-name} (SBDG) stopped providing support for {pivotal-gemfire-name} after SBDG 1.3. SBDG 1.3 was +the last version to support both {geode-name} and {pivotal-gemfire-name}. If you need support for {pivotal-gemfire-name} +in Spring Boot, then you will need to downgrade to SBDG 1.3. -NOTE: What was "_Pivotal GemFire_" has now been rebranded as {pivotal-gemfire-website}[VMware Tanzu GemFire] and what -was Pivotal Cloud Cache (PCC) running on Pivotal CloudFoundry (PCF) has been rebranded as -{pivotal-cloudcache-website}[VMware Tanzu GemFire for VMs] -and {pivotal-cloudfoundry-website}[VMware Tanzu Application Service (TAS)], respectively. +WARNING: This section is now deprecated. Spring Boot for {geode-name} (SBDG) no longer provides the +`spring-gemfire-starter` or related starter modules. As of SBDG 1.4, SBDG is based on {geode-name} 1.13. Standalone +GemFire bits based on {geode-name} are no longer being released by VMware, Inc. after GemFire 9.10. GemFire 9.10 +was based on {geode-name} 1.12, and SBDG can no longer properly support standalone GemFire bits (version <= 9.10). + +NOTE: What was Pivotal GemFire has now been rebranded as {pivotal-gemfire-website}[{pivotal-gemfire-name}] +and what was Pivotal Cloud Cache (PCC) running on Pivotal CloudFoundry (PCF) has been rebranded as +{pivotal-cloudcache-website}[{pivotal-cloudcache-name}] and {pivotal-cloudfoundry-website}[{pivotal-cloudfoundry-name} (TAS)], +respectively. [[geode-cluster-configuration-bootstrapping]] -=== Running an {geode-name} cluster using Spring Boot from your IDE +=== Running an {geode-name} cluster with Spring Boot from your IDE -As described in <>, it is possible to configure and run a small {geode-name} cluster -from inside your IDE using Spring Boot. This is extremely helpful during development since it allows you to manually -spin up, test and debug your applications quickly and easily. +As described in <>, you can configure and run a small {geode-name} cluster from inside +your IDE using Spring Boot. This is extremely helpful during development because it enables you to manually run, test, +and debug your applications quickly and easily. Spring Boot for {geode-name} includes such a class: .Spring Boot application class used to configure and bootstrap an {geode-name} server +==== [source,java] ---- include::{docs-src-dir}/org/springframework/geode/docs/example/app/server/SpringBootApacheGeodeCacheServerApplication.java[tags=class] ---- +==== -This class is a proper Spring Boot application that can be used to configure and bootstrap multiple {geode-name} servers -and joining them together to form a small cluster simply by modifying the runtime configuration of this class ever so -slightly. +This class is a proper Spring Boot application that you can use to configure and bootstrap multiple {geode-name} servers +and join them together to form a small cluster. You only need to modify the runtime configuration of this class +to startup multiple servers. -Initially you will want to start a single, primary server with the embedded Locator and Manager service. +Initially, you will need to start a single (primary) server with an embedded Locator and Manager. -The Locator service enables members in the cluster to locate one another and allows new members to attempt to -join the cluster as a peer. Additionally, the Locator service also allows clients to connect to the servers -in the cluster. When the cache client's Pool is configured to use Locators, then the Pool can intelligently -route data requests directly to the server hosting the data (a.k.a. single-hop access), especially when the data -is partitioned/sharded across servers in the cluster. Locator Pools include support for load balancing connections -and handling automatic fail-over in the event of failed connections, among other things. +The Locator enables members in the cluster to locate one another and lets new members join the cluster as a peer. +The Locator also lets clients connect to the servers in the cluster. When the cache client's connection pool +is configured to use Locators, the pool of connections can intelligently route data requests directly to the server +hosting the data (a.k.a. single-hop access), especially when the data is partitioned/sharded across multiple servers +in the cluster. Locator-based connection pools include support for load balancing connections and handling automatic +fail-over in the event of failed connections, among other things. -The Manager service enables you to connect to this server using _Gfsh_ (the {geode-name} +The Manager lets you connect to this server using Gfsh ({geode-name}'s {apache-geode-docs}/tools_modules/gfsh/chapter_overview.html[command-line shell tool]). -To start our primary server, create a run configuration in your IDE for the `SpringBootApacheGeodeCacheServerApplication` -class with the following, recommended JRE command-line options: +To start your primary server, create a run configuration in your IDE for the `SpringBootApacheGeodeCacheServerApplication` +class using the following, recommended JRE command-line options: .Server 1 run profile configuration +==== [source,txt] ---- -server -ea -Dspring.profiles.active= ---- +==== -Start the class. You should see similar output: +Run the class. You should see output similar to the following: .Server 1 output on startup +==== [source,txt] ---- /Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/bin/java -server -ea -Dspring.profiles.active= "-javaagent:/Applications/IntelliJ IDEA 17 CE.app/Contents/lib/idea_rt.jar=62866:/Applications/IntelliJ IDEA 17 CE.app/Contents/bin" -Dfile.encoding=UTF-8 -classpath /Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/charsets.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/deploy.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/cldrdata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/dnsns.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/jaccess.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/jfxrt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/localedata.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/nashorn.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/sunec.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/sunjce_provider.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/sunpkcs11.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/ext/zipfs.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/javaws.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/jce.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/jfr.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/jfxswt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/jsse.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/management-agent.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/plugin.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/resources.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/jre/lib/rt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/lib/ant-javafx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/lib/dt.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/lib/javafx-mx.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/lib/jconsole.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/lib/packager.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/lib/sa-jdi.jar:/Library/Java/JavaVirtualMachines/jdk1.8.0_152.jdk/Contents/Home/lib/tools.jar:/Users/jblum/pivdev/spring-boot-data-geode/spring-geode-docs/build/classes/main:/Users/jblum/pivdev/spring-boot-data-geode/spring-geode-docs/build/resources/main:/Users/jblum/pivdev/spring-boot-data-geode/spring-geode-autoconfigure/build/classes/main:/Users/jblum/pivdev/spring-boot-data-geode/spring-geode-autoconfigure/build/resources/main:/Users/jblum/pivdev/spring-boot-data-geode/spring-geode/build/classes/main:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-starter/2.0.3.RELEASE/ffaa050dbd36b0441645598f1a7ddaf67fd5e678/spring-boot-starter-2.0.3.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot-autoconfigure/2.0.3.RELEASE/11bc4cc96b08fabad2b3186755818fa0b32d83f/spring-boot-autoconfigure-2.0.3.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework.boot/spring-boot/2.0.3.RELEASE/b874870d915adbc3dd932e19077d3d45c8e54aa0/spring-boot-2.0.3.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/javax.annotation/javax.annotation-api/1.3.2/934c04d3cfef185a8008e7bf34331b79730a9d43/javax.annotation-api-1.3.2.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework.data/spring-data-geode/2.0.8.RELEASE/9e0a3cd2805306d355c77537aea07c281fc581b/spring-data-geode-2.0.8.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-context-support/5.0.7.RELEASE/e8ee4902d9d8bfbb21bc5e8f30cfbb4324adb4f3/spring-context-support-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-context/5.0.7.RELEASE/243a23f8968de8754d8199d669780d683ab177bd/spring-context-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-tx/5.0.7.RELEASE/4ca59b21c61162adb146ad1b40c30b60d8dc42b8/spring-tx-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-web/5.0.7.RELEASE/2e04c6c2922fbfa06b5948be14a5782db168b6ec/spring-web-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework.data/spring-data-commons/2.0.8.RELEASE/5c19af63b5acb0eab39066684e813d5ecd9d03b7/spring-data-commons-2.0.8.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-aop/5.0.7.RELEASE/fdd0b6aa3c9c7a188c3bfbf6dfd8d40e843be9ef/spring-aop-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-beans/5.0.7.RELEASE/c1196cb3e56da83e3c3a02ef323699f4b05feedc/spring-beans-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-expression/5.0.7.RELEASE/ca01fb473f53dd0ee3c85663b26d5dc325602057/spring-expression-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-core/5.0.7.RELEASE/54b731178d81e66eca9623df772ff32718208137/spring-core-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.yaml/snakeyaml/1.19/2d998d3d674b172a588e54ab619854d073f555b5/snakeyaml-1.19.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework/spring-jcl/5.0.7.RELEASE/699016ddf454c2c167d9f84ae5777eccadf54728/spring-jcl-5.0.7.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.geode/geode-lucene/1.2.1/3d22a050bd4eb64bd8c82a74677f45c070f102d5/geode-lucene-1.2.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.geode/geode-core/1.2.1/fe853317e33dd2a1c291f29cee3c4be549f75a69/geode-core-1.2.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.geode/geode-cq/1.2.1/69873d6b956ba13b55c894a13e72106fb552e840/geode-cq-1.2.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.geode/geode-wan/1.2.1/df0dd8516e1af17790185255ff21a54b56d94344/geode-wan-1.2.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/antlr/antlr/2.7.7/83cd2cd674a217ade95a4bb83a8a14f351f48bd0/antlr-2.7.7.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.shiro/shiro-spring/1.3.2/281a6b565f6cf3aebd31ddb004632008d7106f2d/shiro-spring-1.3.2.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.aspectj/aspectjweaver/1.8.13/ad94df2a28d658a40dc27bbaff6a1ce5fbf04e9b/aspectjweaver-1.8.13.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-databind/2.9.6/cfa4f316351a91bfd95cb0644c6a2c95f52db1fc/jackson-databind-2.9.6.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-annotations/2.9.0/7c10d545325e3a6e72e06381afe469fd40eb701/jackson-annotations-2.9.0.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.shiro/shiro-web/1.3.2/725be023e1c65a0fd70c01b8c0c13a2936c23315/shiro-web-1.3.2.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.shiro/shiro-core/1.3.2/b5dede9d890f335998a8ebf479809fe365b927fc/shiro-core-1.3.2.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.slf4j/slf4j-api/1.7.25/da76ca59f6a57ee3102f8f9bd9cee742973efa8a/slf4j-api-1.7.25.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/com.github.stephenc.findbugs/findbugs-annotations/1.3.9-1/a6b11447635d80757d64b355bed3c00786d86801/findbugs-annotations-1.3.9-1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.jgroups/jgroups/3.6.10.Final/fc0ff5a8a9de27ab62939956f705c2909bf86bc2/jgroups-3.6.10.Final.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/commons-io/commons-io/2.5/2852e6e05fbb95076fc091f6d1780f1f8fe35e0f/commons-io-2.5.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/commons-lang/commons-lang/2.6/ce1edb914c94ebc388f086c6827e8bdeec71ac2/commons-lang-2.6.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/it.unimi.dsi/fastutil/7.1.0/9835253257524c1be7ab50c057aa2d418fb72082/fastutil-7.1.0.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/javax.resource/javax.resource-api/1.7/ae40e0864eb1e92c48bf82a2a3399cbbf523fb79/javax.resource-api-1.7.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/net.java.dev.jna/jna/4.5.1/65bd0cacc9c79a21c6ed8e9f588577cd3c2f85b9/jna-4.5.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/net.sf.jopt-simple/jopt-simple/5.0.3/cdd846cfc4e0f7eefafc02c0f5dce32b9303aa2a/jopt-simple-5.0.3.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-core/2.10.0/c90b597163cd28ab6d9687edd53db601b6ea75a1/log4j-core-2.10.0.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.logging.log4j/log4j-api/2.10.0/fec5797a55b786184a537abd39c3fa1449d752d6/log4j-api-2.10.0.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/commons-beanutils/commons-beanutils/1.9.3/c845703de334ddc6b4b3cd26835458cb1cba1f3d/commons-beanutils-1.9.3.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/io.github.lukehutch/fast-classpath-scanner/2.0.11/ae34a7a5e6de8ad1f86e12f6f7ae1869fcfe9987/fast-classpath-scanner-2.0.11.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.geode/geode-common/1.2.1/9db253081d33f424f6e3ce0cde4b306e23e3420b/geode-common-1.2.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.geode/geode-json/1.2.1/bdb4c262e4ce6bb3b22e0f511cfb133a65fa0c04/geode-json-1.2.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.lucene/lucene-analyzers-common/6.4.1/c6f0f593503080204e9d33189cdc59320f55db37/lucene-analyzers-common-6.4.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.lucene/lucene-queryparser/6.4.1/1fc5795a072770a2c47dce11a3c85a80f3437af6/lucene-queryparser-6.4.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.lucene/lucene-queries/6.4.1/6de41d984c16185a244b52c4d069b00f5b2b120f/lucene-queries-6.4.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.apache.lucene/lucene-core/6.4.1/2a18924b9e0ed86b318902cb475a0b9ca4d7be5b/lucene-core-6.4.1.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/com.fasterxml.jackson.core/jackson-core/2.9.6/4e393793c37c77e042ccc7be5a914ae39251b365/jackson-core-2.9.6.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/javax.transaction/javax.transaction-api/1.2/d81aff979d603edd90dcd8db2abc1f4ce6479e3e/javax.transaction-api-1.2.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/commons-logging/commons-logging/1.2/4bfc12adfe4842bf07b657f0369c4cb522955686/commons-logging-1.2.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/commons-collections/commons-collections/3.2.2/8ad72fe39fa8c91eaaf12aadb21e0c3661fe26d5/commons-collections-3.2.2.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/org.springframework.shell/spring-shell/1.2.0.RELEASE/d94047721f292bd5334b5654e8600cef4b845049/spring-shell-1.2.0.RELEASE.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/com.google.guava/guava/17.0/9c6ef172e8de35fd8d4d8783e4821e57cdef7445/guava-17.0.jar:/Users/jblum/.gradle/caches/modules-2/files-2.1/jline/jline/2.12/ce9062c6a125e0f9ad766032573c041ae8ecc986/jline-2.12.jar org.springframework.geode.docs.example.app.server.SpringBootApacheGeodeCacheServerApplication @@ -246,10 +255,12 @@ ack-severe-alert-threshold=0 [info 2018/06/24 21:42:31.588 PDT
tid=0x1] Started SpringBootApacheGeodeCacheServerApplication in 3.77 seconds (JVM running for 5.429) ---- +==== -You can now connect to this server using _Gfsh_: +You can now connect to this server by using Gfsh: .Connect with Gfsh +==== [source,txt] ---- $ echo $GEMFIRE @@ -295,62 +306,66 @@ Server Port : 40404 Running : true Client Connections : 0 ---- +==== -Now, let's start some additional servers to scale-out our cluster. +Now you can run additional servers to scale-out your cluster. -To do so, you simply need to vary the name of the members we will add to our cluster as peers. {geode-name} requires -that the members in a cluster be named and the names of each member in the cluster be unique. +To do so, you must vary the name of the members you add to your cluster as peers. {geode-name} requires members in a +cluster to be named and for the names of each member in the cluster to be unique. Additionally, since we are running multiple instances of our `SpringBootApacheGeodeCacheServerApplication` class, -which also embeds a `CacheServer` instance enabling cache clients to connect, we need to be careful to vary our -ports used by the embedded services. +which also embeds a `CacheServer` component enabling cache clients to connect. Therefore, you must vary the ports +used by the embedded services. -Fortunately, we do not need to run another embedded _Locator_ or _Manager_ service (we only need 1 in this case), -therefore, we can switch profiles from non-clusted to using the Spring "_clustered_" profile, which includes different +Fortunately, you do not need to run another embedded Locator or Manager (you need only one of each in this case). +Therefore, you can switch profiles from non-clustered to using the Spring "clustered" profile, which includes different configuration (the `ClusterConfiguration` class) to connect another server as a peer member in the cluster, -which currently only has 1 member as shown in the `list members` _Gfsh_ command output above. +which currently has only one member, as shown in Gfsh with the `list members` command (shown earlier). -To add another server, set the member name and the `CacheServer` port to a different number with the following -run profile configuration: +To add another server, set the member name and `CacheServer` port to different values with the following +run configuration: .Run profile configuration for server 2 +==== [source,txt] ---- -server -ea -Dspring.profiles.active=clustered -Dspring.data.gemfire.name=ServerTwo -Dspring.data.gemfire.cache.server.port=41414 ---- +==== -Notice that we explicitly activated the "_clustered_" Spring profile, which enables the configuration provided -in the nested `ClusteredConfiguration` class while disabling the `LonerConfiguration` class. +Notice that we explicitly activated the "clustered" Spring profile, which enables the configuration provided in +the nested `ClusteredConfiguration` class while disabling the configuration provided in the `LonerConfiguration` class. -This `ClusteredConfiguration` class is also annotated with `@UseLocators`, which sets the {geode-name} `locators` -property to "_localhost[10334]_". By default, it assumes the Locator process/service is running on "_locahost_", -listening on the default Locator port of "_10334_". You can of course adjust your Locators endpoint if your Locators -are running elsewhere in your network by using the "locators" attribute of the `@UseLocators` annotation. +The `ClusteredConfiguration` class is also annotated with `@UseLocators`, which sets the {geode-name} `locators` +property to "localhost[10334]". By default, it assumes that the Locator runs on localhost, listening on the default +Locator port of 10334. You can adjust your `locators` connection endpoint if your Locators run elsewhere in your network +by using the `locators` attribute of the `@UseLocators` annotation. -TIP: It is common in production environments to run multiple Locators as a separate process. Running multiple Locators -provides redundancy in case a Locator process fails. If all Locator processes in your network fail, don't fret, -your cluster will not go down. It simply means no other members will be able to join the cluster, allowing you to -scale your cluster out, nor will any clients be able to connect. Simply just restart the Locators if this happens. +TIP: In production environments, it is common to run multiple Locators in separate processes. Running multiple Locators +provides redundancy in case a Locator fails. If all Locators in your cluster fail, then your cluster will continue to +run, but no other members will be able to join the cluster, which is important when scaling out the cluster. Clients +also will not be able to connect. Restart the Locators if this happens. -Additionally, we set the `spring.data.gemfire.name` property to "_ServerTwo_" adjusting the name of our member -when it joins the cluster as a peer. +Also, we set the `spring.data.gemfire.name` property to `ServerTwo`, adjusting the name of our member when it joins +the cluster as a peer. -Finally, we set the `spring.data.gemfire.cache.server.port` to "41414" to vary the `CacheServer` port -used by "_ServerTwo_". The default `CacheServer` port is "40404". If we had not set this property before starting -"_ServerTwo_" we would have hit a `java.net.BindException`. +Finally, we set the `spring.data.gemfire.cache.server.port` property to `41414` to vary the `CacheServer` port used by +`ServerTwo`. The default `CacheServer` port is `40404`. If we had not set this property before starting `ServerTwo`, +we would have encounter a `java.net.BindException`. -TIP: Both the `spring.data.gemfire.name` and `spring.data.gemfire.cache.server.port` properties are well-known properties -used by SDG to dynamically configure {geode-name} using a Spring Boot `application.properties` file -or Java System properties. You can find these properties in the Annotation Javadoc in SDG's Annotation-based -Configuration model. For instance, the `spring.data.gemfire.cache.server.port` property is documented -{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#port--[here]. -Most of the SDG annotations include corresponding properties that can be defined in `application.properties` -and is explained in more detail {spring-data-geode-docs-html}/#bootstrap-annotation-config-properties[here]. +TIP: Both `spring.data.gemfire.name` and `spring.data.gemfire.cache.server.port` are well-known properties used by SDG +to dynamically configure {geode-name} with a Spring Boot `application.properties` file or by using Java System +properties. You can find these properties in the annotation Javadoc in SDG's annotation-based configuration model. +For example, see the Javadoc for the +{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#port--[`spring.data.gemfire.cache.server.port` property]. +Most SDG annotations include corresponding properties that can be defined in Spring Boot `application.properties`, +which is explained in detail in the {spring-data-geode-docs-html}/#bootstrap-annotation-config-properties[documentation]. -After starting our second server, "_ServerTwo_", we should see similar output at the command-line, and in _Gfsh_, -when we `list members` and `describe member` again: +After starting our second server, `ServerTwo`, we should see output similar to the following at the command-line +and in Gfsh when we again `list members` and `describe member`: .Gfsh output after starting server 2 +==== [source,txt] ---- gfsh>list members @@ -379,21 +394,25 @@ Server Port : 41414 Running : true Client Connections : 0 ---- +==== -When list members, we see "_ServerTwo_" and when we `describe` "_ServerTwo_", we see that its `CacheServer` port -is appropriately set to "41414". +When we list the members of the cluster, we see `ServerTwo`, and when we `describe` `ServerTwo`, we see that its +`CacheServer` port is appropriately set to `41414`. -If we add 1 more server, "_ServerThree_" using the following run configuration: +We can add one more server, `ServerThree`, by using the following run configuration: -.Add server 3 to our cluster +.Add server three to our cluster +==== [source,txt] ---- -server -ea -Dspring.profiles.active=clustered -Dspring.data.gemfire.name=ServerThree -Dspring.data.gemfire.cache.server.port=42424 ---- +==== -Again, we will see similar output at the command-line and in Gfsh: +We again see similar output at the command-line and in Gfsh: .Gfsh output after starting server 3 +==== [source,txt] ---- gfsh>list members @@ -423,51 +442,51 @@ Server Port : 42424 Running : true Client Connections : 0 ---- +==== -Congratulations! You just started a small {geode-name} cluster, with 3 members, using Spring Boot from inside your IDE. +Congratulations. You have just started a small {geode-name} cluster with 3 members by using Spring Boot from inside +your IDE. -It is pretty simple to build and run a Spring Boot, {geode-name} `ClientCache` application that connects to this cluster. -Simply include and use Spring Boot for {geode-name}. +Now you can build and run a Spring Boot, {geode-name} `ClientCache` application that connects to this cluster. To do so, +include and use Spring Boot for {geode-name}. [[geode-testing-support]] === Testing -https://github.com/spring-projects/spring-test-data-geode[Spring Test for {geode-name}] is a new, soon to be released -and upcoming project to help developers write both _Unit_ and _Integration Tests_ when using {geode-name} in a Spring -context. - -In fact, the entire {github-url}/tree/master/spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure[test suite] +https://github.com/spring-projects/spring-test-data-geode[Spring Test for {geode-name}] (STDG) is a relatively new project +to help you write both unit and integration tests when you use {geode-name} in a Spring context. In fact, the entire +{github-url}/tree/master/spring-geode-autoconfigure/src/test/java/org/springframework/geode/boot/autoconfigure[test suite] in Spring Boot for {geode-name} is based on this project. -All Spring projects integrating with {geode-name} will use this new test framework for all their testing needs, making -this new test framework for {geode-name} a proven and reliable solution for all your {geode-name} application testing -needs when using Spring as well. +All Spring projects that integrate with {geode-name} will use this new test framework for all their testing needs, +making this new test framework for {geode-name} a proven and reliable solution for all your {geode-name} application +testing needs when using Spring as well. -Later on, this reference guide will include and dedicate an entire chapter on testing. +In future versions, this reference guide will include an entire chapter on testing along with samples. In the meantime, +look to the STDG https://github.com/spring-projects/spring-test-data-geode#stdg-in-a-nutshell[README]. [[geode-examples]] === Examples The definitive source of truth on how to best use Spring Boot for {geode-name} is to refer to -the <>. +the <>. -Additionally, you may refer to the https://github.com/jxblum/temperature-service[Temperature Service], Spring Boot -application implementing a Temperature Sensor and Monitoring, Internet of Things (IOT) example. The example uses SBDG -to showcase {geode-name} CQ, Function Implementations/Executions and positions {geode-name} as a _caching provider_ -in Spring's Cache Abstraction. It is a working, sophisticated and complete example, and is highly recommended as a good -starting point for real-world use cases. +See also the https://github.com/jxblum/temperature-service[Temperature Service], Spring Boot application that implements +a temperature sensor and monitoring, Internet of Things (IOT) example. The example uses SBDG to showcase {geode-name} CQ, +function implementations and executions, and positions {geode-name} as a caching provider in Spring's Cache Abstraction. +It is a working, sophisticated, and complete example, and we highly recommend it as a good starting point for real-world +use cases. -You may also refer to the https://github.com/jxblum/contacts-application/tree/master/boot-example[boot-example] -from the _Contact Application_ Reference Implementation (RI) for Spring Data for {geode-name} (SDG) as yet another -example. +See the https://github.com/jxblum/contacts-application/tree/master/boot-example[Boot example] from the contact +application reference implementation (RI) for Spring Data for {geode-name} (SDG) as yet another example. [[references]] === References -1. Spring Framework {spring-framework-docs}[Reference Guide] | {spring-framework-javadoc}[Javadoc] -2. Spring Boot {spring-boot-docs-html}[Reference Guide] | {spring-boot-javadoc}[Javadoc] -3. Spring Data Commons {spring-data-commons-docs-html}[Reference Guide] | {spring-data-commons-javadoc}[Javadoc] -4. Spring Data for {geode-name} {spring-data-geode-docs-html}[Reference Guide] | {spring-data-geode-javadoc}[Javadoc] -5. Spring Session for {geode-name} {spring-session-data-gemfire-docs}[Reference Guide] | {spring-session-data-gemfire-javadoc}[Javadoc] -6. Spring Test for {geode-name} {spring-test-data-gemfire-website}[README] -7. {geode-name} {apache-geode-docs}[User Guide] | {apache-geode-javadoc}[Javadoc] +. Spring Framework {spring-framework-docs}[Reference Guide] | {spring-framework-javadoc}[Javadoc] +. Spring Boot {spring-boot-docs-html}[Reference Guide] | {spring-boot-javadoc}[Javadoc] +. Spring Data Commons {spring-data-commons-docs-html}[Reference Guide] | {spring-data-commons-javadoc}[Javadoc] +. Spring Data for {geode-name} {spring-data-geode-docs-html}[Reference Guide] | {spring-data-geode-javadoc}[Javadoc] +. Spring Session for {geode-name} {spring-session-data-gemfire-docs}[Reference Guide] | {spring-session-data-gemfire-javadoc}[Javadoc] +. Spring Test for {geode-name} {spring-test-data-gemfire-website}[README] +. {geode-name} {apache-geode-docs}[User Guide] | {apache-geode-javadoc}[Javadoc] diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/caching.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/caching.adoc index 142f9682..323289b9 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/caching.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/caching.adoc @@ -4,49 +4,49 @@ :geode-name: {apache-geode-name} -One of the easiest, quickest and least invasive ways to get started using {geode-name} in your Spring Boot applications -is to use {geode-name} as a {spring-framework-docs}/integration.html#cache-store-configuration[_caching provider_] -in {spring-framework-docs}/integration.html#cache[Spring's Cache Abstraction]. SDG +One of the easiest, quickest and least invasive ways to start using {geode-name} in your Spring Boot applications +is to use {geode-name} as a {spring-framework-docs}/integration.html#cache-store-configuration[caching provider] +in {spring-framework-docs}/integration.html#cache[Spring's Cache Abstraction]. SDG {spring-framework-docs}/integration.html#cache-store-configuration-gemfire[enables] -{geode-name} to function as a _caching provider_ in Spring's Cache Abstraction. +{geode-name} to function as a caching provider in Spring's Cache Abstraction. TIP: See the _Spring Data for {geode-name} Reference Guide_ for more details on the {spring-data-geode-docs-html}/#apis:spring-cache-abstraction[support] and {spring-data-geode-docs-html}/#bootstrap-annotation-config-caching[configuration] -of {geode-name} as a _caching provider_ in Spring's Cache Abstraction. +of {geode-name} as a caching provider in Spring's Cache Abstraction. TIP: Make sure you thoroughly understand the {spring-framework-docs}/integration.html#cache-strategies[concepts] behind Spring's Cache Abstraction before you continue. -TIP: You can also refer to the relevant section on {spring-boot-docs-html}/#boot-features-caching[Caching] -in _Spring Boot's Reference Documentation_. _Spring Boot_ even provides _auto-configuration_ support for a few, -simple {spring-boot-docs-html}/#_supported_cache_providers[caching providers] out-of-the-box. +TIP: See also the relevant section on {spring-boot-docs-html}/#boot-features-caching[caching] +in Spring Boot's reference documentation. Spring Boot even provides auto-configuration support for a few of the simple +{spring-boot-docs-html}/#_supported_cache_providers[caching providers]. -Indeed, _caching_ can be a very effective _software design pattern_ to avoid the cost of invoking -a potentially expensive operation when, given the same input, the operation yields the same output every time. +Indeed, caching can be an effective software design pattern to avoid the cost of invoking a potentially expensive +operation when, given the same input, the operation yields the same output, every time. -Some classic examples of caching include, but are not limited to: looking up a customer by name or account number, -looking up a book by ISBN, geocoding a physical address, caching the calculation of a person's credit score +Some classic examples of caching include, but are not limited to, looking up a customer by name or account number, +looking up a book by ISBN, geocoding a physical address, and caching the calculation of a person's credit score when the person applies for a financial loan. If you need the proven power of an enterprise-class caching solution, with strong consistency, high availability, -low latency and multi-site (WAN) capabilities, then you should consider https://geode.apache.org/[{geode-name}], -or alternatively, VMWare, Inc. offers a commercial solution built on {geode-name} called, {gemfire-name}. +low latency, and multi-site (WAN) capabilities, then you should consider https://geode.apache.org/[{geode-name}]. +Alternatively, VMWare, Inc. offers a commercial solution, built on {geode-name}, called {gemfire-name}. Spring's {spring-framework-docs}/integration.html#cache-annotations[declarative, annotation-based caching] makes it -extremely simple to get started with caching, which is as easy as annotating your application components with -the appropriate Spring cache annotations. +simple to get started with caching, which is as easy as annotating your application components with the appropriate +Spring cache annotations. TIP: Spring's declarative, annotation-based caching also {spring-framework-docs}/integration.html#cache-jsr-107[supports] JCache (JSR-107) annotations. -For example, suppose you want to cache the results of determining a person's eligibility when applying for a financial -loan. A person's financial status is unlikely to change in the time that the computer runs the algorithms to compute -a person's eligibility after all the financial information for the person has been collected and submitted for review -and processing. +For example, suppose you want to cache the results of determining a person's eligibility when applying for a loan. A +person's financial status is unlikely to change in the time that the computer runs the algorithms to compute a person's +eligibility after all the financial information for the person has been collected, submitted for review and processed. Our application might consist of a financial loan service to process a person's eligibility over a given period of time: .Spring application service component applicable to caching +==== [source,java] ---- @Service @@ -58,34 +58,36 @@ class FinancialLoanApplicationService { } } ---- +==== Notice the `@Cacheable` annotation declared on the `processEligibility(:Person, :Timespan)` method of our service class. When the `FinancialLoanApplicationService.processEligibility(..)` method is called, Spring's caching infrastructure -first consults the "_EligibilityDecisions_" cache to determine if a decision has already been computed for the given -person within the given span of time. If the person's eligibility in the given time frame has already been determined, -then the existing decision is returned from the cache. Otherwise, the `processEligibility(..)` method will be invoked -and the result of the method will be cached when the method returns, before returning the decision to the caller. +first consults the "EligibilityDecisions" cache to determine if a decision has already been computed for the given +person within the given span of time. If the person's eligibility in the given time frame has already been determined, +the existing decision is returned from the cache. Otherwise, the `processEligibility(..)` method is invoked +and the result of the method is cached when the method returns, before returning the decision to the caller. -Spring Boot for {geode-name} _auto-configures_ {geode-name} as the _caching provider_ when {geode-name} is declared on -the application classpath, and when no other _caching provider_ (e.g. Redis) has been configured. +Spring Boot for {geode-name} auto-configures {geode-name} as the caching provider when {geode-name} is declared on +the application classpath and when no other caching provider (such as Redis) has been configured. -If Spring Boot for {geode-name} detects that another _cache provider_ has already been configured, then {geode-name} -will not function as the _caching provider_ for the application. This allows users to configure another store, e.g. -Redis, as the _caching provider_ and perhaps use {geode-name} as your application's persistent store. +If Spring Boot for {geode-name} detects that another cache provider has already been configured, then {geode-name} +will not function as the caching provider for the application. This lets you configure another store, such as +Redis, as the caching provider and perhaps use {geode-name} as your application's persistent store. The only other requirement to enable caching in a Spring Boot application is for the declared caches (as specified in Spring's or JSR-107's caching annotations) to have been created and already exist, especially before the operation -on which caching has been applied is invoked. This means the backend data store must provide the data structure -serving as the "_cache_". For {geode-name} this means a cache `Region`. +on which caching was applied is invoked. This means the backend data store must provide the data structure that serves +as the cache. For {geode-name}, this means a cache `Region`. -To configure the necessary Regions backing the caches declared in Spring's cache annotations, this is as simple as -using Spring Data for {geode-name}'s -{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableCachingDefinedRegions.html[`@EnableCachingDefinedRegions`] +To configure the necessary Regions that back the caches declared in Spring's cache annotations, use Spring Data +for {geode-name}'s {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableCachingDefinedRegions.html[`@EnableCachingDefinedRegions`] annotation. -The complete Spring Boot application looks like this: +The following listing shows a complete Spring Boot application: +.Spring Boot cache enabled application using {geode-name} +==== [source,java] ---- package example.app; @@ -99,65 +101,66 @@ class FinancialLoanApplication { } } ---- +==== -TIP: The `FinancialLoanApplicationService` is picked up by Spring's classpath component scan since this class +TIP: The `FinancialLoanApplicationService` is picked up by Spring's classpath component scan, since this class is annotated with Spring's `@Service` stereotype annotation. -TIP: You can set the `DataPolicy` of the Region created through the `@EnableCachingDefinedRegions` annotation by -setting the `clientRegionShortcut` to a valid enumerated value. +TIP: You can set the `DataPolicy` of the Region created through the `@EnableCachingDefinedRegions` annotation +by setting the `clientRegionShortcut` attribute to a valid enumerated value. NOTE: Spring Boot for {geode-name} does not recognize nor apply the `spring.cache.cache-names` property. Instead, you should use SDG's `@EnableCachingDefinedRegions` on an appropriate Spring Boot application `@Configuration` class. [[geode-caching-provider-look-aside-near-inline-multi-site]] -=== Look-Aside Caching, Near Caching, Inline Caching and Multi-Site Caching +=== Look-Aside Caching, Near Caching, Inline Caching, and Multi-Site Caching Four different types of caching patterns can be applied with Spring when using {geode-name} for your application caching -needs. +needs: -The 4 primary caching patterns include: +* Look-aside caching +* Near caching +* [Async] Inline caching +* Multi-site caching -* _Look-Aside Caching_ -* _Near Caching_ -* _Inline Caching_ -* _Multi-Site Caching_ +Typically, when most users think of caching, they think of Look-aside caching. This is the default caching +pattern applied by Spring's Cache Abstraction. -Typically, when most users think of caching, they are thinking of _Look-Aside Caching_. This is the default caching -pattern applied by _Spring's Cache Abstraction_. +In a nutshell, Near caching keeps the data closer to where the data is used, thereby improving on performance due to +lower latencies when data is needed (no extra network hops). This also improves application throughput -- that is, +the amount of work completed in a given period of time. -In a nutshell, _Near Caching_ keeps the data closer to where the data is used thereby improving on performance due to -lower latencies when data is needed (i.e. no extra network hops). This also improves application throughput, i.e. the -amount of work completed in a given period of time. +Within Inline caching_, developers have a choice between synchronous (read/write-through) and asynchronous (write-behind) +configurations depending on the application use case and requirements. Synchronous, read/write-through Inline caching +is necessary if consistency is a concern. Asynchronous, write-behind Inline caching is applicable if throughput +and low-latency are a priority. -Within _Inline Caching_, developers have a choice between synchronous (_Read/Write-Through_) and asynchronous -(_Write-Behind_) configurations depending on the application use case and requirements. Synchronous, Read/Write-Through -_Inline Caching_ is necessary if consistency is a concern. Asynchronous, Write-Behind _Inline Caching_ is applicable -if throughput and low-latency are a priority. - -Within _Multi-Site Caching_, there are _Active-Passive_ and _Active-Active_ arrangements. More details on _Multi-Site -Caching_ will be presented in a later release. +Within Multi-site caching, there are active-active and active-passive arrangements. More details on Multi-site caching +will be presented in a later release. [[geode-caching-provider-look-aside-caching]] ==== Look-Aside Caching -TIP: Refer to the corresponding Sample link:guides/caching-look-aside.html[Guide] and {github-samples-url}/caching/look-aside[Code] -to see _Look-Aside Caching_ using {apache-geode-name} in action! +TIP: See the corresponding sample link:guides/caching-look-aside.html[guide] and {github-samples-url}/caching/look-aside[code] +to see Look-aside caching with {apache-geode-name} in action. -The caching pattern demonstrated in the example above is a form of -https://content.pivotal.io/blog/an-introduction-to-look-aside-vs-inline-caching-patterns[_Look-Aside Caching_]. +The caching pattern demonstrated in the preceding example is a form of +https://content.pivotal.io/blog/an-introduction-to-look-aside-vs-inline-caching-patterns[Look-aside caching] +(or "_Cache Aside_"). Essentially, the data of interest is searched for in the cache first, before calling a potentially expensive -operation, e.g. like an operation that makes an IO or network bound request resulting in either a blocking, -or a latency sensitive computation. +operation, such as an operation that makes an IO- or network-bound request that results in either a blocking +or a latency-sensitive computation. -If the data can be found in the cache (stored in-memory to reduce latency) then the data is returned without ever -invoking the expensive operation. If the data cannot be found in the cache, then the operation must be invoked. -However, before returning, the result of the operation is cached for subsequent requests when the the same input -is requested again, by another caller resulting in much improved response times. +If the data can be found in the cache (stored in-memory to reduce latency), the data is returned without ever invoking +the expensive operation. If the data cannot be found in the cache, the operation must be invoked. However, before +returning, the result of the operation is cached for subsequent requests when the same input is requested again by +another caller, resulting in much improved response times. -Again, typical _Look-Aside Caching_ pattern applied in your application code looks similar to the following: +The typical Look-aside caching pattern applied in your Spring application code looks similar to the following: .Look-Aside Caching Pattern Applied +==== [source,java] ---- @Service @@ -178,39 +181,40 @@ class CustomerService { } } ---- +==== -In this design, the `CustomerRepository` is perhaps a JDBC or JPA/Hibernate backed implementation accessing -the external data source (i.e. RDBMS) directly. The `@Cacheable` annotation wraps, or "decorates", -the `findByAccount(:Account):Customer` operation to provide caching facilities. +In this design, the `CustomerRepository` is perhaps a JDBC- or JPA/Hibernate-backed implementation that accesses +the external data source (for example, an RDBMS) directly. The `@Cacheable` annotation wraps, or "decorates", +the `findByAccount(:Account):Customer` operation (method) to provide caching behavior. -NOTE: This operation may be expensive because it might validate the Customer's Account before looking up the Customer, -pull multiple bits of information to retrieve the Customer record, and so on, hence the need for caching. +NOTE: This operation may be expensive because it may validate the customer's account before looking up the customer, +pull multiple bits of information to retrieve the customer record, and so on -- hence the need for caching. [[geode-caching-provider-near-caching]] ==== Near Caching -TIP: Refer to the corresponding Sample link:guides/caching-near.html[Guide] and {github-samples-url}/caching/near[Code] -to see _Near Caching_ using {apache-geode-name} in action! +TIP: See the corresponding sample link:guides/caching-near.html[guide] and {github-samples-url}/caching/near[code] +to see Near caching with {apache-geode-name} in action. -_Near Caching_ is another pattern of caching where the cache is collocated with the application. This is useful when -the caching technology is configured using a client/server arrangement. +Near caching is another pattern of caching where the cache is collocated with the application. This is useful when +the caching technology is configured in a client/server arrangement. We already mentioned that Spring Boot for {geode-name} <> -an _auto-configured_, `ClientCache` instance, out-of-the-box, by default. A `ClientCache` instance is most effective -when the data access operations, including cache access, is distributed to the servers in a cluster accessible by the -client, and in most cases, multiple clients. This allows other cache client applications to access the same data. -However, this also means the application will incur a network hop penalty to evaluate the presence of the data -in the cache. +an auto-configured `ClientCache` instance by default. A `ClientCache` instance is most effective when the data access +operations, including cache access, are distributed to the servers in a cluster that is accessible to the client and, +in most cases, multiple clients. This lets other cache client applications access the same data. However, this also +means the application incurs a network hop penalty to evaluate the presence of the data in the cache. -To help avoid the cost of this network hop in a client/server topology, a local cache can be established, which -maintains a subset of the data in the corresponding server-side cache (i.e. Region). Therefore, the client cache -only contains the data of interests to the application. This "local" cache (i.e. client-side Region) is consulted -before forwarding the lookup request to the server. +To help avoid the cost of this network hop in a client/server topology, a local cache can be established to maintain +a subset of the data in the corresponding server-side cache (that is, a Region). Therefore, the client cache contains +only the data of interest to the application. This "local" cache (that is, a client-side Region) is consulted before +forwarding the lookup request to the server. -To enable _Near Caching_ when using either {geode-name}, simply change the Region's (i.e. the `Cache` in Spring's -Cache Abstraction) data management policy from `PROXY` (the default) to `CACHING_PROXY`, like so: +To enable Near caching when using {geode-name}, change the Region's (that is the `Cache` in Spring's Cache Abstraction) +data management policy from `PROXY` (the default) to `CACHING_PROXY`: -.Enabling Near Caching using {geode-name} +.Enable Near Caching with {geode-name} +==== [source,java] ---- @SpringBootApplication @@ -222,62 +226,64 @@ class FinancialLoanApplication { } } ---- +==== -TIP: The default, client Region data management policy is +TIP: The default client Region data management policy is {apache-geode-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html#PROXY[`ClientRegionShortcut.PROXY`]. -As such, all data access operations are immediately forwarded to the server. +As a result, all data access operations are immediately forwarded to the server. -TIP: Also see the {geode-name} documentation concerning -{apache-geode-docs}/developing/events/how_client_server_distribution_works.html[Client/Server Event Distribution] -and specifically, "_Client Interest Registration on the Server_" when client CACHING_PROXY Regions to manage state -in addition to the corresponding server-side Region. This is necessary to receive updates on entries in the Region -that might have been changed by other clients accessing the same data. +TIP: See also the {geode-name} documentation concerning +{apache-geode-docs}/developing/events/how_client_server_distribution_works.html[client/server event distribution] +and, specifically, "`Client Interest Registration on the Server,`" which applies when you use client `CACHING_PROXY` +Regions to manage state in addition to the corresponding server-side Region. This is necessary to receive updates on +entries in the Region that might have been changed by other clients that have access to the same data. [[geode-caching-provider-inline-caching]] ==== Inline Caching -The next pattern of caching we will discuss in this chapter is _Inline Caching_. +The next pattern of caching covered in this chapter is Inline caching. -There are two different configurations of _Inline Caching_ that developers can apply to their Spring Boot applications -when using the _Inline Caching_ pattern: Synchronous (_Read/Write-Through_) and Asynchronous (_Write-Behind_). +You can apply two different configurations of Inline caching to your Spring Boot applications when you use +the Inline caching pattern: synchronous (read/write-through) and asynchronous (write-behind). -NOTE: Asynchronous (currently) only offers write capabilities, from the cache to the backend, external data source. -There is no option to asynchronously and automatically load the cache when the value becomes available in the backend, -external data source. +NOTE: Asynchronous (currently) offers only write capabilities, from the cache to the external data source. There is no +option to asynchronously and automatically load the cache when the value becomes available in the external data source. [[geode-caching-provider-inline-caching-synchronous]] ===== Synchronous Inline Caching -TIP: Refer to the corresponding Sample link:guides/caching-inline.html[Guide] and {github-samples-url}/caching/inline[Code] -to see _Inline Caching_ using {geode-name} in action! +TIP: See the corresponding sample link:guides/caching-inline.html[guide] and {github-samples-url}/caching/inline[code] +to see Inline caching with {geode-name} in action. -When employing _Inline Caching_ and a cache miss occurs, the application service method may still not be invoked since -a cache can be configured to invoke a loader to load the missing entry from an backend, external data source. +When employing Inline caching and a cache miss occurs, the application service method might not be invoked still, since +a cache can be configured to invoke a loader to load the missing entry from an external data source. -With {geode-name} the cache, or using {geode-name} terminology, the Region, can be configured with a -{apache-geode-javadoc}/org/apache/geode/cache/CacheLoader.html[CacheLoader]. A `CacheLoader` is implemented to retrieve -missing values from an external data source, which could be an RDBMS or any other type of data store (e.g. another NoSQL -data store like Apache Cassandra, MongoDB or Neo4j), when a cache miss occurs. +With {geode-name}, you can configure the cache (or, to use {geode-name} terminology, the Region) with a +{apache-geode-javadoc}/org/apache/geode/cache/CacheLoader.html[`CacheLoader`]. A `CacheLoader` is implemented to +retrieve missing values from an external data source when a cache miss occurs. The external data source could be +an RDBMS or any other type of data store (for example, another NoSQL data store, such as Apache Cassandra, MongoDB, +or Neo4j). -TIP: See the {geode-name} User Guide on -{apache-geode-docs}/developing/outside_data_sources/how_data_loaders_work.html[Data Loaders] for more details. +TIP: See {geode-name}'s User Guide on +{apache-geode-docs}/developing/outside_data_sources/how_data_loaders_work.html[data loaders] for more details. -Likewise, an {geode-name} Region can also be configured with a -{apache-geode-javadoc}/org/apache/geode/cache/CacheWriter.html[CacheWriter]. A `CacheWriter` is responsible for writing -an entry put into the Region to the backend data store, such as an RDBMS. This is referred to as a "_write-through_" -operation because it is synchronous. If the backend data store fails to be updated then the entry will not be stored in -the Region. This helps to ensure consistency between the backend data store and the {geode-name} Region. +Likewise, you can also configure an {geode-name} Region with a +{apache-geode-javadoc}/org/apache/geode/cache/CacheWriter.html[`CacheWriter`]. A `CacheWriter` is responsible for +writing an entry that has been put into the Region to the backend data store, such as an RDBMS. This is referred to +as a write-through operation, because it is synchronous. If the backend data store fails to be updated, the entry is +not stored in the Region. This helps to ensure consistency between the backend data store and the {geode-name} Region. -TIP: It is also possible to implement _Inline-Caching_ using _asynchronous_, _write-behind_ operations by registering -an {apache-geode-javadoc}/org/apache/geode/cache/asyncqueue/AsyncEventListener.html[AsyncEventListener] on an -{apache-geode-javadoc}/org/apache/geode/cache/asyncqueue/AsyncEventQueue.html[AEQ] attached to a server-side Region. -You should consult the {geode-name} User Guide for more -{apache-geode-docs}/developing/events/implementing_write_behind_event_handler.html[details]. We cover _asynchronous_, -_write-behind_ _Inline Caching_ in the next section. +TIP: You can also implement Inline caching using asynchronous write-behind operations by registering +an {apache-geode-javadoc}/org/apache/geode/cache/asyncqueue/AsyncEventListener.html[`AsyncEventListener`] +on an {apache-geode-javadoc}/org/apache/geode/cache/asyncqueue/AsyncEventQueue.html[`AsyncEventQueue`] attached to +a server-side Region. See {geode-name}'s User Guide for more +{apache-geode-docs}/developing/events/implementing_write_behind_event_handler.html[details]. We cover asynchronous +write-behind Inline caching in the next section. -The typical pattern of _Inline Caching_ when applied to application code looks similar to the following: +The typical pattern of Inline caching when applied to application code looks similar to the following: .Inline Caching Pattern Applied +==== [source,java] ---- @Service @@ -297,20 +303,22 @@ class CustomerService { } } ---- +==== -The main difference is, there are no Spring or JSR-107 caching annotations applied to the application's service methods -and the `CustomerRepository` is accessing {geode-name} directly and NOT the RDBMS. +The main difference is that no Spring or JSR-107 caching annotations are applied to the application's service methods, +and the `CustomerRepository` accesses {geode-name} directly and the RDBMS indirectly. [[geode-caching-provider-inline-caching-synchronous-cacheloader-cachewriter]] -====== Implementing CacheLoaders & CacheWriters for Inline Caching +====== Implementing CacheLoaders and CacheWriters for Inline Caching -You can use Spring to configure a `CacheLoader` or `CacheWriter` as a bean in the Spring `ApplicationContext` -and then wire the loader and/or writer to a Region. Given the `CacheLoader` or `CacheWriter` is a Spring bean -like any other bean in the Spring `ApplicationContext`, you can inject any `DataSource` you like into the Loader/Writer. +You can use Spring to configure a `CacheLoader` or `CacheWriter` as a bean in the Spring `ApplicationContext` and then +wire the loader or writer to a Region. Given that the `CacheLoader` or `CacheWriter` is a Spring bean like any other +bean in the Spring `ApplicationContext`, you can inject any `DataSource` you like into the loader or writer. -While you can configure client Regions with `CacheLoaders` and `CacheWriters`, it is typically more common to -configure the corresponding server-side Region; for example: +While you can configure client Regions with `CacheLoaders` and `CacheWriters`, it is more common to configure +the corresponding server-side Region: +==== [source,java] ---- @SpringBootApplication @@ -323,33 +331,32 @@ class FinancialLoanApplicationServer { @Bean("EligibilityDecisions") PartitionedRegionFactoryBean eligibilityDecisionsRegion( - GemFireCache gemfireCache, CacheLoader decisionManagementSystemLoader, - CacheWriter decisionManagementSystemWriter) { + GemFireCache gemfireCache, CacheLoader eligibilityDecisionLoader, + CacheWriter eligibilityDecisionWriter) { PartitionedRegionFactoryBean eligibilityDecisionsRegion = new PartitionedRegionFactoryBean<>(); eligibilityDecisionsRegion.setCache(gemfireCache); - eligibilityDecisionsRegion.setCacheLoader(decisionManagementSystemLoader); - eligibilityDecisionsRegion.setCacheWriter(decisionManagementSystemWriter); + eligibilityDecisionsRegion.setCacheLoader(eligibilityDecisionLoader); + eligibilityDecisionsRegion.setCacheWriter(eligibilityDecisionWriter); eligibilityDecisionsRegion.setPersistent(false); return eligibilityDecisionsRegion; } - @Bean - CacheLoader decisionManagementSystemLoader( + CacheLoader eligibilityDecisionLoader( DataSource dataSource) { - return new DecisionManagementSystemLoader(dataSource); + return new EligibilityDecisionLoader(dataSource); } @Bean - CacheWriter decisionManagementSystemWriter( + CacheWriter eligibilityDecisionWriter( DataSource dataSource) { - return new DecisionManagementSystemWriter(dataSource); + return new EligibilityDecisionWriter(dataSource); } @Bean @@ -358,44 +365,49 @@ class FinancialLoanApplicationServer { } } ---- +==== -Then, you would implement the {apache-geode-javadoc}/org/apache/geode/cache/CacheLoader.html[`CacheLoader`] -and {apache-geode-javadoc}/org/apache/geode/cache/CacheWriter.html[`CacheWriter`] interfaces as appropriate: +Then you could implement the {apache-geode-javadoc}/org/apache/geode/cache/CacheLoader.html[`CacheLoader`] +and {apache-geode-javadoc}/org/apache/geode/cache/CacheWriter.html[`CacheWriter`] interfaces, as appropriate: -.DecisionManagementSystemLoader +.EligibilityDecisionLoader +==== [source,java] ---- -class DecisionManagementSystemLoader implements CacheLoader { +class EligibilityDecisionLoader implements CacheLoader { private final DataSource dataSource; - DecisionManagementSystemLoader(DataSource dataSource) { + EligibilityDecisionLoader(DataSource dataSource) { this.dataSource = dataSource; } public EligibilityDecision load(LoadHelper helper) { - Object key = helper.getKey(); + Object key = helper.getKey(); - // Use the configured DataSource to load the value identified by the key from a backend, external data store. - } + // Use the configured DataSource to load the EligibilityDecision identified by the key + // from a backend, external data store. + } } ---- +==== TIP: SBDG provides the `org.springframework.geode.cache.support.CacheLoaderSupport` `@FunctionalInterface` to conveniently implement application `CacheLoaders`. -If the configured `CacheLoader` still cannot resolve the value, then the cache lookup operation results in a miss -and the application service method will then be invoked to compute the value. +If the configured `CacheLoader` still cannot resolve the value, the cache lookup operation results in a cache miss +and the application service method is then invoked to compute the value: -.DecisionManagementSystemWriter +.EligibilityDecisionWriter +==== [source,java] ---- -class DecisionManagementSystemWriter implements CacheWriter { +class EligibilityDecisionWriter implements CacheWriter { private final DataSource dataSource; - DecisionManagementSystemWriter(DataSource dataSource) { + EligibilityDecisionWriter(DataSource dataSource) { this.dataSource = dataSource; } @@ -414,49 +426,47 @@ class DecisionManagementSystemWriter implements CacheWriter` interface. +SBDG provides the `InlineCachingRegionConfigurer` interface. Given a `Predicate` to express the criteria used to match the target Region by name and a Spring Data `CrudRepository`, -the `InlineCachingRegionConfigurer` will configure and adapt the Spring Data `CrudRepository` as a `CacheLoader` and -`CacheWriter` registered on the Region (e.g. "Customers") to enable _Inline Caching_ functionality. +the `InlineCachingRegionConfigurer` configures and adapts the Spring Data `CrudRepository` as a `CacheLoader` +and `CacheWriter` registered on the Region (for example, "Customers") to enable Inline caching functionality. -You simply only need to declare `InlineCachingRegionConfigurer` as a bean in the Spring `ApplicationContext` and make +You need only declare `InlineCachingRegionConfigurer` as a bean in the Spring `ApplicationContext` and make the association between the Region (by name) and the appropriate Spring Data `CrudRepository`. -In this example, we used JPA and Spring Data JPA to store/retrieve the data in the cache (Region) to/from a backend -database. But, you can inject any Spring Data Repository for any data store (e.g. Redis, MongoDB, etc) that supports -the Spring Data Repository abstraction. +In this example, we used JPA and Spring Data JPA to store and retrieve data stored in the cache (Region) to and from +a backend database. However, you can inject any Spring Data Repository for any data store (Redis, MongoDB, and others) +that supports the Spring Data Repository abstraction. -TIP: If you only want to support one way data access operations when using _Inline Caching_, then you can use either +TIP: If you want only to support one-way data access operations when you use Inline caching, you can use either the `RepositoryCacheLoaderRegionConfigurer` for reads or the `RepositoryCacheWriterRegionConfigurer` for writes, instead of the `InlineCachingRegionConfigurer`, which supports both reads and writes. -TIP: To see a similar implementation of _Inline Caching_ using a Database (In-Memory, HSQLDB Database) in action, have a -look at this https://github.com/spring-projects/spring-boot-data-geode/blob/master/spring-geode/src/test/java/org/springframework/geode/cache/inline/database/InlineCachingWithDatabaseIntegrationTests.java[test class] -from the SBDG test suite. A dedicated sample will be provided in a future release. +TIP: To see a similar implementation of Inline caching with a database (an in-memory HSQLDB database) in action, see the +https://github.com/spring-projects/spring-boot-data-geode/blob/master/spring-geode/src/test/java/org/springframework/geode/cache/inline/database/InlineCachingWithDatabaseIntegrationTests.java[`InlineCachingWithDatabaseIntegrationTests`] +test class from the SBDG test suite. A dedicated sample will be provided in a future release. [[geode-caching-provider-inline-caching-asynchronous]] ===== Asynchronous Inline Caching -TIP: Refer to the corresponding Sample link:guides/caching-inline-async.html[Guide] -and {github-samples-url}/caching/inline-async[Code] to see _Asynchronous Inline Caching_ using {geode-name} in action! +TIP: See the corresponding sample link:guides/caching-inline-async.html[guide] +and {github-samples-url}/caching/inline-async[code] to see asynchronous Inline caching with {geode-name} in action. -If consistency between the cache and your external, backend data source is not a concern, and you only need to write -from the cache to the backend data store periodically, then you can employ asynchronous (_Write-Behind_) _Inline Caching_. +If consistency between the cache and your external data source is not a concern, and you need only write from the cache +to the backend data store periodically, you can employ asynchronous (write-behind) Inline caching. -As the term "_Write-Behind_" implies, a write to the backend data store is asynchronous and not strictly tied to the -cache operation. As a result, the backend data store will be in an "_eventually consistent_" state since the cache is +As the term, "write-behind", implies, a write to the backend data store is asynchronous and not strictly tied to the +cache operation. As a result, the backend data store is in an "eventually consistent" state, since the cache is primarily used by the application at runtime to access and manage data. In this case, the backend data store is used -to persist the state of the cache, and that of the application, at periodic intervals. +to persist the state of the cache (and that of the application) at periodic intervals. -Of course, if multiple applications are updating the backend data store concurrently, you could combine a `CacheLoader` -to synchronously "_Read-Through_" to the backend data store and keep the cache up-to-date as well as asynchronously -_Write-Behind_ from the cache to the backend data store when the cache is updated to eventually inform other interested -applications of data changes. In this capacity, the backend data store is still the primary _System of Record_ (SOR). +If multiple applications are updating the backend data store concurrently, you could combine a `CacheLoader` +to synchronously read through to the backend data store and keep the cache up-to-date as well as asynchronously +write behind from the cache to the backend data store when the cache is updated to eventually inform other interested +applications of data changes. In this capacity, the backend data store is still the primary System of Record (SoR). -If data processing is not time sensitive, you can gain a performance advantage from periodic, quantity and/or time-based +If data processing is not time sensitive, you can gain a performance advantage from quantity-based or time-based batch updates. [[geode-caching-provider-inline-caching-asynchronous-asynceventlistener]] ====== Implementing an AsyncEventListener for Inline Caching -If you were to configure asynchronous (_Write-Behind_) _Inline Caching_ by hand, then you would need to do all of -the following yourself: +If you were to configure asynchronous, write-behind Inline caching by hand, you would need to do the following yourself: -1. Implement an `AsyncEventListener` to write to an external, backend data source on cache events -2. Configure, create and register the listener with an `AsyncEventQueue` (AEQ) -3. Create a Region serving as the source of cache events and attach the AEQ +. Implement an `AsyncEventListener` to write to an external data source on cache events. +. Configure and register the listener with an `AsyncEventQueue` (AEQ). +. Create a Region to serve as the source of cache events and attach the AEQ to the Region. -The advantage of this approach is you have access to and control over low-level configuration details. The disadvantage, -of course, is with more moving parts, it is easier to mess things up. +The advantage of this approach is that you have access to and control over low-level configuration details. +The disadvantage is that with more moving parts, it is easier to make errors. -Following on from our synchronous (_Read/Write-Through_) _Inline Caching_ examples from the prior sections above, +Following on from our synchronous, read/write-through, Inline caching examples from the prior sections, our `AsyncEventListener` implementation might appear as follows: -.Example `AsyncEventListener` for Async _Inline Caching_ +.Example `AsyncEventListener` for Asynchronous, Write-Behind Inline Caching +==== [source,java] ---- @Component @@ -548,21 +559,23 @@ class ExampleAsyncEventListener implements AsyncEventListener { @Override public boolean processEvents(List events) { - // Iterate over the ordered AsyncEvents and use the DataSource + // Iterate over the ordered AsyncEvents and use the configured DataSource // to write to the external, backend DataSource } } ---- +==== -NOTE: Instead of injecting a `DataSource` into your `AsyncEventListener` directly, you could use JDBC, -Spring's `JdbcTemplate`, JPA/Hibernate or another data access API/Framework. Further below, we will show how SBDG -simplifies the `AsyncEventListener` implementation by using Spring Data _Repositories_. +NOTE: Instead of directly injecting a `DataSource` into your `AsyncEventListener`, you could use JDBC, Spring's +`JdbcTemplate`, JPA and Hibernate, or another data access API or framework. Later in this chapter, we show how SBDG +simplifies the `AsyncEventListener` implementation by using Spring Data Repositories. -Then, we need to register this listener with a `AsyncEventQueue` (AEQ) (#2) and attach it to the target Region -that will be the source of the cache events we want to persist asynchronously (#3): +Then we need to register this listener with an `AsyncEventQueue` (step 2 from the procedure shown earlier) and attach it +to the target Region that will be the source of the cache events we want to persist asynchronously (step 3): -.Configure and Create an `AsyncEventQueue` +.Create and Configure an `AsyncEventQueue` +==== [source,java] ---- @Configuration @@ -571,7 +584,7 @@ class GeodeConfiguration { @Bean DataSource exampleDataSource() { - // Configure and construct a data store specific DataSource + // Construct and configure a data store specific DataSource } @Bean @@ -606,25 +619,28 @@ class GeodeConfiguration { } } ---- +==== -While this approach affords you the developer a lot of control over the (low-level) configuration, in addition to +While this approach affords you a lot of control over the low-level configuration, in addition to your `AsyncEventListener` implementation, this is a lot of boilerplate code. -TIP: See the {spring-data-geode-javadoc}/org/springframework/data/gemfire/wan/AsyncEventQueueFactoryBean.html[Javadoc] -on SDG's `AsyncEventQueueFactoryBean` for more details on the configuration of the AEQ. +TIP: See the Javadoc for SDG's {spring-data-geode-javadoc}/org/springframework/data/gemfire/wan/AsyncEventQueueFactoryBean.html[`AsyncEventQueueFactoryBean`] +for more detail on the configuration of the AEQ. TIP: See {geode-name}'s {apache-geode-docs}/developing/events/implementing_write_behind_event_handler.html[User Guide] for more details on AEQs and listeners. -Fortunately, with SBDG, there is a better way! +Fortunately, with SBDG, there is a better way. [[geode-caching-provider-inline-caching-asynchronous-using-spring-data-repositories]] -====== Asynchronous Inline Caching using Spring Data Repositories +====== Asynchronous Inline Caching with Spring Data Repositories -The implementation and configuration of the `AsyncEventListener` as well as the AEQ shown above can be simplified -as follows: +The implementation and configuration of the `AsyncEventListener` as well as the AEQ shown in +the <> +can be simplified as follows: -.Using SBDG to configure Asynchronous (Write-Behind) Inline Caching +.Using SBDG to configure Asynchronous, Write-Behind Inline Caching +==== [source,java] ---- @SpringBootApplication @@ -645,61 +661,62 @@ class ExampleSpringBootApacheGeodeAsyncInlineCachingApplication { } } ---- +==== The `AsyncInlineCachingRegionConfigurer.create(..)` method is overloaded to accept a `Predicate` in place of the `String` -in order to express more powerful matching logic, programmatically, identifying the target Region (by name) on which to -configure asynchronous _Inline Caching_ functionality. +to programmatically express more powerful matching logic and identify the target Region (by name) on which to configure +asynchronous Inline caching functionality. -The `AsyncInlineCachingRegionConfigurer` uses the https://en.wikipedia.org/wiki/Builder_pattern[_Builder Software Design Pattern_] +The `AsyncInlineCachingRegionConfigurer` uses the https://en.wikipedia.org/wiki/Builder_pattern[Builder software design pattern] and `withQueue*(..)` builder methods to configure the underlying `AsyncEventQueue` (AEQ) when the queue's configuration deviates from the defaults, as specified by {geode-name}. -Under-the-hood, the `AsyncInlineCachingRegionConfigurer` constructs a new instance of the `RepositoryAsyncEventListener` +Under the hood, the `AsyncInlineCachingRegionConfigurer` constructs a new instance of the `RepositoryAsyncEventListener` class initialized with the given Spring Data `CrudRepository`. The `RegionConfigurer` then registers the listener with the AEQ and attaches it to the target `Region`. -With the power of Spring Boot _auto-configuration_ and SBDG, the configuration is much more concise and intuitive. +With the power of Spring Boot auto-configuration and SBDG, the configuration is much more concise and intuitive. [[geode-caching-provider-inline-caching-asynchronous-listener]] ====== About `RepositoryAsyncEventListener` -The SBDG `RepositoryAsyncEventListener` class is the magic sauce behind the integration of the cache with an external, -backend data source. +The SBDG `RepositoryAsyncEventListener` class is the magic ingredient behind the integration of the cache with +an external data source. -The listener is a specialized https://en.wikipedia.org/wiki/Adapter_pattern[Adpater] that processes `AsyncEvents` by +The listener is a specialized https://en.wikipedia.org/wiki/Adapter_pattern[adapter] that processes `AsyncEvents` by invoking an appropriate `CrudRepository` method based on the cache operation. The listener requires an instance of -`CrudRepository`. As such, the listener supports any external, backend data source supported by Spring Data's -_Repository_ abstraction. +`CrudRepository`. The listener supports any external data source supported by Spring Data's Repository abstraction. -Of course, backend data store, data access operations (e.g. INSERT, UPDATE, DELETE, etc) triggered by cache events +Backend data store, data access operations (such as INSERT, UPDATE, DELETE, and so on) triggered by cache events are performed asynchronously from the cache operation. This means the state of the cache and backend data store -will be "_eventually consistent_". +will be "eventually consistent". -ERROR HANDLING - -Given the complex nature of "_eventually consistent_" systems and asynchronous concurrent processing, the -`RepositoryAsyncEventListener` allows users to register a custom `AsyncEventErrorHandler` to handle the errors -that occur during processing of `AsyncEvents`, perhaps due to a faulty backend data store data access operation -(e.g. `OptimisticLockingFailureException`), in an application relevant way. +Given the complex nature of "eventually consistent" systems and asynchronous concurrent processing, the +`RepositoryAsyncEventListener` lets you register a custom `AsyncEventErrorHandler` to handle the errors that occur +during processing of `AsyncEvents`, perhaps due to a faulty backend data store data access operation (such as +`OptimisticLockingFailureException`), in an application-relevant way. The `AsyncEventErrorHandler` interface is a `java.util.function.Function` implementation and `@FunctionalInterface` defined as: .AsyncEventErrorHandler interface definition +==== [source,java] ---- @FunctionalInterface interface AsyncEventErrorHandler implements Function { } ---- +==== The `AsyncEventError` class encapsulates `AsyncEvent` along with the `Throwable` that was thrown while processing -the event. +the `AsyncEvent`. -Since the `AsyncEventErrorHandler` interface implements `Function`, then you would override the `apply(:AsyncEventError)` -method to handle the error with application-specific actions. The handler returns a `Boolean` to indicate whether it was -able to handle the error or not. +Since the `AsyncEventErrorHandler` interface implements `Function`, you should override the `apply(:AsyncEventError)` +method to handle the error with application-specific actions. The handler returns a `Boolean` to indicate whether it +was able to handle the error or not: .Custom `AsyncEventErrorHandler` implementation +==== [source,java] ---- class CustomAsyncEventErrorHandler implements AsyncEventErrorHandler { @@ -709,22 +726,27 @@ class CustomAsyncEventErrorHandler implements AsyncEventErrorHandler { if (error.getCause() instanceof OptimisticLockingFailureException) { // handle optimistic locking failure if you can - return true; // if error was successfully handled. + return true; // if error was successfully handled } else if (error.getCause() instanceof IncorrectResultSizeDataAccessException) { // handle no row or too many row update if you can - return true; // if error was successfully handled. + return true; // if error was successfully handled + } + else { + // ... } return false; } } ---- +==== -It is easy to configure the `RepositoryAsyncEventListener` with your custom `AsyncEventErrorHandler` using the -`AsyncInlineCachingRegionConfigurer`, like so: +You can configure the `RepositoryAsyncEventListener` with your custom `AsyncEventErrorHandler` by using the +`AsyncInlineCachingRegionConfigurer`: .Configuring a custom `AsyncEventErrorHandler` +==== [source,java] ---- @Configuration @@ -738,26 +760,24 @@ class GeodeConfiguration { @Bean AsyncInlineCachingRegionConfigurer asyncInlineCachingRegionConfigurer( CrudRepository repository, - CustomAsyncEventErrorHandler errorHandler - ) { + CustomAsyncEventErrorHandler errorHandler) { return AsyncInlineCachingRegionConfigurer.create(repository, "Example") .withAsyncEventErrorHandler(errorHandler); } } ---- +==== -Also, since `AsyncEventErrorHandler` implements `Function`, you can https://en.wikipedia.org/wiki/Composite_pattern["_compose_"] -multiple error handlers using {jdk-javadoc}/java/util/function/Function.html#andThen-java.util.function.Function-[`Function.andThen(:Function)`]. +Also, since `AsyncEventErrorHandler` implements `Function`, you can https://en.wikipedia.org/wiki/Composite_pattern[compose] +multiple error handlers by using {jdk-javadoc}/java/util/function/Function.html#andThen-java.util.function.Function-[`Function.andThen(:Function)`]. -SUPPORTED CACHE OPERATIONS +By default, the `RepositoryAsyncEventListener` handles `CREATE`, `UPDATE`, and `REMOVE` cache event, entry operations. -By default, the `RepositoryAsyncEventListener` handles `CREATE`, `UPDATE` and `REMOVE` cache event, entry operations. - -`CREATE` and `UPDATE` translates to `CrudRepository.save(entity)` where the `entity` is derived from +`CREATE` and `UPDATE` translate to `CrudRepository.save(entity)`. The `entity` is derived from `AsyncEvent.getDeserializedValue()`. -`REMOVE` translates to `CrudRepository.delete(entity)` where the `entity` is derived from +`REMOVE` translates to `CrudRepository.delete(entity)`. The `entity` is derived from `AsyncEvent.getDeserializedValue()`. The cache {apache-geode-javadoc}/org/apache/geode/cache/Operation.html[`Operation`] to `CrudRepository` method is @@ -765,11 +785,12 @@ supported by the `AsyncEventOperationRepositoryFunction` interface, which implem and is a `@FunctionalInterface`. This interface becomes useful if and when you want to implement `CrudRepository` method invocations for other -`AsyncEvent` `Operations` not handled by SBDG's `RepositoryAsyncEventListener` out-of-the-box. +`AsyncEvent` `Operations` not handled by SBDG's `RepositoryAsyncEventListener`. -The `AsyncEventOperationRepositoryFunction` interface is defined as: +The `AsyncEventOperationRepositoryFunction` interface is defined as follows: .AsyncEventOperationRepositoryFunction interface definition +==== [source,java] ---- @FunctionalInterface @@ -780,27 +801,30 @@ interface AsyncEventOperationRepositoryFunction implements Function { + extends RepositoryAsyncEventListener.AbstractAsyncEventOperationRepositoryFunction { InvalidateAsyncEventRepositoryFunction(RepositoryAsyncEventListener listener) { super(listener); @@ -819,22 +843,25 @@ class InvalidateAsyncEventRepositoryFunction } } ---- +==== -You can then register your user-defined, `AsyncEventOperationRepositoryFunction` -(i.e. `InvalidateAsyncEventRepositoryFunction`) with the `RepositoryAsyncEventListener` by using the -`AsyncInlineCachingRegionConfigurer`, like so: +You can then register your user-defined, `AsyncEventOperationRepositoryFunction` (that is, +`InvalidateAsyncEventRepositoryFunction`) with the `RepositoryAsyncEventListener` by using +the `AsyncInlineCachingRegionConfigurer`: .Configuring a user-defined `AsyncEventOperationRepositoryFunction` +==== [source,java] ---- -import org.springframework.geode.cache.RepositoryAsyncEventListener;@Configuration +import org.springframework.geode.cache.RepositoryAsyncEventListener; + +@Configuration class GeodeConfiguration { @Bean AsyncInlineCachingRegionConfigurer asyncInlineCachingRegionConfigurer( CrudRepository repository, - CustomerAsyncEventErrorHandler errorHandler - ) { + CustomAsyncEventErrorHandler errorHandler ) { return AsyncInlineCachingRegionConfigurer.create(repository, "ExampleRegion") .applyToListener(listener -> { @@ -852,87 +879,90 @@ class GeodeConfiguration { } } ---- +==== -This same technique can be applied to `CREATE`, `UPDATE` and `REMOVE` cache operations as well, effectively overriding -the default behavior for this cache operations handled by SBDG out-of-the-box. +This same technique can be applied to `CREATE`, `UPDATE`, and `REMOVE` cache operations as well, effectively overriding +the default behavior for these cache operations handled by SBDG. [[geode-caching-provider-inline-caching-asynchronous-region-configurer]] ====== About `AsyncInlineCachingRegionConfigurer` -As we saw in the previous section, it is possible to intercept and post-process key components constructed +As we saw in the previous section, you can intercept and post-process the essential components that are constructed and configured by the `AsyncInlineCachingRegionConfigurer` class during initialization. -Out-of-the-box, SBDG's allows you to intercept and post-process the `AsyncEventListener` (e.g. `RepositoryAsyncEventListener`), -`AsyncEventQueueFactory` and even the `AsyncEventQueue`, created by the `AsyncInlineCachingRegionConfigurer` +SBDG's lets you intercept and post-process the `AsyncEventListener` (such as `RepositoryAsyncEventListener`), +the `AsyncEventQueueFactory` and even the `AsyncEventQueue` created by the `AsyncInlineCachingRegionConfigurer` (a SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/RegionConfigurer.html[`RegionConfigurer`]) -during Spring `ApplicationContext`, bean initialization. +during Spring `ApplicationContext` bean initialization. -The `AsyncInlineCachingRegionConfigurer` class provides the builder methods listed below to intercept and post-process -any of the following {geode-name} objects: +The `AsyncInlineCachingRegionConfigurer` class provides the following builder methods to intercept and post-process any +of the following {geode-name} objects: * `applyToListener(:Function)` * `applyToQueue(:Function)` * `applyToQueueFactory(:Function)` -All of these "_apply_" methods accept a `java.util.function.Function` that "_applies_" the logic of the `Function` to -the {geode-name} object (e.g. `AsyncEventListener`), returning the object as a result. +All of these `apply*` methods accept a `java.util.function.Function` that applies the logic of the `Function` to +the {geode-name} object (such as `AsyncEventListener`), returning the object as a result. TIP: The {geode-name} object returned by the `Function` may be the same object, a proxy, or a completely new object. -Essentially, the returned object can be anything you want. This is the fundamental premise behind -_Aspect-Oriented Programming_ (AOP) and the https://en.wikipedia.org/wiki/Decorator_pattern[Decorator Software Design Pattern]. +Essentially, the returned object can be anything you want. This is the fundamental premise behind Aspect-Oriented +Programming (AOP) and the https://en.wikipedia.org/wiki/Decorator_pattern[Decorator software design pattern]. -These "_apply_" methods and the supplied `Function` allow you to decorate, enhance, post-process, whatever you want to, -to the {geode-name} objects created by the listener. +The `apply*` methods and the supplied `Function` let you decorate, enhance, post-process, or otherwise modify +the {geode-name} objects created by the configurer. -Of course, the `AsyncInlineCachingRegionConfigurer` strictly adheres to the https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle[Open/Close Principle] -as well, and is therefore flexibly extensible. +The `AsyncInlineCachingRegionConfigurer` strictly adheres to the https://en.wikipedia.org/wiki/Open%E2%80%93closed_principle[open/close principle] +and is, therefore, flexibly extensible. [[geode-caching-provider-multi-site-caching]] ==== Multi-Site Caching -The final pattern of caching presented in this chapter is _Multi-Site Caching_. +The final pattern of caching presented in this chapter is Multi-site caching. -As described above, there are 2 configuration arrangements depending on your application usage patterns, requirements -and user demographic: _Active-Active_ & _Active-Passive_. +As described earlier, there are two configuration arrangements, depending on your application usage patterns, +requirements and user demographic: active-active and active-passive. -_Multi-Site Caching_ along with _Active-Active_ and _Active-Passive_ configuration arrangements will be described -in more detail in the Sample link:guides/caching-multi-site.html[Guide]. Also, be sure to review the Sample -{github-samples-url}/caching/multi-site[Code]. +Multi-site caching, along with active-active and active-passive configuration arrangements, are described in more detail +in the sample link:guides/caching-multi-site.html[guide]. Also, be sure to review the sample +{github-samples-url}/caching/multi-site[code]. [[geode-caching-provider-advanced-configuration]] === Advanced Caching Configuration {geode-name} supports additional caching capabilities to manage the entries stored in the cache. -As you can imagine, given that cache entries are stored in-memory, it becomes important to monitor and manage the -available memory wisely. After all, by default, {geode-name} stores data in the JVM Heap. +As you can imagine, given that cache entries are stored in-memory, it becomes important to manage and monitor +the available memory used by the cache. After all, by default, {geode-name} stores data in the JVM Heap. -Several techniques can be employed to more effectively manage memory, such as using -{apache-geode-docs}/developing/eviction/chapter_overview.html[Eviction], possibly +You can employ several techniques to more effectively manage memory, such as using +{apache-geode-docs}/developing/eviction/chapter_overview.html[eviction], possibly {apache-geode-docs}/developing/storing_data_on_disk/chapter_overview.html[overflowing data to disk], -configuring both entry _Idle-Timeout_ (TTI) as well as _Time-To-Live_ (TTL) -{apache-geode-docs}/developing/expiration/chapter_overview.html[Expiration policies], -configuring {apache-geode-docs}/managing/region_compression.html[Compression], -and using {apache-geode-docs}/managing/heap_use/off_heap_management.html[Off-Heap], or main memory. +configuring both entry Idle-Timeout_ (TTI) and Time-to-Live_ (TTL) +{apache-geode-docs}/developing/expiration/chapter_overview.html[expiration policies], +configuring {apache-geode-docs}/managing/region_compression.html[compression], +and using {apache-geode-docs}/managing/heap_use/off_heap_management.html[off-heap] +or main memory. -There are several other strategies that can be used as well, as described in +You can use several other strategies as well, as described in {apache-geode-docs}/managing/heap_use/heap_management.html[Managing Heap and Off-heap Memory]. -While this is well beyond the scope of this document, know that Spring Data for {geode-name} makes all of these -{spring-data-geode-docs-html}/#bootstrap-annotation-config-regions[configuration options] available and simple to use. +While this is beyond the scope of this document, know that Spring Data for {geode-name} makes all of these +{spring-data-geode-docs-html}/#bootstrap-annotation-config-regions[configuration options] available to you. [[geode-caching-provider-disable]] === Disable Caching There may be cases where you do not want your Spring Boot application to cache application state with -{spring-framework-docs}/integration.html#cache[Spring's Cache Abstraction] using {geode-name}. In certain cases, you -may be using another Spring supported caching provider, such as Redis, to cache and manage your application state, -while, even in other cases, you may not want to use Spring's Cache Abstraction at all. +{spring-framework-docs}/integration.html#cache[Spring's Cache Abstraction] using {geode-name}. In certain cases, +you may use another Spring supported caching provider, such as Redis, to cache and manage your application state. +In other cases, you may not want to use Spring's Cache Abstraction at all. -Either way, you can specifically call out your Spring Cache Abstraction provider using the `spring.cache.type` property -in `application.properties`, as follows: +Either way, you can specifically call out your Spring Cache Abstraction provider by using the `spring.cache.type` +property in `application.properties`: .Use Redis as the Spring Cache Abstraction Provider +==== [source,txt] ---- #application.properties @@ -940,11 +970,13 @@ in `application.properties`, as follows: spring.cache.type=redis ... ---- +==== -If you prefer not to use Spring's Cache Abstraction to manage your Spring Boot application's state at all, then -do the following: +If you prefer not to use Spring's Cache Abstraction to manage your Spring Boot application's state at all, then set +the `spring.cache.type` property to "none": .Disable Spring's Cache Abstraction +==== [source,txt] ---- #application.properties @@ -952,13 +984,14 @@ do the following: spring.cache.type=none ... ---- +==== -See Spring Boot {spring-boot-docs-html}/boot-features-caching.html#boot-features-caching-provider-none[docs] -for more details. +See the Spring Boot {spring-boot-docs-html}/boot-features-caching.html#boot-features-caching-provider-none[documentation] +for more detail. -TIP: It is possible to include multiple providers on the classpath of your Spring Boot application. For instance, -you might be using Redis to cache your application's state while using {geode-name} as your application's persistent -data store (_System of Record_). +TIP: You can include multiple caching providers on the classpath of your Spring Boot application. For instance, +you might use Redis to cache your application's state while using {geode-name} as your application's persistent +data store (that is, the System of Record (SOR)). -NOTE: Spring Boot does not properly recognize `spring.cache.type=[gemfire|geode]` even though Spring Boot -for {geode-name} is setup to handle either of these property values (i.e. either "`gemfire`" or "`geode`"). +NOTE: Spring Boot does not properly recognize `spring.cache.type=[gemfire|geode]`, even though Spring Boot +for {geode-name} is set up to handle either of these property values (that is, either `gemfire` or `geode`). diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/clientcache-applications.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/clientcache-applications.adoc index 515649d7..3de546e8 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/clientcache-applications.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/clientcache-applications.adoc @@ -3,20 +3,21 @@ :geode-name: {apache-geode-name} -The first opinionated option provided to you by Spring Boot for {geode-name} (SBDG) out-of-the-box is a -{apache-geode-javadoc}/org/apache/geode/cache/client/ClientCache.html[ClientCache] instance simply by declaring -Spring Boot for {geode-name} on your application classpath. +The first opinionated option provided to you by Spring Boot for {geode-name} (SBDG) is a +{apache-geode-javadoc}/org/apache/geode/cache/client/ClientCache.html[`ClientCache`] instance +that you get by declaring Spring Boot for {geode-name} on your application classpath. -It is assumed that most application developers using Spring Boot to build applications backed by {geode-name} will be -building cache client applications deployed in an {geode-name} +It is assumed that most application developers who use Spring Boot to build applications backed by {geode-name} +are building cache client applications deployed in an {geode-name} {apache-geode-docs}/topologies_and_comm/cs_configuration/chapter_overview.html[Client/Server Topology]. -The _client/server topology_ is the most common and traditional architecture employed by enterprise applications when -using {geode-name}. +The client/server topology is the most common and traditional architecture employed by enterprise applications +that use {geode-name}. -For example, you can begin building a Spring Boot, {geode-name} `ClientCache` application by declaring the +For example, you can begin building a Spring Boot {geode-name} `ClientCache` application by declaring the `spring-geode-starter` on your application's classpath: .Spring Boot for {geode-name} on the application classpath +==== [source,xml] ---- @@ -24,11 +25,13 @@ For example, you can begin building a Spring Boot, {geode-name} `ClientCache` ap spring-geode-starter ---- +==== -Then, you configure and bootstrap your Spring Boot, {geode-name} `ClientCache` application with the following +Then you configure and bootstrap your Spring Boot {geode-name} `ClientCache` application with the following main application class: .Spring Boot, {geode-name} `ClientCache` Application +==== [source,java] ---- @SpringBootApplication @@ -39,34 +42,36 @@ public class SpringBootApacheGeodeClientCacheApplication { } } ---- +==== -Your application now has a `ClientCache` instance, which is able to connect to an {geode-name} server running on -`localhost`, listening on the default `CacheServer` port, `40404`. +Your application now has a `ClientCache` instance that can connect to an {geode-name} server running on `localhost` +and listening on the default `CacheServer` port, `40404`. -By default, an {geode-name} server (i.e. `CacheServer`) must be running in order to use the `ClientCache` instance. -However, it is perfectly valid to create a `ClientCache` instance and perform data access operations using `LOCAL` -Regions. This is very useful during development. +By default, an {geode-name} server (that is, `CacheServer`) must be running for the application to use the `ClientCache` +instance. However, it is perfectly valid to create a `ClientCache` instance and perform data access operations by using +`LOCAL` Regions. This is useful during development. -TIP: To develop with `LOCAL` Regions, you only need to configure your cache Regions with the +TIP: To develop with `LOCAL` Regions, configure your cache Regions with the {apache-geode-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html#LOCAL[`ClientRegionShortcut.LOCAL`] data management policy. When you are ready to switch from your local development environment (IDE) to a client/server architecture in a managed -environment, you simply change the data management policy of the client Region from `LOCAL` back to the default `PROXY`, -or even a `CACHING_PROXY`, which will cause the data to be sent/received to and from 1 or more servers, respectively. +environment, change the data management policy of the client Region from `LOCAL` back to the default (`PROXY`) +or even a `CACHING_PROXY`, which causes the data to be sent to and received from one or more servers. -TIP: Compare and contrast the above configuration with Spring Data for {geode-name} +TIP: Compare and contrast the preceding configuration with the Spring Data for {geode-name} {spring-data-geode-docs-html}/#bootstrap-annotation-config-geode-applications[approach]. It is uncommon to ever need a direct reference to the `ClientCache` instance provided by SBDG injected into your -application components (e.g. `@Service` or `@Repository` beans defined in a Spring `ApplicationContext`) whether you -are configuring additional {geode-name} objects (e.g. Regions, Indexes, etc) or simply using those objects indirectly -in your applications. However, it is also possible to do so if and when needed. +application components (for example, `@Service` or `@Repository` beans defined in a Spring `ApplicationContext`), +whether you are configuring additional {geode-name} objects (Regions, Indexes, and so on) or are using those objects +indirectly in your applications. However, it is possible to do so if and when needed. For example, perhaps you want to perform some additional `ClientCache` initialization in a Spring Boot -{spring-boot-javadoc}/org/springframework/boot/ApplicationRunner.html[ApplicationRunner] on startup: +{spring-boot-javadoc}/org/springframework/boot/ApplicationRunner.html[`ApplicationRunner`] on startup: .Injecting a `GemFireCache` reference +==== [source,java] ---- @SpringBootApplication @@ -88,29 +93,31 @@ public class SpringBootApacheGeodeClientCacheApplication { } } ---- +==== [[geode-peercache-applications]] === Building Embedded (Peer & Server) Cache Applications -What if you want to build an embedded, peer `Cache` application instead? +What if you want to build an embedded peer `Cache` application instead? Perhaps you need an actual peer cache member, configured and bootstrapped with Spring Boot, along with the ability -to join this member to an existing cluster (of data servers) as a peer node. Well, you can do that too. +to join this member to an existing cluster (of data servers) as a peer node. -Remember the 2nd goal in Spring Boot's {spring-boot-docs-html}/#getting-started-introducing-spring-boot[documentation]: +Remember the second goal in Spring Boot's {spring-boot-docs-html}/#getting-started-introducing-spring-boot[documentation]: -> _Be opinionated out of the box but get out of the way quickly as requirements start to diverge from the defaults._ +> Be opinionated out of the box but get out of the way quickly as requirements start to diverge from the defaults. -It is the 2nd part, "_get out of the way quickly as requirements start to diverge from the defaults_" -that we refer to here. +Here, we focus on the second part of the goal: "_get out of the way quickly as requirements start to diverge +from the defaults_". -If your application requirements demand you use Spring Boot to configure and bootstrap an embedded, peer `Cache` -instance, then simply declare your intention with either SDG's +If your application requirements demand you use Spring Boot to configure and bootstrap an embedded peer `Cache` instance, +declare your intention with either SDG's {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html[`@PeerCacheApplication`] annotation, -or alternatively, if you need to enable connections from `ClientCache` apps as well, use SDG's +or, if you also need to enable connections from `ClientCache` applications, use SDG's {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html[`@CacheServerApplication`] annotation: .Spring Boot, {geode-name} `CacheServer` Application +==== [source,java] ---- @SpringBootApplication @@ -122,20 +129,22 @@ public class SpringBootApacheGeodeCacheServerApplication { } } ---- +==== -TIP: An {geode-name} "server" is not necessarily a `CacheServer` capable of serving cache clients. It is merely a peer -member node in an {geode-name} cluster (a.k.a. distributed system) that stores and manages data. +TIP: An {geode-name} server is not necessarily a `CacheServer` capable of serving cache clients. It is merely a peer +member node in an {geode-name} cluster (that is, a distributed system) that stores and manages data. -By explicitly declaring the `@CacheServerApplication` annotation, you are telling Spring Boot that you do not want -the default, `ClientCache` instance, but rather an embedded, peer `Cache` instance with a `CacheServer` component, -which enables connections from `ClientCache` apps. +By explicitly declaring the `@CacheServerApplication` annotation, you tell Spring Boot that you do not want the default +`ClientCache` instance but rather want an embedded peer `Cache` instance with a `CacheServer` component, which enables +connections from `ClientCache` applications. -You can also enable 2 other {geode-name} services, an embedded _Locator_, which allows clients or even other peers -to "locate" servers in the cluster, as well as an embedded _Manager_, which allows the {geode-name} application process -to be managed and monitored using {apache-geode-docs}/tools_modules/gfsh/chapter_overview.html[_Gfsh_], {geode-name}'s -command-line shell tool: +You can also enable two other {geode-name} services: +* An embedded _Locator_, which allows clients or even other peers to locate servers in the cluster. +* An embedded _Manager_, which allows the {geode-name} application process to be managed and monitored by using +{apache-geode-docs}/tools_modules/gfsh/chapter_overview.html[Gfsh], {geode-name}'s command-line shell tool: -.Spring Boot, {geode-name} `CacheServer` Application with _Locator_ and _Manager_ services enabled +.Spring Boot {geode-name} `CacheServer` Application with _Locator_ and _Manager_ services enabled +==== [source,java] ---- @SpringBootApplication @@ -149,9 +158,11 @@ public class SpringBootApacheGeodeCacheServerApplication { } } ---- +==== -Then, you can use _Gfsh_ to connect to and manage this server: +Then you can use Gfsh to connect to and manage this server: +==== [source,text] ---- $ echo $GEMFIRE @@ -177,7 +188,7 @@ gfsh>list members ------------------------------------------- | -------------------------------------------------------------------------- SpringBootApacheGeodeCacheServerApplication | 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:29798):1024 -gfsh> + gfsh>describe member --name=SpringBootApacheGeodeCacheServerApplication Name : SpringBootApacheGeodeCacheServerApplication Id : 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:29798):1024 @@ -197,12 +208,14 @@ Server Port : 40404 Running : true Client Connections : 0 ---- +==== -You can even start additional servers in _Gfsh_, which will connect to your Spring Boot configured and bootstrapped -{geode-name} `CacheServer` application. These additional servers started in _Gfsh_ know about the Spring Boot, -{geode-name} server because of the embedded _Locator_ service, which is running on `localhost`, listening on -the default _Locator_ port, `10334`: +You can even start additional servers in Gfsh. These additional servers connect to your Spring Boot configured +and bootstrapped {geode-name} `CacheServer` application. These additional servers started in Gfsh know about +the Spring Boot, {geode-name} server because of the embedded Locator service, which is running on `localhost` +and listening on the default Locator port, `10334`: +==== [source,text] ---- gfsh>start server --name=GfshServer --log-level=config --disable-default-server @@ -224,11 +237,13 @@ gfsh>list members SpringBootApacheGeodeCacheServerApplication | 10.0.0.121(SpringBootApacheGeodeCacheServerApplication:29798):1024 GfshServer | 10.0.0.121(GfshServer:30031):1025 ---- +==== -Perhaps you want to start the other way around. As developer, I may need to connect my Spring Boot configured -and bootstrapped {geode-name} server application to an existing cluster. You can start the cluster in _Gfsh_ -by executing the following commands: +Perhaps you want to start the other way around. You may need to connect a Spring Boot configured and bootstrapped +{geode-name} server application to an existing cluster. You can start the cluster in Gfsh with the following commands +(shown with partial typical output): +==== [source,text] ---- gfsh>start locator --name=GfshLocator --port=11235 --log-level=config @@ -267,10 +282,12 @@ gfsh>list members GfshLocator | 10.0.0.121(GfshLocator:30245:locator):1024 GfshServer | 10.0.0.121(GfshServer:30270):1025 ---- +==== -Then, modify the `SpringBootApacheGeodeCacheServerApplication` class to connect to the existing cluster, like so: +Then modify the `SpringBootApacheGeodeCacheServerApplication` class to connect to the existing cluster: -.Spring Boot, {geode-name} `CacheServer` Application connecting to an external cluster +.Spring Boot {geode-name} `CacheServer` Application connecting to an external cluster +==== [source,java] ---- @SpringBootApplication @@ -282,13 +299,16 @@ public class SpringBootApacheGeodeCacheServerApplication { } } ---- +==== -TIP: Notice I configured the `SpringBootApacheGeodeCacheServerApplication` class, `@CacheServerApplication` annotation's -`locators` property with the host and port (i.e. "_localhost[11235]_") on which I started my _Locator_ using _Gfsh_. +TIP: Notice that the `SpringBootApacheGeodeCacheServerApplication` class, `@CacheServerApplication` annotation's +`locators` property are configured with the host and port (`localhost[11235]`), on which the Locator was started +by using Gfsh. -After running your Spring Boot, {geode-name} `CacheServer` application again, and then running `list members` in _Gfsh_, -you should see: +After running your Spring Boot {geode-name} `CacheServer` application again and executing the `list members` command +in Gfsh again, you should see output similar to the following: +==== [source,text] ---- gfsh>list members @@ -318,49 +338,49 @@ Server Port : 40404 Running : true Client Connections : 0 ---- +==== -In both scenarios, the Spring Boot configured and bootstrapped {geode-name} server and the _Gfsh_ _Locator_ -and _Gfsh_ _Server_ formed a cluster. +In both scenarios, the Spring Boot configured and bootstrapped {geode-name} server, the Gfsh Locator and Gfsh server +formed a cluster. While you can use either approach and Spring does not care, it is far more convenient to use Spring Boot and your IDE -to form a small cluster while developing. By leveraging Spring profiles, it is far simpler and much faster to -configure and start a small cluster. +to form a small cluster while developing. Spring profiles make it far simpler and much faster to configure and start +a small cluster. -Plus, this is useful for rapidly prototyping, testing and debugging your entire, end-to-end application -and system architecture, all right from the comfort and familiarity of your IDE of choice. No additional tooling -(e.g. _Gfsh_) or knowledge is required to get started quickly and easily. +Also, this approach enables rapidly prototyping, testing, and debugging your entire end-to-end application +and system architecture right from the comfort and familiarity of your IDE. No additional tooling (such as Gfsh) +or knowledge is required to get started quickly and easily. Just build and run. -Just _build_ and _run_! +TIP: Be careful to vary your port numbers for the embedded services, like the `CacheServer`, Locators, and the Manager, +especially if you start multiple instances on the same machine. Otherwise, you are likely to run into +a `java.net.BindException` caused by port conflicts. -TIP: Be careful to vary your port numbers for the embedded services, like the `CacheServer`, _Locators_ and _Manager_, -especially if you start multiple instances, otherwise you will run into a `java.net.BindException` -due to port conflicts. - -TIP: See the Appendix, <> for more details. +TIP: See the <> appendix for more details. [[geode-locator-applications]] === Building Locator Applications -In addition to `ClientCache`, `CacheServer` and peer `Cache` applications, SDG, and by extension SBDG, now supports -Locator-based, Spring Boot applications. +In addition to `ClientCache`, `CacheServer`, and peer `Cache` applications, SDG, and by extension SBDG, now supports +Spring Boot {geode-name} Locator applications. -An {geode-name} Locator is a location-based service, or alternatively and more typically, a standalone process enabling -clients to "locate" a cluster of {geode-name} servers to manage data. Many cache clients can connect to the same cluster -in order to share data. Running multiple clients is common in a Microservices architecture where you need to scale-up -the number of app instances to satisfy the demand. +An {geode-name} Locator is a location-based service or, more typically, a standalone process that lets clients locate +a cluster of {geode-name} servers to manage data. Many cache clients can connect to the same cluster to share data. +Running multiple clients is common in a Microservices architecture where you need to scale-up the number of application +instances to satisfy the demand. -A Locator is also used by joining members of an existing cluster to scale-out and increase capacity of the logically -pooled system resources (i.e. Memory, CPU and Disk). A Locator maintains metadata that is sent to the clients to -enable capabilities like single-hop data access, routing data access operations to the data node in the cluster -maintaining the data of interests. A Locator also maintains load information for servers in the cluster, which enables -the load to be uniformly distributed across the cluster while also providing fail-over services to a redundant member -if the primary fails. A Locator provides many more benefits and you are encouraged to read -the {apache-geode-docs}/configuring/running/running_the_locator.html[documentation] for more details. +An {geode-name} Locator is also used by joining members of an existing cluster to scale-out and increase capacity of +the logically pooled system resources (memory, CPU, network and disk). A Locator maintains metadata that is sent to +the clients to enable such capabilities as single-hop data access to route data access operations to the data node +in the cluster maintaining the data of interests. A Locator also maintains load information for servers in the cluster, +which enables the load to be uniformly distributed across the cluster while also providing fail-over services to a +redundant member if the primary fails. A Locator provides many more benefits, and we encourage you to read the +{apache-geode-docs}/configuring/running/running_the_locator.html[documentation] for more details. -As shown above, a Locator service can be embedded within either a peer `Cache` or `CacheServer`, Spring Boot application -using the SDG `@EnableLocator` annotation: +As shown earlier, you can embed a Locator service within either a Spring Boot peer `Cache` or a `CacheServer` +application by using the SDG `@EnableLocator` annotation: .Embedded Locator Service +==== [source,java] ---- @SpringBootApplication @@ -370,24 +390,25 @@ class SpringBootCacheServerWithEmbeddedLocatorApplication { // ... } ---- +==== -However, it is more common to start standalone Locator JVM processes. This is useful when you want to increase -the resiliency of your cluster in face of network and process failures, which are bound to happen. If a Locator JVM -process crashes or gets severed from the cluster due to a network failure, then having multiple Locators provides a -higher degree of availability (HA) through redundancy. +However, it is more common to start standalone Locator JVM processes. This is useful when you want to increase the +resiliency of your cluster in the face of network and process failures, which are bound to happen. If a Locator JVM +process crashes or gets severed from the cluster due to a network failure or partition, having multiple Locators +provides a higher degree of availability (HA) through redundancy. -Not to worry though, if all Locators in the cluster go down, then the cluster will still remain intact. -You simply won't be able to add more peer members (i.e. scale-up the number of data nodes in the cluster) -or connect any more clients. If all the Locators in the cluster go down, then it is safe to simply restart them -only after a thorough diagnosis. +Even if all Locators in the cluster go down, the cluster still remains intact. You cannot add more peer members +(that is, scale-up the number of data nodes in the cluster) or connect any more clients, but the cluster is fine. +If all the locators in the cluster go down, it is safe to restart them only after a thorough diagnosis. -NOTE: Once a client receives metadata about the cluster of servers, then all data access operations are sent directly -to servers in the cluster, not a Locator. Therefore, existing, connected clients will remain connected and operable. +NOTE: Once a client receives metadata about the cluster of servers, all data-access operations are sent directly to +servers in the cluster, not a Locator. Therefore, existing, connected clients remain connected and operable. -To configure and bootstrap Locator-based, Spring Boot applications as standalone JVM processes, use the following +To configure and bootstrap Spring Boot {geode-name} Locator applications as standalone JVM processes, use the following configuration: .Standalone Locator Process +==== [source,java] ---- @SpringBootApplication @@ -396,54 +417,57 @@ class SpringBootApacheGeodeLocatorApplication { // ... } ---- +==== Instead of using the `@EnableLocator` annotation, you now use the `@LocatorApplication` annotation. The `@LocatorApplication` annotation works in the same way as the `@PeerCacheApplication` and `@CacheServerApplication` -annotations, bootstrapping an {geode-name} process, overriding the default `ClientCache` instance provided by SBDG -out-of-the-box. +annotations, bootstrapping an {geode-name} process and overriding the default `ClientCache` instance provided by SBDG. -NOTE: If your `@SpringBootApplication` class is annotated with `@LocatorApplication`, then it can only be a `Locator` -and not a `ClientCache`, `CacheServer` or peer `Cache` application. If you need the application to function as a -peer `Cache`, perhaps with an embedded `CacheServer` components and embedded Locator, then you need to follow -the approach shown above using the `@EnableLocator` annotation with either the `@PeerCacheApplication` -or `@CacheServerApplication` annotation. +NOTE: If your `@SpringBootApplication` class is annotated with `@LocatorApplication`, it must be a `Locator` and not +a `ClientCache`, `CacheServer`, or peer `Cache` application. If you need the application to function as a peer `Cache`, +perhaps with embedded `CacheServer` components and an embedded Locator, you need to follow the approach shown earlier: +using the `@EnableLocator` annotation with either the `@PeerCacheApplication` or `@CacheServerApplication` annotation. -With our Spring Boot, {geode-name} Locator application, we can connect both Spring Boot configured and bootstrapped -peer members (peer `Cache`, `CacheServer` and `Locator` applications) as well as _Gfsh_ started Locators and Servers. +With our Spring Boot {geode-name} Locator application, we can connect both Spring Boot configured and bootstrapped +peer members (peer `Cache`, `CacheServer` and `Locator` applications) as well as Gfsh started Locators and servers. -First, let's startup 2 Locators using our {geode-name} Locator, Spring Boot application class. +First, we need to start two Locators by using our Spring Boot {geode-name} Locator application class: .SpringBootApacheGeodeLocatorApplication class +==== [source,java] ---- include::{docs-src-dir}/org/springframework/geode/docs/example/app/locator/SpringBootApacheGeodeLocatorApplication.java[tags=class] ---- +==== -We also need to vary the configuration for each Locator app instance. +We also need to vary the configuration for each Locator application instance. {geode-name} requires each peer member in the cluster to be uniquely named. We can set the name of the Locator by using -the `spring.data.gemfire.locator.name` SDG property set as a JVM System Property in your IDE's Run Configuration Profile -for the application main class like so: `-Dspring.data.gemfire.locator.name=SpringLocatorOne`. We name the second -Locator app instance, "_SpringLocatorTwo_". +the `spring.data.gemfire.locator.name` SDG property set as a JVM System Property in your IDE's run configuration profile +for the main application class: `-Dspring.data.gemfire.locator.name=SpringLocatorOne`. We name the second Locator +application instance `SpringLocatorTwo`. Additionally, we must vary the port numbers that the Locators use to listen for connections. By default, an {geode-name} -Locator listens on port `10334`. We can set the Locator port using the `spring.data.gemfire.locator.port` SDG property. +Locator listens on port `10334`. We can set the Locator port by using the `spring.data.gemfire.locator.port` +SDG property. -For our first Locator app instance (i.e. "_SpringLocatorOne_"), we also enable the "_manager_" Profile so that -we can connect to the Locator using _Gfsh_. +For our first Locator application instance (`SpringLocatorOne`), we also enable the "manager" profile so that +we can connect to the Locator by using Gfsh. -Our IDE Run Configuration Profile for our first Locator app instance appears as: +Our IDE run configuration profile for our first Locator application instance appears as: `-server -ea -Dspring.profiles.active=manager -Dspring.data.gemfire.locator.name=SpringLocatorOne -Dlogback.log.level=INFO` -And our IDE Run Configuration Profile for our second Locator app instance appears as: +And our IDE run configuration profile for our second Locator application instance appears as: `-server -ea -Dspring.profiles.active= -Dspring.data.gemfire.locator.name=SpringLocatorTwo -Dspring.data.gemfire.locator.port=11235 -Dlogback.log.level=INFO` -You should see log output similar to the following when you start a Locator app instance: +You should see log output similar to the following when you start a Locator application instance: -.Spring Boot, {geode-name} Locator log output +.Spring Boot {geode-name} Locator log output +==== [source,txt] ---- . ____ _ __ _ _ @@ -520,11 +544,13 @@ Class Path: 2019-09-01 11:02:54,242 INFO .SpringBootApacheGeodeLocatorApplication: 61 - Started SpringBootApacheGeodeLocatorApplication in 6.137470354 seconds (JVM running for 6.667) Press to exit! ---- +==== -Next, start up the second Locator app instance (you should see log output similar to above). Then, connect to -the cluster of Locators using _Gfsh_: +Next, start up the second Locator application instance (you should see log output similar to the preceding list). +Then connect to the cluster of Locators by using Gfsh: .Cluster of Locators +==== [source,txt] ---- $ echo $GEMFIRE @@ -550,23 +576,27 @@ gfsh>list members SpringLocatorOne | 10.99.199.24(SpringLocatorOne:30043:locator):41000 [Coordinator] SpringLocatorTwo | 10.99.199.24(SpringLocatorTwo:30077:locator):41001 ---- +==== -Using our `SpringBootApacheGeodeCacheServerApplication` main class from the previous section, we can configure -and bootstrap an {geode-name} `CacheServer` application with Spring Boot and connect it to our cluster of Locators. +By using our `SpringBootApacheGeodeCacheServerApplication` main class from the previous section, we can configure +and bootstrap an {geode-name} `CacheServer` application with Spring Boot and connect it to our cluster of Locators: .SpringBootApacheGeodeCacheServerApplication class +==== [source,java] ---- include::{docs-src-dir}/org/springframework/geode/docs/example/app/server/SpringBootApacheGeodeCacheServerApplication.java[tags=class] ---- +==== -Simply enable the "clustered" Profile by using a IDE Run Profile Configuration similar to: +To do so, enable the "clustered" profile by using an IDE run profile configuration similar to: `-server -ea -Dspring.profiles.active=clustered -Dspring.data.gemfire.name=SpringServer -Dspring.data.gemfire.cache.server.port=41414 -Dlogback.log.level=INFO` After the server starts up, you should see the new peer member in the cluster: .Cluster with Spring Boot configured and bootstrapped {geode-name} `CacheServer` +==== [source,txt] ---- gfsh>list members @@ -576,10 +606,12 @@ SpringLocatorOne | 10.99.199.24(SpringLocatorOne:30043:locator):41000 [C SpringLocatorTwo | 10.99.199.24(SpringLocatorTwo:30077:locator):41001 SpringServer | 10.99.199.24(SpringServer:30216):41002 ---- +==== -Finally, we can even start additional Locators and Servers connected to this cluster using _Gfsh_: +Finally, we can even start additional Locators and servers connected to this cluster by using Gfsh: .Gfsh started Locators and Servers +==== [source,txt] ---- gfsh>start locator --name=GfshLocator --port=12345 --log-level=config @@ -615,28 +647,30 @@ SpringServer | 10.99.199.24(SpringServer:30216):41002 GfshLocator | 10.99.199.24(GfshLocator:30259:locator):41003 GfshServer | 10.99.199.24(GfshServer:30295):41004 ---- +==== -You must be careful to vary the ports and name of your peer members appropriately. With Spring, and Spring Boot -for {geode-name} (SBDG) in particular, it really is that easy! +You must be careful to vary the ports and name of your peer members appropriately. Spring, and Spring Boot +for {geode-name} (SBDG) in particular, make doing so easy. [[geode-manager-applications]] === Building Manager Applications -As discussed in the previous sections above, it is possible to enable a Spring Boot configured and bootstrapped -{geode-name} peer member node in the cluster to function as a _Manager_. +As discussed in the previous sections, you can enable a Spring Boot configured and bootstrapped {geode-name} +peer member node in the cluster to function as a Manager. -An {geode-name} _Manager_ is a peer member node in the cluster running the Management Service, allowing the cluster -to be managed and monitored using JMX based tools, like _Gfsh_, _JConsole_ or _JVisualVM_, for instance. Any tool -that uses the JMX API can connect to and manage an {geode-name} cluster for whatever purpose. +An {geode-name} Manager is a peer member node in the cluster that runs the management service, letting the cluster +be managed and monitored with JMX-based tools, such as Gfsh, JConsole, or JVisualVM. Any tool using the JMX API +can connect to and manage an {geode-name} cluster for whatever purpose. -The cluster may have more than 1 _Manager_ for redundancy. Only server-side, peer member nodes in the cluster -may function as a _Manager_. Therefore, a `ClientCache` application cannot be a _Manager_. +Like Locators, the cluster may have more than one Manager for redundancy. Only server-side, peer member nodes +in the cluster may function Managers. Therefore, a `ClientCache` application cannot be a Manager. -To create a _Manager_, you use the SDG `@EnableManager` annotation. +To create a Manager, use the SDG `@EnableManager` annotation. -The 3 primary uses of the `@EnableManager` annotation to create a _Manager_ is: +The three primary uses of the `@EnableManager` annotation to create a Manager are: -.1 - CacheServer Manager Application +1 - CacheServer Manager Application +==== [source,java] ---- @SpringBootApplication @@ -646,8 +680,10 @@ class CacheServerManagerApplication { // ... } ---- +==== -.2 - Peer Cache Manager Application +2 - Peer Cache Manager Application +==== [source,java] ---- @SpringBootApplication @@ -657,8 +693,10 @@ class SpringBootPeerCacheManagerApplication { // ... } ---- +==== -.3 - Locator Manager Application +3 - Locator Manager Application +==== [source,java] ---- @SpringBootApplication @@ -668,34 +706,37 @@ class LocatorManagerApplication { // ... } ---- +==== -#1 creates a peer `Cache` instance with a `CacheServer` component accepting client connections along with -an embedded _Manager_ enabling JMX clients to connect. +#1 creates a peer `Cache` instance with a `CacheServer` component that accepts client connections along with +an embedded Manager that lets JMX clients connect. -#2 creates only a peer `Cache` instance along with an embedded _Manager_. As a peer `Cache` with NO `CacheServer` -component, clients are not able to connect to this node. It is merely a server managing data. +#2 creates only a peer `Cache` instance along with an embedded Manager. As a peer `Cache` with no `CacheServer` +component, clients are not able to connect to this node. It is merely a server managing data. -#3 creates a _Locator_ instance with an embedded _Manager_. +#3 creates a Locator instance with an embedded Manager. -In all configuration arrangements, the _Manager_ was configured to start immediately. +In all configuration arrangements, the Manager is configured to start immediately. -TIP: See the `@EnableManager` annotation -{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html[Javadoc] +TIP: See the Javadoc for the +{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html[`@EnableManager` annotation] for additional configuration options. -As of {geode-name} 1.11.0, you must now include additional {geode-name} dependencies on your Spring Boot application -classpath to make your application a proper {geode-name} _Manager_ in the cluster, particularly if you are also enabling -the embedded HTTP service in the _Manager_. +As of {geode-name} 1.11.0, you must include additional {geode-name} dependencies on your Spring Boot application +classpath to make your application a proper {geode-name} Manager in the cluster, particularly if you also enable +the embedded HTTP service in the Manager. The required dependencies are: -.Additional, required Manager dependencies expressed in Gradle +.Additional Manager dependencies expressed in Gradle +==== [source,groovy] ---- runtime "org.apache.geode:geode-http-service" runtime "org.apache.geode:geode-web" runtime "org.springframework.boot:spring-boot-starter-jetty" ---- +==== The embedded HTTP service (implemented with the Eclipse Jetty Servlet Container), runs the Management (Admin) REST API, which is used by tooling, such as _Gfsh_, to connect to the cluster over HTTP. In addition, it also enables the @@ -708,10 +749,12 @@ and `spring-boot-starter-jetty` dependencies. Optionally, you may also include the `geode-pulse` dependency, as follows: .Additional, optional Manager depdendencies expressed in Gradle +==== [source,groovy] ---- runtime "org.apache.geode:geode-pulse" ---- +==== The `geode-pulse` dependency is only required if you want the _Manager_ to automatically start the {geode-name} {apache-geode-docs}/tools_modules/pulse/pulse-overview.html[Pulse] Monitoring Tool. _Pulse_ enables diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/cloudfoundry.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/cloudfoundry.adoc index 2c1d2aa8..f8125ff7 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/cloudfoundry.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/cloudfoundry.adoc @@ -5,72 +5,74 @@ :pcc-name: Pivotal Cloud Cache :pcf-name: Pivotal CloudFoundry - -NOTE: As of the VMware, Inc acquisition of Pivotal Software, Inc, {pcf-name} (PCF) is now known as VMware Tanzu +NOTE: As of the VMware, Inc. acquisition of Pivotal Software, Inc., {pcf-name} (PCF) is now known as VMware Tanzu Application Service (TAS) for VMs. Also, {pcc-name} (PCC) has been rebranded as VMware Tanzu GemFire for VMS. This documentation will eventually be updated to reflect the rebranding. -In most cases, when you deploy (i.e. "_push_") your Spring Boot applications to {pcf-name} (PCF) you will bind your app -to 1 or more instances of the {pcc-name} (PCC) service. +In most cases, when you deploy (that is, `cf push`) your Spring Boot applications to {pcf-name} (PCF), you bind +your application to one or more instances of the {pcc-name} (PCC) service. In a nutshell, {pivotal-cloudcache-website}[{pcc-name}] (PCC) is a managed version of -{pivotal-gemfire-website}[Pivotal GemFire] running in {pivotal-cloudfoundry-website}[{pcf-name}] (PCF). -When running in or across cloud environments (e.g. AWS, Azure, GCP or PWS), PCC with PCF offers several advantages +{pivotal-gemfire-website}[{pivotal-gemfire-name}] that runs in {pivotal-cloudfoundry-website}[{pcf-name}] (PCF). +When running in or across cloud environments (such as AWS, Azure, GCP, or PWS), PCC with PCF offers several advantages over trying to run and manage your own standalone {geode-name} clusters. It handles many of the infrastructure-related, -operational concerns so you do not have to. +operational concerns so that you need not do so. [[cloudfoundry-cloudcache-security-auth-runtime-user-configuration]] -=== Running Spring Boot applications as a specific user +=== Running a Spring Boot application as a specific user -By default, Spring Boot applications run as a "_cluster_operator_" Role-based user in {pcf-name} when the app is bound -to a {pcc-name} service instance. +By default, Spring Boot applications run as a `cluster_operator` role-based user in {pcf-name} when the application +is bound to a {pcc-name} service instance. -A "_cluster_operator_" has full system privileges (i.e. Authorization) to do whatever that user wishes to involving -the PCC service instance. A "_cluster_operator_" has read/write access to all the data, can modify the schema -(e.g. create/destroy Regions, add/remove Indexes, change eviction or expiration policies, etc), start and stop servers -in the PCC cluster, or even modify permissions. +A `cluster_operator` has full system privileges (that is, authorization) to do whatever that user wishes to involving +the PCC service instance. A `cluster_operator` has read and write access to all the data, can modify the schema (for +example, create and destroy Regions, add and remove Indexes, change eviction or expiration policies, and so on), start +and stop servers in the PCC cluster, or even modify permissions. -.About _cluster-operator_ as the default user +.About cluster_operator as the default user **** -1 of the reasons why Spring Boot apps default to running as a "_cluster_operator_" is to allow configuration metadata to -be sent from the client to the server. Enabling configuration metadata to be sent from the client to the server is a -useful development-time feature and is as simple as annotating your main `@SpringBootApplication` class with -the `@EnableClusterConfiguration` annotation: +One of the reasons why Spring Boot applications default to running as a `cluster_operator` is to allow configuration +metadata to be sent from the client to the server. Enabling configuration metadata to be sent from the client to the +server is a useful development-time feature and is as simple as annotating your main `@SpringBootApplication` class +with the `@EnableClusterConfiguration` annotation: .Using `@EnableClusterConfiguration` +==== [source,java] ---- @SpringBootApplication @EnableClusterConfiguration(useHttp = true) class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -With `@EnableClusterConfiguration`, Region and OQL Index configuration metadata defined on the client can be sent to -servers in the PCC cluster. {geode-name} requires matching Regions by name on both the client and servers in order for -clients to send and receive data to and from the cluster. +With `@EnableClusterConfiguration`, Region and OQL Index configuration metadata that is defined on the client can be +sent to servers in the PCC cluster. {geode-name} requires matching Regions by name on both the client and the servers +in order for clients to send and receive data to and from the cluster. -For example, when you declare the Region where an application entity will be persisted using the `@Region` mapping -annotation and additionally declare the `@EnableEntityDefinedRegions` annotation on the main `@SpringBootApplication` -class in conjunction with the `@EnableClusterConfiguration` annotation, then not only will SBDG create the required -client Region, but it will also send the configuration metadata for this Region to the servers in the cluster to create -the matching, required server Region, where the data for your application entity will be managed. +For example, when you declare the Region where an application entity is persisted by using the `@Region` mapping +annotation and declare the `@EnableEntityDefinedRegions` annotation on the main `@SpringBootApplication` class +in conjunction with the `@EnableClusterConfiguration` annotation, not only does SBDG create the required client Region, +but it also sends the configuration metadata for this Region to the servers in the cluster to create the matching, +required server Region, where the data for your application entity is managed. **** However... > With great power comes great responsibility. - Uncle Ben -Not all Spring Boot applications using PCC will need to change the schema, or even modify data. Rather, certain apps -may only need read access. Therefore, it is ideal to be able to configure your Spring Boot applications to run with -a different user at runtime other than the auto-configured "_cluster_operator_", by default. +Not all Spring Boot applications using PCC need to change the schema or even modify data. Rather, certain applications +may need only read access. Therefore, it is ideal to be able to configure your Spring Boot applications to run with +a different user at runtime other than the auto-configured `cluster_operator`, by default. -A prerequisite for running a Spring Boot application using PCC with a specific user is to create a user with restricted -permissions using {pcf-name} _AppsManager_ while provisioning the PCC service instance to which the Spring Boot app -will be bound. +A prerequisite for running a Spring Boot application in PCC with a specific user is to create a user with restricted +permissions by using {pcf-name} AppsManager while provisioning the PCC service instance to which the Spring Boot +application is bound. Configuration metadata for the PCC service instance might appear as follows: .{pcc-name} configuration metadata +==== [source,json] ---- { @@ -110,48 +112,53 @@ Configuration metadata for the PCC service instance might appear as follows: }] } ---- +==== -In the PCC service instance configuration metadata above, we see a "_guest_" user with the "_read-only-user_" Role. -If the "_read-only-user_" Role is properly configured with "read-only" permissions as the name implies, then we could -configure our Spring Boot application to run as "_guest_" with read-only access using: +In the PCC service instance configuration metadata shown in the preceding example, we see a `guest` user with +the `read-only-user` role. If the `read-only-user` role is properly configured with read-only permissions as the name +implies, we could configure our Spring Boot application to run as `guest` with read-only access: -.Configuring a Spring Boot app to run as a specific user +.Configuring a Spring Boot application to run as a specific user +==== [source,properties] ---- # Spring Boot application.properties for PCF when using PCC spring.data.gemfire.security.username=guest ---- +==== -TIP: The `spring.data.gemfire.security.username` property corresponds directly to the SDG `@EnableSecurity` annotation, -`securityUsername` attribute. -See the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityUsername--[Javadoc] +TIP: The `spring.data.gemfire.security.username` property corresponds directly to the SDG `@EnableSecurity` annotation's +`securityUsername` attribute. See the +{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityUsername--[Javadoc] for more details. The `spring.data.gemfire.security.username` property is the same property used by Spring Data for {geode-name} (SDG) to -configure the runtime user of your Spring Data application when connecting to an externally managed {geode-name} cluster. +configure the runtime user of your Spring Data application when you connect to an externally managed {geode-name} +cluster. -In this case, SBDG simply uses the configured username to lookup the authentication credentials of the user to set -the username and password used by the Spring Boot, `ClientCache` app when connecting to PCC while running in PCF. +In this case, SBDG uses the configured username to look up the authentication credentials of the user to set +the username and password used by the Spring Boot `ClientCache` application when connecting to PCC while running in PCF. -If the username is not valid, then an `IllegalStateException` is thrown. +If the username is not valid, an `IllegalStateException` is thrown. -By using {spring-boot-docs-html}/#boot-features-profiles[Spring Profiles], it would be a simple matter to configure +By using {spring-boot-docs-html}/#boot-features-profiles[Spring profiles], it would be a simple matter to configure the Spring Boot application to run with a different user depending on environment. -See the {pcc-name} documentation on {pivotal-cloudcache-docs}/security.html[Security] for configuring users with -assigned roles & permissions. +See the {pcc-name} documentation on {pivotal-cloudcache-docs}/security.html[security] for configuring users with +assigned roles and permissions. [[cloudfoundry-cloudcache-security-auth-autoconfiguration-override]] ==== Overriding Authentication Auto-configuration -It should be generally understood that _auto-configuration_ for client authentication is only available for managed -environments, like {pcf-name}. When running in externally managed environments, you must explicitly set a username -and password to authenticate, as described <>. +It should be understood that auto-configuration for client authentication is available only for managed environments, +such as {pcf-name}. When running in externally managed environments, you must explicitly set a username and password +to authenticate, as described in <>. -To completely override the _auto-configuration_ of client authentication, simply set both a username and password: +To completely override the auto-configuration of client authentication, you can set both a username and a password: .Overriding Security Authentication Auto-configuration with explicit username and password +==== [source,txt] ---- # Spring Boot application.properties @@ -159,53 +166,57 @@ To completely override the _auto-configuration_ of client authentication, simply spring.data.gemfire.security.username=MyUser spring.data.gemfire.security.password=MyPassword ---- +==== -In this case, SBDG's _auto-configuration_ for authentication is effectively disabled and security credentials -will not be extracted from the environment. +In this case, SBDG's auto-configuration for authentication is effectively disabled and security credentials are not +extracted from the environment. [[cloudfoundry-cloudcache-serviceinstance-targeting]] === Targeting Specific {pcc-name} Service Instances It is possible to provision multiple instances of the {pcc-name} service in your {pcf-name} environment. You can then -bind multiple PCC service instances to your Spring Boot app. +bind multiple PCC service instances to your Spring Boot application. -However, Spring Boot for {geode-name} (SBDG) will only auto-configure 1 PCC service instance for your Spring Boot -application. This does not mean it is not possible to use multiple PCC service instances with your Spring Boot app, -just that SBDG only "_auto-configures_" 1 service instance for you. +However, Spring Boot for {geode-name} (SBDG) only auto-configures one PCC service instance for your Spring Boot +application. This does not mean that it is not possible to use multiple PCC service instances with your Spring Boot +application, just that SBDG only auto-configures one service instance for you. -You must select which PCC service instance your Spring Boot app will auto-configure for you automatically when you have -multiple instances and want to target a specific PCC service instance to use. +You must select which PCC service instance your Spring Boot application automatically auto-configures for you when +you have multiple instances and want to target a specific PCC service instance to use. To do so, declare the following SBDG property in Spring Boot `application.properties`: .Spring Boot application.properties targeting a specific PCC service instance by name +==== [source,properties] ---- # Spring Boot application.properties spring.boot.data.gemfire.cloud.cloudfoundry.service.cloudcache.name=pccServiceInstanceTwo ---- +==== The `spring.boot.data.gemfire.cloud.cloudfoundry.service.cloudcache.name` property tells SBDG which PCC service instance to auto-configure. -If the named PCC service instance identified by the property does not exist, then SBDG will throw -an `IllegalStateException` stating the PCC service instance by name could not be found. +If the PCC service instance identified by the property does not exist, SBDG throws an `IllegalStateException` +stating the PCC service instance by name could not be found. -If you did not set the property and your Spring Boot app is bound to multiple PCC service instances, -then SBDG will auto-configure the first PCC service instance it finds by name, alphabetically. +If you did not set the property and your Spring Boot application is bound to multiple PCC service instances, +SBDG auto-configures the first PCC service instance it finds by name, alphabetically. -If you did not set the property and no PCC service instance is found, then SBDG will log a warning. +If you did not set the property and no PCC service instance is found, SBDG logs a warning. [[cloudfoundry-cloudcache-multiinstance-using]] === Using Multiple {pcc-name} Service Instances -If you want to use multiple PCC service instances with your Spring Boot application, then you need to configure -multiple connection `Pools` connected to each PCC service instance used by your Spring Boot application. +If you want to use multiple PCC service instances with your Spring Boot application, you need to configure multiple +connection `Pools` connected to each PCC service instance used by your Spring Boot application. The configuration would be similar to the following: .Multiple {pcc-name} Service Instance Configuration +==== [source,java] ---- @Configuration @@ -219,11 +230,13 @@ class PccConfiguration { // ... } ---- +==== You would then externalize the configuration for the individually declared `Pools` in Spring Boot `application.properties`: -.Configuring Pool Locator connection endpoints +.Configuring Locator-based Pool connections +==== [source,properties] ---- # Spring Boot `application.properties` @@ -232,18 +245,20 @@ spring.data.gemfire.pool.pccone.locators=pccOneHost1[port1], pccOneHost2[port2], spring.data.gemfire.pool.pcctwo.locators=pccTwoHost1[port1], pccTwoHost2[port2], ..., pccTwoHostN[portN] ---- +==== NOTE: Though less common, you can also configure the `Pool` of connections to target specific servers in the cluster -using the `spring.data.gemfire.pool..severs` property. +by setting the `spring.data.gemfire.pool..severs` property. -TIP: Keep in mind that properties in Spring Boot `application.properties` can refer to other properties like so: -`property=$\{otherProperty}`. This allows you to further externalize properties using Java System properties -or Environment Variables. +TIP: Keep in mind that properties in Spring Boot `application.properties` can refer to other properties: +`property=$\{otherProperty}`. This lets you further externalize properties by using Java System properties +or environment variables. -Of course, a client Region is then assigned the Pool of connections that are used to send data to/from -the specific PCC service instance (cluster): +A client Region is then assigned the Pool of connections that are used to send data to and from the specific +PCC service instance (cluster): .Assigning a Pool to a client Region +==== [source,java] ---- @Configuration @@ -263,63 +278,67 @@ class GeodeConfiguration { } } ---- +==== -You can configure as many Pools and client Regions as needed by your application. Again, the `Pool` determines -which {pcc-name} service instance and cluster the data for the client Region will reside. +You can configure as many Pools and client Regions as your application needs. Again, the `Pool` determines +the {pcc-name} service instance and cluster in which the data for the client Region resides. -NOTE: By default, SBDG configures all `Pools` declared in a Spring Boot, `ClientCache` application to connect to -and use a single PCC service instance. This may be a targeted PCC service instance when using the +NOTE: By default, SBDG configures all `Pools` declared in a Spring Boot `ClientCache` application to connect to +and use a single PCC service instance. This may be a targeted PCC service instance when you use the `spring.boot.data.gemfire.cloud.cloudfoundry.service.cloudcache.name` property -as discussed <>. +as discussed <>. [[cloudfoundry-geode]] -=== Hybrid {pcf-name} & {geode-name} Spring Boot Applications +=== Hybrid {pcf-name} and {geode-name} Spring Boot Applications -Sometimes, it is desirable to deploy (i.e. "_push_") and run your Spring Boot applications in {pcf-name}, but still -connect your Spring Boot applications to an externally managed, standalone {geode-name} cluster. +Sometimes, it is desirable to deploy (that is, `cf push`) and run your Spring Boot applications in {pcf-name} +but still connect your Spring Boot applications to an externally managed, standalone {geode-name} cluster. Spring Boot for {geode-name} (SBDG) makes this a non-event and honors its "_little to no code or configuration changes -necessary_" goal, regardless of your runtime choice, "_it should just work!_" +necessary_" goal. Regardless of your runtime choice, it should just work! -To help guide you through this process, we will cover the following topics: +To help guide you through this process, we cover the following topics: -1. Install and Run PCFDev. -2. Start an {geode-name} cluster. -3. Create a User-Provided Service (CUPS). -4. Push and Bind a Spring Boot application. -5. Run the Spring Boot application. +. Install and Run PCFDev. +. Start an {geode-name} cluster. +. Create a User-Provided Service (CUPS). +. Push and Bind a Spring Boot application. +. Run the Spring Boot application. [[cloudfoundry-geode-pcfdev]] ==== Running PCFDev -For this exercise, we will be using https://pivotal.io/pcf-dev[PCF Dev]. +For this exercise, we use https://docs.pivotal.io/pcf-dev/install-osx.html[PCF Dev]. -PCF Dev, much like PCF, is an elastic application runtime for deploying, running and managing your Spring Boot -applications. However, it does so in the confines of your local development environment, i.e. your workstation. +PCF Dev, much like PCF, is an elastic application runtime for deploying, running, and managing your Spring Boot +applications. However, it does so in the confines of your local development environment -- that is, your workstation. -Additionally, PCF Dev provides several services out-of-the-box, such as MySQL, Redis and RabbitMQ. These services -can be bound and used by your Spring Boot application to accomplish its tasks. +Additionally, PCF Dev provides several services, such as MySQL, Redis, and RabbitMQ. You Spring Boot application +can bind to and use these services to accomplish its tasks. -However, PCF Dev lacks the {pcc-name} service that is available in PCF. This is actually ideal for this little exercise -since we are trying to build and run Spring Boot applications in a PCF environment but connect to an externally managed, +However, PCF Dev lacks the {pcc-name} service that is available in PCF. This is actually ideal for this exercise since +we are trying to build and run Spring Boot applications in a PCF environment but connect to an externally managed, standalone {geode-name} cluster. -As a prerequisite, you will need to follow the steps outlined in the +As a prerequisite, you need to follow the steps outlined in the https://pivotal.io/platform/pcf-tutorials/getting-started-with-pivotal-cloud-foundry-dev/introduction[tutorial] -to get PCF Dev setup and running on your workstation. +to get PCF Dev set up and running on your workstation. -To run PCF Dev, you will execute the following `cf` CLI command, replacing the path to the TGZ file -with the file you acquired from the https://network.pivotal.io/products/pcfdev[download]: +To run PCF Dev, execute the following `cf` CLI command, replacing the path to the TGZ file with the file you acquired +from the https://network.pivotal.io/products/pcfdev[download]: .Start PCF Dev +==== [source,txt] ---- $ cf dev start -f ~/Downloads/Pivotal/CloudFoundry/Dev/pcfdev-v1.2.0-darwin.tgz ---- +==== -You should see output similar to: +You should see output similar to the following: .Running PCF Dev +==== [source,txt] ---- Downloading Network Helper... @@ -360,34 +379,38 @@ Deploying Apps-Manager... To deploy a particular service, please run: cf dev deploy-service [Available services: mysql,redis,rabbitmq,scs] ---- +==== To use the `cf` CLI tool, you must login to the PCF Dev environment: .Login to PCF Dev using `cf` CLI +==== [source,txt] ---- $ cf login -a https://api.dev.cfdev.sh --skip-ssl-validation ---- +==== You can also access the https://apps.dev.cfdev.sh/[PCF Dev Apps Manager] tool from your Web browser at the following URL: https://apps.dev.cfdev.sh/ -Apps Manager provides a nice UI to manage your org, space, services and apps. It lets you push and update apps, -create services, bind apps to the services and start and stop your deployed applications, among many other things. +Apps Manager provides a nice UI to manage your org, space, services and apps. It lets you push and update apps, +create services, bind apps to the services, and start and stop your deployed applications, among many other things. [[cloudfoundry-geode-cluster]] ==== Running an {geode-name} Cluster -Now that PCF Dev is setup and running, we need to start an external, standalone {geode-name} cluster that our Spring Boot -application will connect to and use to manage its data. +Now that PCF Dev is set up and running, you need to start an external, standalone {geode-name} cluster to which our +Spring Boot application connects and uses to manage its data. -You will need to install a {apache-geode-website}/releases/[distribution] of {geode-name} on your workstation. -Then you must set the `$GEODE` environment variable. It is also convenient to add `$GEODE/bin` to your system `$PATH`. +You need to install a {apache-geode-website}/releases/[distribution] of {geode-name} on your computer. Then you must +set the `$GEODE` environment variable. It is also convenient to add `$GEODE/bin` to your system `$PATH`. Afterward, you can launch the Geode Shell (_Gfsh_) tool: .Running Gfsh +==== [source,txt] ---- $ echo $GEODE @@ -403,28 +426,32 @@ $ gfsh Monitor and Manage Apache Geode gfsh> ---- +==== -We have conveniently provided the _Gfsh_ shell script used to start the {geode-name} cluster: +We have provided the Gfsh shell script that you can use to start the {geode-name} cluster: .Gfsh shell script to start the {geode-name} cluster +==== [source,txt] ---- include::{docs-resources-dir}/geode/bin/start-cluster.gfsh[] ---- +==== -The `start-cluster.gfsh` shell script starts one Geode Locator and one Geode Server. +The `start-cluster.gfsh` shell script starts one Geode Locator and one Geode server. -A Locator is used by clients to discover and connect to servers in the cluster to manage its data. A Locator -is also used by new servers joining a cluster as a peer member, which allows the cluster to be elastically scaled-out -(or scaled-down, as needed). A Geode Server stores the data for the application. +A Locator is used by clients to discover and connect to servers in a cluster to manage its data. A Locator is also used +by new servers that join a cluster as peer members, which lets the cluster be elastically scaled out (or scaled down, +as needed). A Geode server stores the data for the application. -You can start as many Locators or Servers as necessary to meet the availability and load demands of your application. -Obviously, the more Locators and Servers your cluster has, the more resilient it is to failure. However, you should -size your cluster accordingly, based on your application's needs since there is overhead relative to the cluster size. +You can start as many Locators or servers as necessary to meet the availability and load demands of your application. +The more Locators and servers your cluster has, the more resilient it is to failure. However, you should size your +cluster accordingly, based on your application's needs, since there is overhead relative to the cluster size. -You will see output similar to the following when starting the Locator and Server: +You see output similar to the following when starting the Locator and server: .Starting the {geode-name} cluster +==== [source,txt] ---- gfsh>start locator --name=LocatorOne --log-level=config --classpath=/Users/jblum/pivdev/spring-boot-data-geode/apache-geode-extensions/build/libs/apache-geode-extensions-1.1.0.BUILD-SNAPSHOT.jar --J=-Dgemfire.security-manager=org.springframework.geode.security.TestSecurityManager --J=-Dgemfire.http-service-port=8080 @@ -462,10 +489,12 @@ Log File: /Users/jblum/pivdev/lab/ServerOne/ServerOne.log JVM Arguments: -Dgemfire.default.locators=10.99.199.24[10334] -Dgemfire.security-username=admin -Dgemfire.start-dev-rest-api=false -Dgemfire.security-password=******** -Dgemfire.use-cluster-configuration=true -Dgemfire.log-level=config -XX:OnOutOfMemoryError=kill -KILL %p -Dgemfire.launcher.registerSignalHandlers=true -Djava.awt.headless=true -Dsun.rmi.dgc.server.gcInterval=9223372036854775806 Class-Path: /Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-core-1.6.0.jar:/Users/jblum/pivdev/spring-boot-data-geode/apache-geode-extensions/build/libs/apache-geode-extensions-1.1.0.BUILD-SNAPSHOT.jar:/Users/jblum/pivdev/apache-geode-1.6.0/lib/geode-dependencies.jar ---- +==== Once the cluster has been started successfully, you can list the members: .List members of the cluster +==== [source,txt] ---- gfsh>list members @@ -474,46 +503,52 @@ gfsh>list members LocatorOne | 10.99.199.24(LocatorOne:14358:locator):1024 [Coordinator] ServerOne | 10.99.199.24(ServerOne:14401):1025 ---- +==== Currently, we have not defined any Regions in which to store our application's data: .No Application Regions +==== [source,txt] ---- gfsh>list regions No Regions Found ---- +==== -This is deliberate since we are going to let the application drive its schema structure, both on the client (app) -as well as on the server-side (cluster). More on this below. +This is deliberate, since we are going to let the application drive its schema structure, both on the client +(application) as well as on the server-side (cluster). We cover this in more detail later in this chapter. [[cloudfoundry-geode-cups]] ==== Creating a User-Provided Service -Now that we have PCF Dev and a small {geode-name} cluster up and running, it is time to create a User-Provided Service +Now that we have PCF Dev and a small {geode-name} cluster up and running, it is time to create a user-provided service to the external, standalone {geode-name} cluster that we started in <>. -As mentioned, PCF Dev offers the MySQL, Redis and RabbitMQ services out-of-the-box. However, to use {geode-name} in -the same capacity as you would {pcc-name} when running in a production-grade, PCF environment, you need to create a -User-Provided Service for the standalone {geode-name} cluster. +As mentioned, PCF Dev offers MySQL, Redis and RabbitMQ services (among others). However, to use {geode-name} in the same +capacity as you would {pcc-name} when running in a production-grade PCF environment, you need to create a user-provided +service for the standalone {geode-name} cluster. -To do so, execute the following `cf` CLI command: +To do so, run the following `cf` CLI command: .cf cups command +==== [source,txt] ---- $ cf cups -t "gemfire, cloudcache, database, pivotal" -p '' ---- +==== -NOTE: It is important that you specify the tags ("gemfire, cloudcache, database, pivotal") exactly as shown -in the `cf` CLI command above. +NOTE: It is important that you specify the tags (`gemfire`, `cloudcache`, `database`, `pivotal`) exactly as shown +in the preceding `cf` CLI command. -The argument passed to the `-p` command-line option is a JSON document (object) containing the "credentials" -for our User-Provided Service. +The argument passed to the `-p` command-line option is a JSON document (object) containing the credentials for our +user-provided service. The JSON object is as follows: .User-Provided Service Crendentials JSON +==== [source,json] ---- { @@ -522,27 +557,32 @@ The JSON object is as follows: "users": [{ "password": "", "roles": [ "cluster_operator" ], "username": "" }] } ---- +==== The complete `cf` CLI command would be similar to the following: .Example `cf cups` command +==== [source,txt] ---- cf cups apacheGeodeService -t "gemfire, cloudcache, database, pivotal" \ -p '{ "locators": [ "10.99.199.24[10334]" ], "urls": { "gfsh": "https://10.99.199.24/gemfire/v1" }, "users": [{ "password": "admin", "roles": [ "cluster_operator" ], "username": "admin" }] }' ---- +==== -We replaced the `` placeholder tag with the IP address of our external {geode-name} Locator. The IP address -can be found in the _Gfsh_ `start locator` output above. +We replaced the `` placeholder with the IP address of our standalone {geode-name} Locator. You can find +the IP address in the Gfsh `start locator` command output shown in the preceding example. -Additionally, the `` placeholder tag has been replaced with the default Locator port, `10334`, +Additionally, the `` placeholder has been replaced with the default Locator port, `10334`, Finally, we set the `username` and `password` accordingly. -TIP: Spring Boot for {geode-name} (SBDG) provides template files in the {docs-dir}/src/main/resources directory. +TIP: Spring Boot for {geode-name} (SBDG) provides template files in the `{docs-dir}/src/main/resources` directory. -Once the service has been created, you can query the details from the `cf` CLI: +Once the service has been created, you can query the details of the service from the `cf` CLI: +.Query the CF Dev Services +==== [source,txt] ---- $ cf services @@ -563,52 +603,59 @@ bound apps: name binding name status message boot-pcc-demo create succeeded ---- +==== You can also view the "apacheGeodeService" from Apps Manager, starting from the `Service` tab in your org and space: image::{images-dir}/pcfdev-appsmanager-org-space-services.png[] -By clicking on the "apacheGeodeService" service entry in the table you can get all the service details, -such the bound apps: +By clicking on the "apacheGeodeService" service entry in the table, you can get all the service details, such as +the bound apps: image::{images-dir}/pcfdev-appsmanager-org-space-service-boundapps.png[] -Configuration: +You can also view and set the configuration: image::{images-dir}/pcfdev-appsmanager-org-space-service-configuration.png[] -And so on. +This brief section did not cover all the capabilities of the Apps Manager. We suggest you explore its UI to see all +that is possible. -TIP: You can learn more about CUPS in the PCF documentation, -{pivotal-cloudfoundry-docs}/devguide/services/user-provided.html[here]. +TIP: You can learn more about CUPS in the +{pivotal-cloudfoundry-docs}/devguide/services/user-provided.html[PCF documentation]. [[cloudfoundry-geode-app]] -==== Push & Bind a Spring Boot application +==== Push and Bind a Spring Boot application -Now it is time to push a Spring Boot application to PCF Dev and bind the app to the "apacheGeodeService". +Now it is time to push a Spring Boot application to PCF Dev and bind the application to the `apacheGeodeService`. -Any Spring Boot `ClientCache` application using SBDG will do. For this example, we will use -the https://github.com/jxblum/PCCDemo/tree/sbdg-doc-ref[PCCDemo] application, available in _GitHub_. +Any Spring Boot `ClientCache` application that uses SBDG works for this purpose. For this example, we use the +https://github.com/jxblum/PCCDemo/tree/sbdg-doc-ref[PCCDemo] application, which is available in GitHub. -After cloning the project to your workstation, you must perform a build to produce the artifact to push to PCF Dev: +After cloning the project to your computer, you must run a build to produce the artifact to push to PCF Dev: -.Build the PCCDemo app +.Build the PCCDemo application +==== [source,txt] ---- $ mvn clean package ---- +==== -Then, you can push the app to PCF Dev with the following `cf` CLI command: +Then you can push the application to PCF Dev with the following `cf` CLI command: -.Push app to PCF Dev +.Push the application to PCF Dev +==== [source,txt] ---- $ cf push boot-pcc-demo -u none --no-start -p target/client-0.0.1-SNAPSHOT.jar ---- +==== -Once the app has been successfully deployed to PCF Dev, you can get app details: +Once the application has been successfully deployed to PCF Dev, you can get the application details: -.Details for deployed app +.Get details for the deployed application +==== [source,txt] ---- $ cf apps @@ -641,19 +688,23 @@ memory usage: 256M There are no running instances of this process. ---- +==== -You can either bind the PPCDemo app to the "apacheGeodeService" using the `cf` CLI command: +You can bind the PPCDemo application to the `apacheGeodeService` using the `cf` CLI command: -.Bind app to apacheGeodeService using CLI +.Bind application to `apacheGeodeService` using CLI +==== [source,txt] ---- cf bind-service boot-pcc-demo apacheGeodeService ---- +==== -Or, alternatively, you can create a YAML file (`manifest.yml` in `src/main/resources`) containing the -deployment descriptor: +Alternatively, you can create a YAML file (`manifest.yml` in `src/main/resources`) that contains +the deployment descriptor: -.Example YAML deployment descriptor file +.Example YAML deployment descriptor +==== [source,yml] ---- \--- @@ -667,62 +718,66 @@ applications: buildpacks: - https://github.com/cloudfoundry/java-buildpack.git ---- +==== -You can also use Apps Manager to view app details and un/bind additional services. Start by navigating to -the `App` tab under your org and space: +You can also use Apps Manager to view application details and bind and unbind additional services. +Start by navigating to the `App` tab under your org and space: image::{images-dir}/pcfdev-appsmanager-org-space-apps.png[] -From there, you can click on the desired app and navigate to the `Overview`: +From there, you can click on the desired application and navigate to the `Overview`: image::{images-dir}/pcfdev-appsmanager-org-space-app-overview.png[] -You can also review the app `Settings`. Specifically, we are looking at the configuration of the app once bound to -the "apacheGeodeService" as seen in the `VCAP_SERVICES` _Environment Variable_: +You can also review the application `Settings`. Specifically, we are looking at the configuration of the applicatinon +once it is bound to the `apacheGeodeService`, as seen in the `VCAP_SERVICES` environment variable: image::{images-dir}/pcfdev-appsmanager-org-space-app-settings-envvars.png[] -This JSON document structure is not unlike the configuration used to bind your Spring Boot, `ClientCache` application -to the {pcc-name} service when deploying the same app to {pcf-name}. This is actually very key if you want to minimize -the amount of boilerplate code and configuration changes when migrating between different CloudFoundry environments, -even https://www.cloudfoundry.org/[Open Source CloudFoundry]. +This JSON document structure is not unlike the configuration used to bind your Spring Boot `ClientCache` application +to the {pcc-name} service when deploying the same application to {pcf-name}. This is actually key if you want to +minimize the amount of boilerplate code and configuration changes when you migrate between different CloudFoundry +environments, even https://www.cloudfoundry.org/[Open Source CloudFoundry]. -Again, SBDG's entire goal is to simply the effort for you, as a developer, to build, run and manage your application, -in whatever context your application lands, even if it changes later. If you follow the steps in this documentation, -that goal will be realized. +Again, SBDG's goal is to simply the effort for you to build, run, and manage your application, in whatever context +your application lands, even if it changes later. If you follow the steps in this documentation, you can realize +that goal. [[cloudfoundry-geode-app-run]] ==== Running the Spring Boot application -All that is left to do now is run the app. +All that is left to do now is run the application. -You can start the PCCDemo app from the `cf` CLI using the following command: +You can start the PCCDemo application from the `cf` CLI by using the following command: -.Start the Spring Boot app +.Start the Spring Boot application +==== [source,txt] ---- $ cf start boot-pcc-demo ---- +==== -Alternatively, you can also start the app from Apps Manager. This is convenient since then you can tail and monitor -the application log file. +Alternatively, you can also start the application from Apps Manager. This is convenient, since you can then tail +and monitor the application log file. image::{images-dir}/pcfdev-appsmanager-org-space-app-logs.png[] -Once the app has started, you can click the https://boot-pcc-demo.dev.cfdev.sh/[VIEW APP] link +Once the application has started, you can click the https://boot-pcc-demo.dev.cfdev.sh/[VIEW APP] link in the upper right corner of the `APP` screen. image::{images-dir}/PCCDemo-app-screenshot.png[] You can navigate to any of the application Web Service, Controller endpoints. For example, if you know the ISBN -of a Book, you can access it from the Web browser: +of a book, you can access it from your Web browser: image::{images-dir}/PCCDemo-app-book-by-isbn-screenshot.png[] -You can also access the same data from the _Gfsh_ command-line tool. However, the first thing to observe -is that our application informed the cluster that it needed a Region called "Books": +You can also access the same data from the Gfsh command-line tool. However, the first thing to observe is that our +application informed the cluster that it needed a Region called `Books`: .Books Region +==== [source,txt] ---- gfsh>list regions @@ -744,10 +799,12 @@ Non-Default Attributes Shared By Hosting Members Region | size | 1 | data-policy | PARTITION ---- +==== -The PCCDemo app creates fake data on startup, which we can query in _Gfsh_ like so: +The PCCDemo app creates fake data on startup, which we can query in Gfsh: .Query Books +==== [source,txt] ---- gfsh>query --query="SELECT book.isbn, book.title FROM /Books book" @@ -759,18 +816,17 @@ Rows : 1 ------------- | --------------------- 1235432BMF342 | The Torment of Others ---- +==== [[cloudfoundry-geode-summary]] === Summary -There you have it! +The ability to deploy Spring Boot, {geode-name} `ClientCache` applications to {pcf-name} yet connect your application to +an externally managed, standalone {geode-name} cluster is powerful. -The ability to deploy Spring Boot, {geode-name} `ClientCache` applications to {pcf-name}, yet connect your app to an -externally managed, standalone {geode-name} cluster is powerful. +Indeed, this is a useful arrangement and stepping stone for many users as they begin their journey towards Cloud-Native +platforms such as {pcf-name} and using services such as {pcc-name}. -Indeed, this is will be a useful arrangement and stepping stone for many users as they begin their journey towards -Cloud-Native platforms like {pcf-name} and using services like {pcc-name}. - -Later, when the time comes and your need is real, you can simply migrate your Spring Boot applications to a fully -managed and production-grade {pcf-name} environment and SBDG will figure out what to do, leaving you to focus entirely -on your application. +Later, when you need to work with real (rather than sample) applications, you can migrate your Spring Boot applications +to a fully managed and production-grade {pcf-name} environment, and SBDG figures out what to do, leaving you to focus +entirely on your application. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-annotations.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-annotations.adoc index f520168c..8b563d39 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-annotations.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-annotations.adoc @@ -1,66 +1,66 @@ [[geode-auto-configuration-annotations]] == Auto-configuration vs. Annotation-based configuration :geode-name: {apache-geode-name} -:vmw-gemfire-name: VMware Tanzu GemFire -:vmw-tas-name: VMware Tanzu Application Service +:vmw-gemfire-name: {pivotal-gemfire-name} +:vmw-tas-name: {pivotal-cloudfoundry-name} -The question most often asked is, "_What Spring Data for {geode-name} (SDG) annotations can I use, or must I use, when -developing {geode-name} applications with Spring Boot?_" +The question most often asked is, "`What Spring Data for {geode-name} (SDG) annotations can I use, or must I use, when +developing {geode-name} applications with Spring Boot?`" -This section will answer this question and more. +This section answers this question and more. -Readers should refer to the complimentary sample, link:guides/boot-configuration.html[Spring Boot Auto-configuration for {geode-name}], -which showcases the _auto-configuration_ provided by Spring Boot for {geode-name} in action. +See the complementary sample, link:guides/boot-configuration.html[Spring Boot Auto-configuration for {geode-name}], +which shows the auto-configuration provided by Spring Boot for {geode-name} in action. [[geode-autoconfiguration-annotations-background]] === Background -To help answer this question, we must start by reviewing the complete collection of available Spring Data for {geode-name} -(SDG) annotations. These annotations are provided in the -{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/package-summary.html[org.springframework.data.gemfire.config.annotation] -package. Most of the pertinent annotations begin with `@Enable...`, except for the base annotations: +To help answer this question, you must start by reviewing the complete collection of available Spring Data for +{geode-name} (SDG) annotations. These annotations are provided in the +{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/package-summary.html[`org.springframework.data.gemfire.config.annotation`] +package. Most of the essential annotations begin with `@Enable...`, except for the base annotations: `@ClientCacheApplication`, `@PeerCacheApplication` and `@CacheServerApplication`. -By extension, Spring Boot for {geode-name} (SBDG) builds on SDG's Annotation-based configuration model to implement -_auto-configuration_ and apply Spring Boot's core concepts, like "_convention over configuration_", enabling -{geode-name} applications to be built with Spring Boot reliably, quickly and easily. +By extension, Spring Boot for {geode-name} (SBDG) builds on SDG's annotation-based configuration model to implement +auto-configuration and apply Spring Boot's core concepts, such as "`convention over configuration`", letting +{geode-name} applications be built with Spring Boot reliably, quickly, and easily. -SDG provides this Annotation-based configuration model to, first and foremost, give application developers "_choice_" -when building Spring applications using {geode-name}. SDG makes no assumptions about what application developers are -trying to do and fails fast anytime the configuration is ambiguous, giving users immediate feedback. +SDG provides this annotation-based configuration model to, first and foremost, give application developers "`choice`" +when building Spring applications with {geode-name}. SDG makes no assumptions about what application developers are +trying to create and fails fast anytime the configuration is ambiguous, giving users immediate feedback. -Second, SDG's Annotations were meant to get application developers up and running quickly and reliably with ease. SDG -accomplishes this by applying sensible defaults so application developers do not need to know, or even have to learn, -all the intricate configuration details and tooling provided by {geode-name} to accomplish simple tasks, e.g. build a +Second, SDG's annotations were meant to get application developers up and running quickly and reliably with ease. SDG +accomplishes this by applying sensible defaults so that application developers need not know, or even have to learn, all +the intricate configuration details and tooling provided by {geode-name} to accomplish simple tasks, such as building a prototype. -So, SDG is all about "choice" and SBDG is all about "convention". Together these frameworks provide application -developers with convenience and reliability to move quickly and easily. +So, SDG is all about "`choice`" and SBDG is all about "`convention`". Together these frameworks provide application +developers with convenience and ease to move quickly and reliably. -To learn more about the motivation behind SDG's Annotation-based configuration model, refer to the +To learn more about the motivation behind SDG's annotation-based configuration model, see the {spring-data-gemfire-docs-html}/#bootstrap-annotation-config-introduction[Reference Documentation]. [[geode-autoconfiguration-annotations-conventions]] === Conventions -Currently, SBDG provides _auto-configuration_ for the following features: +Currently, SBDG provides auto-configuration for the following features: * `ClientCache` * Caching with Spring's Cache Abstraction * Continuous Query -* Function Execution & Implementation +* Function Execution and Implementation * Logging * PDX * `GemfireTemplate` * Spring Data Repositories -* Security (Client/Server Auth & SSL) +* Security (Client/server auth and SSL) * Spring Session -Technically, this means the following SDG Annotations are not required to use the features above: +This means the following SDG annotations are not required to use the features above: * `@ClientCacheApplication` -* `@EnableGemfireCaching` (or by using Spring Framework's `@EnableCaching`) +* `@EnableGemfireCaching` (or by using Spring Framework's `@EnableCaching` annotation) * `@EnableContinuousQueries` * `@EnableGemfireFunctionExecutions` * `@EnableGemfireFunctions` @@ -71,9 +71,9 @@ Technically, this means the following SDG Annotations are not required to use th * `@EnableSsl` * `@EnableGemFireHttpSession` -Since SBDG auto-configures these features for you, then the above annotations are not strictly required. Typically, you -would only declare one of theses annotations when you want to "override" Spring Boot's conventions, expressed in -_auto-configuration_, and "customize" the behavior of the feature. +Since SBDG auto-configures these features for you, the above annotations are not strictly required. Typically, you +would only declare one of these annotations when you want to "`override`" Spring Boot's conventions, as expressed in +auto-configuration, and "`customize`" the behavior of the feature. [[geode-autoconfiguration-annotations-overriding]] === Overriding @@ -83,162 +83,167 @@ In this section, we cover a few examples to make the behavior when overriding mo [[geode-autoconfiguration-annotations-overriding-caches]] ==== Caches -By default, SBDG provides you with a `ClientCache` instance. Technically, SBDG accomplishes this by annotating -an auto-configuration class with `@ClientCacheApplication`, internally. +By default, SBDG provides you with a `ClientCache` instance. SBDG accomplishes this by annotating an auto-configuration +class with `@ClientCacheApplication` internally. -It is by convention that we assume most application developers' will be developing Spring Boot applications using -{geode-name} as "client" applications in {geode-name}'s client/server topology. This is especially true as users -migrate their applications to a managed cloud environment. +By convention, we assume most application developers' are developing Spring Boot applications by using {geode-name} +as "`client`" applications in {geode-name}'s client/server topology. This is especially true as users migrate their +applications to a managed cloud environment. -Still, users are free to "override" the default settings and declare their Spring applications to be actual peer `Cache` -members of a cluster, instead. - -For example: +Still, you can "`override`" the default settings (convention) and declare your Spring applications to be actual peer +`Cache` members (nodes) of a {geode-name} cluster, instead: +.Spring Boot, {geode-name} Peer `Cache` Application +==== [source,java] ---- @SpringBootApplication @CacheServerApplication -class MySpringBootPeerCacheServerApplication { } +class SpringBootApacheGeodePeerCacheServerApplication { } ---- +==== By declaring the `@CacheServerApplication` annotation, you effectively override the SBDG default. Therefore, SBDG -will not provide a `ClientCache` instance because you have informed SBDG of exactly what you want, i.e. a peer `Cache` -instance hosting an embedded `CacheServer` that allows client connections. +does not provide you with a `ClientCache` instance by default, because you have informed SBDG of exactly what you want: +a peer `Cache` instance hosting an embedded `CacheServer` that allows client connections. -However, you then might ask, "_Well, how do I customize the ClientCache instance when developing client applications -without explicitly declaring the @ClientCacheApplication annotation, then?_" +However, you then might ask, "`Well, how do I customize the `ClientCache` instance when developing client applications +without explicitly declaring the `@ClientCacheApplication` annotation?`" -First, you are entirely allowed to "customize" the `ClientCache` instance by explicitly declaring the -`@ClientCacheApplication` annotation in your Spring Boot application configuration, and set specific attributes -as needed. However, you should be aware that by explicitly declaring this annotation, or any of the other -auto-configured annotations by default, then you assume all the responsibility that comes with it since you have -effectively overridden the auto-configuration. One example of this is Security, which we touch on more below. +First, you can "`customize`" the `ClientCache` instance by explicitly declaring the `@ClientCacheApplication` annotation +in your Spring Boot application configuration and setting specific attributes as needed. However, you should be aware +that, by explicitly declaring this annotation, (or, by default, any of the other auto-configured annotations), you +assume all the responsibility that comes with it, since you have effectively overridden the auto-configuration. One +example of this is security, which we touch on more later. -The most ideal way to "customize" the configuration of any feature is by way of the well-known and documented -<>, specified in Spring Boot `application.properties` (the "convention"), -or by using a {spring-data-gemfire-docs-html}/#bootstrap-annotation-config-configurers[Configurer]. +The most ideal way to "`customize`" the configuration of any feature is by way of the well-known and documented +<>, specified in Spring Boot `application.properties` (the "`convention`"), +or by using a {spring-data-gemfire-docs-html}/#bootstrap-annotation-config-configurers[`Configurer`]. -See the <> for more details. +See the <> for more detail. [[geode-autoconfiguration-annotations-overriding-security]] ==== Security -Like the `@ClientCacheApplication` annotation, the `@EnableSecurity` annotation is not strictly required, not unless -you want to override and customize the defaults. +As with the `@ClientCacheApplication` annotation, the `@EnableSecurity` annotation is not strictly required, unless you +want to override and customize the defaults. -Outside a managed environment, the only Security configuration required is specifying a username and password. You do -this using the well-known and document SDG username/password properties in Spring Boot `application.properties`, -like so: +Outside a managed environment, the only security configuration required is specifying a username and password. You do +this by using the well-known and documented SDG username and password properties in Spring Boot `application.properties`: .Required Security Properties in a Non-Manage Envionment +==== [source,properties] ---- spring.data.gemfire.security.username=MyUser spring.data.gemfire.security.password=Secret ---- +==== -You do not need to explicitly declare the `@EnableSecurity` annotation just to specify Security configuration -(e.g. username/password). +You need not explicitly declare the `@EnableSecurity` annotation just to specify security configuration (such as +username and password). -Inside a managed environment, such as the {vmw-tas-name} (TAS) when using {vmw-gemfire-name}, SBDG is able to introspect -the environment and configure Security (Auth) completely without the need to specify any configuration, usernames -/ passwords, or otherwise. This is due in part because PCF supplies the security details in the VCAP environment -when the app is deployed to TAS and bound to services (e.g. {vmw-gemfire-name}). +Inside a managed environment, such as the {vmw-tas-name} when using {vmw-gemfire-name}, SBDG is able to introspect +the environment and configure security (auth) completely without the need to specify any configuration, usernames +and passwords, or otherwise. This is due, in part, because TAS supplies the security details in the VCAP environment +when the application is deployed to TAS and bound to services (such as {vmw-gemfire-name}). -So, in short, you do not need to explicitly declare the `@EnableSecurity` annotation (or the `@ClientCacheApplication` -for that matter). +So, in short, you need not explicitly declare the `@EnableSecurity` annotation (or `@ClientCacheApplication`). -However, if you do explicitly declare either the `@ClientCacheApplication` and/or `@EnableSecurity` annotations, -guess what, you are now responsible for this configuration and SBDG's _auto-configuration_ no longer applies. +However, if you do explicitly declare the `@ClientCacheApplication` or `@EnableSecurity` annotations, you are now +responsible for this configuration, and SBDG's auto-configuration no longer applies. -While explicitly declaring `@EnableSecurity` makes more sense when "overriding" the SBDG Security _auto-configuration_, +While explicitly declaring `@EnableSecurity` makes more sense when "`overriding`" the SBDG security auto-configuration, explicitly declaring the `@ClientCacheApplication` annotation most likely makes less sense with regard to its impact -on Security configuration. +on security configuration. -This is entirely due to the internals of {geode-name}, which in certain cases, like Security, not even Spring is able to -completely shield users from the nuances of {geode-name}'s configuration. +This is entirely due to the internals of {geode-name}, because, in certain cases (such as security), not even Spring +is able to completely shield you from the nuances of {geode-name}'s configuration. No framework can. -Both Auth and SSL must be configured before the cache instance (whether a `ClientCache` or a peer `Cache`, -it does not matter) is created. Technically, this is because Security is enabled/configured during the "construction" -of the cache. And, the cache pulls the configuration from JVM System properties that must be set before the cache -is constructed. +You must configure both auth and SSL before the cache instance (whether a `ClientCache` or a peer `Cache`) is created. +This is because security is enabled and configured during the "`construction`" of the cache. Also,, the cache pulls +the configuration from JVM System properties that must be set before the cache is constructed. -Structuring the "exact" order of the _auto-configuration_ classes provided by SBDG when the classes are triggered, -is no small feat. Therefore, it should come as no surprise to learn that the Security _auto-configuration_ classes -in SBDG must be triggered before the ClientCache _auto-configuration_ class, which is why a ClientCache instance cannot -"auto" authenticate properly in PCC when the `@ClientCacheApplication` is explicitly declared without some assistance -(i.e. you must also explicitly declare the `@EnableSecurity` annotation in this case since you overrode the -_auto-configuration_ of the cache, and, well, implicitly Security as well). +Structuring the "`exact`" order of the auto-configuration classes provided by SBDG when the classes are triggered, is no +small feat. Therefore, it should come as no surprise to learn that the security auto-configuration classes in SBDG must +be triggered before the `ClientCache` auto-configuration class, which is why a `ClientCache` instance cannot "`auto`" +authenticate properly in PCC when the `@ClientCacheApplication` is explicitly declared without some assistance. In other +words you must also explicitly declare the `@EnableSecurity` annotation in this case, since you overrode the +auto-configuration of the cache, and implicitly security, as well. -Again, this is due to the way Security (Auth) and SSL metadata must be supplied to {geode-name}. +Again, this is due to the way security (auth) and SSL metadata must be supplied to {geode-name} on startup. See the <> for more details. [[geode-autoconfiguration-annotations-extension]] === Extension -Most of the time, many of the other auto-configured annotations for CQ, Functions, PDX, Repositories, and so on, do not -need to ever be declared explicitly. +Most of the time, many of the other auto-configured annotations for CQ, Functions, PDX, Repositories, and so on need not +ever be declared explicitly. -Many of these features are enabled automatically by having SBDG or other libraries (e.g. Spring Session) -on the classpath, or are enabled based on other annotations applied to beans in the Spring `ApplicationContext`. +Many of these features are enabled automatically by having SBDG or other libraries (such as Spring Session) on +the application classpath or are enabled based on other annotations applied to beans in the Spring `ApplicationContext`. -Let's review a few examples. +We review a few examples in the following sections. [[geode-autoconfiguration-annotations-extension-caching]] ==== Caching -It is rarely, if ever, necessary to explicitly declare either the Spring Framework's `@EnableCaching`, or the SDG -specific `@EnableGemfireCaching` annotation, in Spring configuration when using SBDG. SBDG automatically "enables" -caching and configures the SDG `GemfireCacheManager` for you. +It is rarely, if ever, necessary to explicitly declare either the Spring Framework's `@EnableCaching` or the +SDG-specific `@EnableGemfireCaching` annotation in Spring configuration when you use SBDG. SBDG automatically +enables caching and configures the SDG `GemfireCacheManager` for you. -You simply only need to focus on which application service components are appropriate for caching: +You need only focus on which application service components are appropriate for caching: .Service Caching +==== [source,java] ---- @Service class CustomerService { - @Autowired - private CustomerRepository customerRepository; + @Autowired + private CustomerRepository customerRepository; - @Cacheable("CustomersByName") - public Customer findBy(String name) { - return customerRepository.findByName(name); - } + @Cacheable("CustomersByName") + public Customer findBy(String name) { + return customerRepository.findByName(name); + } } ---- +==== -Of course, it is necessary to create {geode-name} Regions backing the caches declared in your application service -components (e.g. "CustomersByName") using Spring's Caching Annotations (e.g. `@Cacheable), or alternatively, -JSR-107, JCache annotations (e.g. `@CacheResult`). +You need to create {geode-name} Regions that back the caches declared in your application service components +(`CustomersByName` in the preceding example) by using Spring's caching annotations (such as `@Cacheable`), +or alternatively, JSR-107 JCache annotations (such as `@CacheResult`). -You can do that by defining each Region explicitly, or more conveniently, you can simply use: +You can do that by defining each Region explicitly or, more conveniently, you can use the following approach: .Configuring Caches (Regions) +==== [source,java] ---- @SpringBootApplication @EnableCachingDefinedRegions class Application { } ---- +==== -`@EnableCachingDefinedRegions` is optional, provided for convenience, and complimentary to caching when used -rather than necessary. +`@EnableCachingDefinedRegions` is optional, provided for convenience, and complementary to caching when used rather than +being necessary. -See the <> for more details. +See the <> for more detail. [[geode-autoconfiguration-annotations-extension-cq]] ==== Continuous Query -It is rarely, if ever, necessary to explicitly declare the SDG `@EnableContinuousQueries` annotation. Instead, -you should be focused on defining your application queries and worrying less about the plumbing. +It is rarely, if ever, necessary to explicitly declare the SDG `@EnableContinuousQueries` annotation. Instead, you +should focus on defining your application queries and worry less about the plumbing. -For example: +Consider the following example: .Defining Queries for CQ +==== [source,java] ---- @Component @@ -257,97 +262,105 @@ public class TemperatureMonitor extends AbstractTemperatureEventPublisher { } } ---- +==== -Of course, {geode-name} CQ only applies to clients. +{geode-name} CQ applies only to clients. -See the <> for more details. +See the <> for more detail. [[geode-autoconfiguration-annotations-extension-functions]] ==== Functions -It is rarely, if ever, necessary to explicitly declare either the `@EnableGemfireFunctionExecutions` -or `@EnableGemfireFunctions` annotations. SBDG provides _auto-configuration_ for both Function implementations -and executions. You simply need to define the implementation: +You rarely, if ever, need to explicitly declare either the `@EnableGemfireFunctionExecutions` +or `@EnableGemfireFunctions` annotations. SBDG provides auto-configuration for both Function implementations +and executions. + +You need to define the implementation: .Function Implementation +==== [source,java] ---- @Component class GeodeFunctions { - @GemfireFunction - Object exampleFunction(Object arg) { - // ... - } + @GemfireFunction + Object exampleFunction(Object arg) { + // ... + } } ---- +==== -And then define the execution: +Then you need to define the execution: .Function Execution +==== [source,java] ---- @OnRegion(region = "Example") interface GeodeFunctionExecutions { - Object exampleFunction(Object arg); + Object exampleFunction(Object arg); + } ---- +==== -SBDG will automatically find, configure and register Function Implementations (POJOs) in {geode-name} as proper -`Functions` as well as create Executions proxies for the Interfaces which can then be injected into application service +SBDG automatically finds, configures, and registers Function implementations (POJOs) in {geode-name} as proper +`Functions` and creates execution proxies for the interfaces, which can then be injected into application service components to invoke the registered `Functions` without needing to explicitly declare the enabling annotations. -The application Function Implementations & Executions (Interfaces) should simply exist below the `@SpringBootApplication` -annotated main class. +The application Function implementations (POJOs) and executions (interfaces) should exist below +the `@SpringBootApplication` annotated main class. -See the <<[geode-functions,Reference Guide>> for more details. +See the <> for more detail. [[geode-autoconfiguration-annotations-extension-pdx]] ==== PDX -It is rarely, if ever, necessary to explicitly declare the `@EnablePdx` annotation since SBDG _auto-configures_ PDX -by default. SBDG automatically configures the SDG `MappingPdxSerializer` as the default `PdxSerializer` as well. +You rarely, if ever, need to explicitly declare the `@EnablePdx` annotation, since SBDG auto-configures PDX by default. +SBDG also automatically configures the SDG `MappingPdxSerializer` as the default `PdxSerializer`. -It is easy to customize the PDX configuration by setting the appropriate <> -(search for "PDX") in Spring Boot `application.properties`. +It is easy to customize the PDX configuration by setting the appropriate <> +(search for "`PDX`") in Spring Boot `application.properties`. -See the <> for more details. +See the <> for more detail. [[geode-autoconfiguration-annotations-extension-repositories]] ==== Spring Data Repositories -It is rarely, if ever, necessary to explicitly declare the `@EnableGemfireRepositories` annotation since SBDG -_auto-configures_ Spring Data (SD) _Repositories_ by default. +You rarely, if ever, need to explicitly declare the `@EnableGemfireRepositories` annotation, since SBDG auto-configures +Spring Data (SD) Repositories by default. -You simply only need to define your Repositories and get cranking: +You need only define your Repositories: .Customer's Repository +==== [source,java] ---- interface CustomerRepository extends CrudRepository { - Customer findByName(String name); + Customer findByName(String name); } ---- +==== -SBDG finds the _Repository_ interfaces defined in your application, proxies them, and registers them as beans -in the Spring `ApplicationContext`. The _Repositories_ may be injected into other application service components. +SBDG finds the Repository interfaces defined in your application, proxies them, and registers them as beans in +the Spring `ApplicationContext`. The Repositories can be injected into other application service components. -It is sometimes convenient to use the `@EnableEntityDefinedRegions` along with SD _Repositories_ to identify -the entities used by your application and define the Regions used by the SD _Repository_ infrastructure to persist -the entity's state. The `@EnableEntityDefinedRegions` annotation is optional, provided for convenience, -and complimentary to the `@EnableGemfireRepositories` annotation. +It is sometimes convenient to use the `@EnableEntityDefinedRegions` along with Spring Data Repositories to identify +the entities used by your application and define the Regions used by the Spring Data Repository infrastructure to +persist the entity's state. The `@EnableEntityDefinedRegions` annotation is optional, provided for convenience, +and complementary to the `@EnableGemfireRepositories` annotation. -See the <> for more details. +See the <> for more detail. [[geode-autoconfiguration-annotations-explicit]] === Explicit Configuration -Most of the other annotations provided in SDG are focused on particular application concerns, or enable certain -{geode-name} features, rather than being a necessity. - -A few examples include: +Most of the other annotations provided in SDG are focused on particular application concerns or enable certain +{geode-name} features, rather than being a necessity, including: * `@EnableAutoRegionLookup` * `@EnableBeanFactoryLocator` @@ -374,24 +387,21 @@ A few examples include: * `@EnableStatistics` * `@UseGemFireProperties` -None of these annotations are necessary and none are auto-configured by SBDG. They are simply at the -application developers disposal if and when needed. This also means none of these annotations are in conflict with -any SBDG _auto-configuration_. +None of these annotations are necessary and none are auto-configured by SBDG. They are at your disposal when and if you +need them. This also means that none of these annotations are in conflict with any SBDG auto-configuration. [[geode-autoconfiguration-annotations-summary]] === Summary -In conclusion, it is important to understand where SDG ends and SBDG begins. It all begins with the _auto-configuration_ -provided by SBDG out-of-the-box. +In conclusion, you need to understand where SDG ends and SBDG begins. It all begins with the auto-configuration +provided by SBDG. -If a feature is not covered by SBDG's _auto-configuration_, then you are responsible for enabling and configuring -the feature appropriately, as needed by your application (e.g. `@EnableRedisServer`). +If a feature or function is not covered by SBDG's auto-configuration, you are responsible for enabling and configuring +the feature appropriately, as needed by your application (for example, `@EnableRedisServer`). -In other cases, you might also want to explicitly declare a complimentary annotation (e.g. `@EnableEntityDefinedRegions`) -for convenience, since there is no convention or "opinion" provided by SBDG out-of-the-box. +In other cases, you might also want to explicitly declare a complimentary annotation +(such as `@EnableEntityDefinedRegions`) for convenience, since SBDG provides no convention or opinion. -In all remaining cases, it boils down to understanding how {geode-name} works under-the-hood. While we go to great -lengths to shield users from as many details as possible, it is not feasible or practical to address all matters, -e.g. cache creation and Security. - -Hope this section provided some relief and clarity. +In all remaining cases, it boils down to understanding how {geode-name} works under the hood. While we go to great +lengths to shield you from as many details as possible, it is not feasible or practical to address all matters, such as +cache creation and security. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-auto.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-auto.adoc index cf6643fe..e2b1d859 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-auto.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-auto.adoc @@ -4,13 +4,13 @@ The following Spring Framework, Spring Data for {geode-name} (SDG) and Spring Session for {geode-name} (SSDG) -_Annotations_ are implicitly declared by Spring Boot for {geode-name}'s (SBDG) _Auto-configuration_. +annotations are implicitly declared by Spring Boot for {geode-name}'s (SBDG) auto-configuration. * `@ClientCacheApplication` -* `@EnableGemfireCaching` (or alternatively, Spring Framework's `@EnableCaching`) +* `@EnableGemfireCaching` (alternatively, Spring Framework's `@EnableCaching`) * `@EnableContinuousQueries` -* `@EnableGemfireFunctionExecutions` * `@EnableGemfireFunctions` +* `@EnableGemfireFunctionExecutions` * `@EnableGemfireRepositories` * `@EnableLogging` * `@EnablePdx` @@ -18,237 +18,258 @@ _Annotations_ are implicitly declared by Spring Boot for {geode-name}'s (SBDG) _ * `@EnableSsl` * `@EnableGemFireHttpSession` -NOTE: This means you DO NOT need to explicitly declare any of these _Annotations_ on your `@SpringBootApplication` class -since they are provided by SBDG already. The only reason you would explicitly declare any of these _Annotations_ is if -you wanted to "_override_" Spring Boot's, and in particular, SBDG's _Auto-configuration_. Otherwise, it is unnecessary! +NOTE: This means that you need not explicitly declare any of these annotations on your `@SpringBootApplication` class, +since they are provided by SBDG already. The only reason you would explicitly declare any of these annotations is to +override Spring Boot's, and in particular, SBDG's auto-configuration. Otherwise, doing so is unnecessary. -TIP: You should read the chapter in Spring Boot's Reference Documentation on -{spring-boot-docs-html}/#using-boot-auto-configuration[Auto-configuration]. +TIP: You should read the chapter in Spring Boot's reference documentation on +{spring-boot-docs-html}/#using-boot-auto-configuration[auto-configuration]. -TIP: You should review the chapter in Spring Data for {geode-name}'s (SDG) Reference Documentation -on {spring-data-geode-docs-html}/#bootstrap-annotation-config[Annotation-based Configuration]. For a quick reference, -or an overview of Annotation-based Configuration, see {spring-data-geode-docs-html}/#bootstap-annotations-quickstart[here]. - -TIP: Refer to the corresponding Sample link:guides/boot-configuration.html[Guide] and {github-samples-url}/boot/configuration[Code] -to see Spring Boot Auto-configuration for {geode-name} in action! +TIP: You should review the chapter in Spring Data for {geode-name}'s (SDG) reference documentation +on {spring-data-geode-docs-html}/#bootstrap-annotation-config[annotation-based configuration]. For a quick reference +and overview of annotation-based configuration, see the +{spring-data-geode-docs-html}/#bootstap-annotations-quickstart[annotations quickstart]. +TIP: See the corresponding sample link:guides/boot-configuration.html[guide] and {github-samples-url}/boot/configuration[code] +to see Spring Boot auto-configuration for {geode-name} in action. [[geode-configuration-auto-customizing]] === Customizing Auto-configuration -You might ask how I can customize the _Auto-configuration_ provided by SBDG if I do not explicitly declare -the annotation? +You might ask, "`How do I customize the auto-configuration provided by SBDG if I do not explicitly declare +the annotation?`" -For example, you may want to customize the member's "_name_". You know that the +For example, you may want to customize the member's name. You know that the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html[`@ClientCacheApplication`] annotation provides the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableGemFireProperties.html#name--[`name`] attribute -so you can set the client member's "_name_". But SBDG has already implicitly declared the `@ClientCacheApplication` -annotation via _Auto-configuration_ on your behalf. What do you do? +so that you can set the client member's name. However, SBDG has already implicitly declared the `@ClientCacheApplication` +annotation through auto-configuration on your behalf. What do you do? -Well, SBDG supplies a few very useful _Annotations_ in this case. +In this case, SBDG supplies a few additional annotations. -For example, to set the (client or peer) member's name, you can use the `@UseMemberName` annotation, like so: +For example, to set the (client or peer) member's name, you can use the `@UseMemberName` annotation: .Setting the member's name using `@UseMemberName` +==== [source,java] ---- @SpringBootApplication @UseMemberName("MyMemberName") -class SpringBootClientCacheApplication { - ///... +class SpringBootApacheGeodeClientCacheApplication { + //... } ---- +==== Alternatively, you could set the `spring.application.name` or the `spring.data.gemfire.name` property in Spring Boot -`application.properties` +`application.properties`: .Setting the member's name using the `spring.application.name` property +==== [source,txt] ---- # Spring Boot application.properties spring.application.name = MyMemberName ---- - -Or: +==== .Setting the member's name using the `spring.data.gemfire.cache.name` property +==== [source,txt] ---- # Spring Boot application.properties spring.data.gemfire.cache.name = MyMemberName ---- +==== -In general, there are 3 ways to customize configuration, even in the context of SBDG's _Auto-configuration_: +NOTE: The `spring.data.gemfire.cache.name` property is an alias for the `spring.data.gemfire.name` property. Both +properties do the same thing (set the name of the client or peer member node). -1. Using {spring-boot-data-geode-javadoc}/org/springframework/geode/config/annotation/package-summary.html[Annotations] -provided by SBDG for common and popular concerns (e.g. naming client or peer members with `@UseMemberName`, or enabling -durable clients with `@EnableDurableClient`). +In general, there are three ways to customize configuration, even in the context of SBDG's auto-configuration: -2. Using well-known and documented {spring-data-geode-docs-html}/#bootstrap-annotation-config-properties[Properties] -(e.g. `spring.application.name`, or `spring.data.gemfire.name`, or `spring.data.gemfire.cache.name`). +* Using {spring-boot-data-geode-javadoc}/org/springframework/geode/config/annotation/package-summary.html[annotations] +provided by SBDG for common and popular concerns (such as naming client or peer members with the `@UseMemberName` +annotation or enabling durable clients with the `@EnableDurableClient` annotation). -3. Using {spring-data-geode-docs-html}/#bootstrap-annotation-config-configurers[Configurers] -(e.g. {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheConfigurer.html[`ClientCacheConfigurer`]). +* Using well-known and documented {spring-data-geode-docs-html}/#bootstrap-annotation-config-properties[properties] +(such as `spring.application.name`, or `spring.data.gemfire.name`, or `spring.data.gemfire.cache.name`). -TIP: For the complete list of _documented_ Properties, see <>. +* Using {spring-data-geode-docs-html}/#bootstrap-annotation-config-configurers[configurers] +(such as {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheConfigurer.html[`ClientCacheConfigurer`]). + +TIP: For the complete list of documented properties, see <>. [[geode-configuration-auto-disabling]] === Disabling Auto-configuration -Disabling Spring Boot _Auto-configuration_ is {spring-boot-docs-html}/#using-boot-disabling-specific-auto-configuration[explained] -in detail in Spring Boot's Reference Guide. +Spring Boot's reference documentation explains how to +{spring-boot-docs-html}/#using-boot-disabling-specific-auto-configuration[disable Spring Boot auto-configuration]. -Disabling SBDG _Auto-confiugration_ was also <> in detail. +<> also explains how to disable SBDG auto-configuration. -In a nutshell, if you want to disable any _Auto-configuration_ provided by either Spring Boot or SBDG, -then you can declare your intent in the `@SpringBootApplication` annotation, like so: +In a nutshell, if you want to disable any auto-configuration provided by either Spring Boot or SBDG, declare your intent +in the `@SpringBootApplication` annotation: .Disabling Specific Auto-configuration Classes +==== [source,java] ---- @SpringBootApplication( exclude = { DataSourceAutoConfiguration.class, PdxAutoConfiguration.class } ) -class SpringBootClientCacheApplication { +class SpringBootApacheGeodeClientCacheApplication { // ... } ---- +==== -WARNING: Make sure you understand what you are doing when you are "disabling" _Auto-configuration_. +CAUTION: Make sure you understand what you are doing when you disable auto-configuration. [[geode-configuration-auto-overriding]] === Overriding Auto-configuration -Overriding SBDG _Auto-configuration_ was <> in detail as well. +<> explains how to override SBDG auto-configuration. -In a nutshell, if you want to override the default _Auto-configuration_ provided by SBDG then you must annotate -your `@SpringBootApplication` class with your intent. +In a nutshell, if you want to override the default auto-configuration provided by SBDG, you must annotate your +`@SpringBootApplication` class with your intent. -For example, say you want to configure and bootstrap an {geode-name} `CacheServer` application (a peer; not a client), -then you would: +For example, suppose you want to configure and bootstrap an {geode-name} `CacheServer` application +(a peer, not a client): .Overriding the default `ClientCache` _Auto-Configuration_ by configuring & bootstrapping a `CacheServer` application +==== [source,java] ---- @SpringBootApplication @CacheServerApplication -class SpringBootCacheServerApplication { +class SpringBootApacheGeodeCacheServerApplication { // ... } ---- +==== -Even when you explicitly declare the `@ClientCacheApplication` annotation on your `@SpringBootApplication` class, -like so: +You can also explicitly declare the `@ClientCacheApplication` annotation on your `@SpringBootApplication` class: .Overriding by explicitly declaring `@ClientCacheApplication` +==== [source,java] ---- @SpringBootApplication @ClientCacheApplication -class SpringBootClientCacheApplication { +class SpringBootApacheGeodeClientCacheApplication { // ... } ---- +==== -You are overriding SBDG's _Auto-configuration_ of the `ClientCache` instance. As a result, you now have also implicitly -consented to being responsible for other aspects of the configuration (e.g. _Security_)! Why? +You are overriding SBDG's auto-configuration of the `ClientCache` instance. As a result, you have now also implicitly +consented to being responsible for other aspects of the configuration (such as security). -This is because in certain cases, like _Security_, certain aspects of _Security_ configuration (e.g. SSL) must be -configured before the cache instance is created. And, Spring Boot always applies user configuration before -_Auto-configuration_ partially to determine what needs to be auto-configured in the first place. +Why does that happen? -WARNING: Especially make sure you understand what you are doing when you are "overriding" _Auto-configuration_. +It happens because, in certain cases, such as security, certain aspects of security configuration (such as SSL) must be +configured before the cache instance is created. Also, Spring Boot always applies user configuration before +auto-configuration partially to determine what needs to be auto-configured in the first place. + +CAUTION: Make sure you understand what you are doing when you override auto-configuration. [[geode-configuration-auto-replacing]] === Replacing Auto-configuration -We will simply refer you to the Spring Boot Reference Guide on replacing _Auto-configuration_. -See {spring-boot-docs-html}/#using-boot-replacing-auto-configuration[here]. +See the Spring Boot reference documentation on +{spring-boot-docs-html}/#using-boot-replacing-auto-configuration[replacing auto-configuration]. [[geode-configuration-auto-explained]] -=== Auto-configuration Explained +=== Understanding Auto-configuration -This section covers the SBDG provided _Auto-configuration_ classes corresponding to the SDG _Annotations_ in more detail. +This section covers the SBDG provided auto-configuration classes that correspond to the SDG annotations in more detail. -To review the complete list of SBDG _Auto-confiugration_ classes, <>. +To review the complete list of SBDG auto-confiugration classes, see <>. [[geode-configuration-declarative-auto-configuration-clientcacheapplication]] ==== `@ClientCacheApplication` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/ClientCacheAutoConfiguration.html[`ClientCacheAutoConfiguration`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html[`@ClientCacheApplication`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/ClientCacheAutoConfiguration.html[`ClientCacheAutoConfiguration`] class +corresponds to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html[`@ClientCacheApplication`] annotation. -SBDG <> with the opinion that application developers will primarily be building {geode-name} -<> using Spring Boot. +As explained in <> SBDG starts with the opinion that application developers primarily build {geode-name} +<> by using Spring Boot. -Technically, this means building Spring Boot applications with an {geode-name} `ClientCache` instance connected to a -dedicated cluster of {geode-name} servers that manage the data as part of a +Technically, this means building Spring Boot applications with an {geode-name} `ClientCache` instance connected to +a dedicated cluster of {geode-name} servers that manage the data as part of a {apache-geode-docs}/topologies_and_comm/cs_configuration/chapter_overview.html[client/server] topology. -By way of example, this means you *do not* need to explicitly declare and annotate your `@SpringBootApplication` class -with SDG's `@ClientCacheApplication` annotation, like so: +By way of example, this means that you need not explicitly declare and annotate your `@SpringBootApplication` class +with SDG's `@ClientCacheApplication` annotation, as the following example shows: .Do Not Do This +==== [source,java] ---- @SpringBootApplication @ClientCacheApplication -class SpringBootClientCacheApplication { +class SpringBootApacheGeodeClientCacheApplication { // ... } ---- +==== -This is because SBDG's provided _Auto-configuration_ class is already meta-annotated with SDG's -`@ClientCacheApplication` annotation. Therefore, you simply need: +SBDG's provided auto-configuration class is already meta-annotated with SDG's `@ClientCacheApplication` annotation. +Therefore, you need only do: .Do This +==== [source,java] ---- @SpringBootApplication -class SpringBootClientCacheApplication { +class SpringBootApacheGeodeClientCacheApplication { // ... } ---- +==== -TIP: Refer to SDG's Reference Documentation for more details on {geode-name} -{spring-data-geode-docs-html}/#bootstrap-annotation-config-geode-applications[cache applications], +TIP: See SDG's reference documentation for more details on {geode-name} +{spring-data-geode-docs-html}/#bootstrap-annotation-config-geode-applications[cache applications] and {spring-data-geode-docs-html}/#bootstrap-annotation-config-client-server-applications[client/server applications] in particular. [[geode-configuration-declarative-auto-configuration-enablecaching]] ==== `@EnableGemfireCaching` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/CachingProviderAutoConfiguration.html[`CachingProviderAutoConfiguration`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/cache/config/EnableGemfireCaching.html[`@EnableGemfireCaching`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/CachingProviderAutoConfiguration.html[`CachingProviderAutoConfiguration`] class +corresponds to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/cache/config/EnableGemfireCaching.html[`@EnableGemfireCaching`] annotation. -If you simply used the core Spring Framework to configure {geode-name} as a _caching provider_ -in {spring-framework-docs}/integration.html#cache[Spring's Cache Abstraction], you would need to do this: +If you used the core Spring Framework to configure {geode-name} as a caching provider in +{spring-framework-docs}/integration.html#cache[Spring's Cache Abstraction], you need to: .Configuring caching using the Spring Framework +==== [source,java] ---- @SpringBootApplication @EnableCaching class CachingUsingApacheGeodeConfiguration { - @Bean - GemfireCacheManager cacheManager(GemFireCache cache) { + @Bean + GemfireCacheManager cacheManager(GemFireCache cache) { - GemfireCacheManager cacheManager = new GemfireCacheManager(); + GemfireCacheManager cacheManager = new GemfireCacheManager(); - cacheManager.setCache(cache); + cacheManager.setCache(cache); - return cacheManager; - } + return cacheManager; + } } ---- +==== -If you were using Spring Data for {geode-name}'s `@EnableGemfireCaching` annotation, then the above configuration -could be simplified to: +If you use Spring Data for {geode-name}'s `@EnableGemfireCaching` annotation, you can simplify the preceding +configuration: -.Configuring caching using Spring Data Geode +.Configuring caching using Spring Data for {geode-name} +==== [source,java] ---- @SpringBootApplication @@ -257,10 +278,12 @@ class CachingUsingApacheGeodeConfiguration { } ---- +==== -And, if you use SBDG, then you only need to do this: +Also, if you use SBDG, you need only do: -.Configuring caching using Spring Data Geode +.Configuring caching using Spring Boot for {geode-name} +==== [source,java] ---- @SpringBootApplication @@ -268,70 +291,77 @@ class CachingUsingApacheGeodeConfiguration { } ---- +==== -This allows you to focus on the areas in your application that would benefit from caching without having to enable -the plumbing. Simply demarcate the service methods in your application that are good candidates for caching: +This lets you focus on the areas in your application that would benefit from caching without having to enable the +plumbing. You can then demarcate the service methods in your application that are good candidates for caching: .Using caching in your application +==== [source,java] ---- @Service class CustomerService { - @Caching("CustomersByName") - Customer findBy(String name) { - // ... - } + @Caching("CustomersByName") + Customer findBy(String name) { + // ... + } } ---- +==== -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-enableautocontinuousqueies]] ==== `@EnableContinuousQueries` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/ContinuousQueryAutoConfiguration.html[`ContinuousQueryAutoConfiguration`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableContinuousQueries.html[`@EnableContinuousQueries`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/ContinuousQueryAutoConfiguration.html[`ContinuousQueryAutoConfiguration`] class +corresponds to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableContinuousQueries.html[`@EnableContinuousQueries`] annotation. -Without having to enable anything, you simply annotate your application (POJO) component method(s) with the SDG +Without having to enable anything, you can annotate your application (POJO) component method(s) with the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/listener/annotation/ContinuousQuery.html[`@ContinuousQuery`] -annotation to register a CQ and start receiving events. The method acts as a `CqEvent` handler, or in {geode-name}'s -case, the method would be an implementation of -{apache-geode-javadoc}/org/apache/geode/cache/query/CqListener.html[`CqListener`]. +annotation to register a CQ and start receiving events. The method acts as a `CqEvent` handler or, in {geode-name}'s +terminology, the method is an implementation of the +{apache-geode-javadoc}/org/apache/geode/cache/query/CqListener.html[`CqListener`] interface. .Declare application CQs +==== [source,java] ---- @Component class MyCustomerApplicationContinuousQueries { - @ContinuousQuery("SELECT customer.* FROM /Customers customers" - + " WHERE customer.getSentiment().name().equalsIgnoreCase('UNHAPPY')") - public void handleUnhappyCustomers(CqEvent event) { - // ... - } + @ContinuousQuery("SELECT customer.* " + + " FROM /Customers customers" + + " WHERE customer.getSentiment().name().equalsIgnoreCase('UNHAPPY')") + public void handleUnhappyCustomers(CqEvent event) { + // ... + } } ---- +==== -As shown above, you define the events you are interested in receiving by using a OQL query with a finely tuned query -predicate describing the events of interests and implement the handler method to process the events (e.g. apply a credit -to the customer's account and follow up in email). +As the preceding example shows, you can define the events you are interested in receiving by using an OQL query with a +finely tuned query predicate that describes the events of interests and implements the handler method to process the +events (such as applying a credit to the customer's account and following up in email). -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-enablefunctions]] ==== `@EnableGemfireFunctionExecutions` & `@EnableGemfireFunctions` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/FunctionExecutionAutoConfiguration.html[`FunctionExecutionAutoConfiguration`] class -corresponds to both the {spring-data-geode-javadoc}/org/springframework/data/gemfire/function/config/EnableGemfireFunctionExecutions.html[`@EnableGemfireFunctionExecutions`] -and {spring-data-geode-javadoc}/org/springframework/data/gemfire/function/config/EnableGemfireFunctions.html[`@EnableGemfireFunctions`] annotations. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/FunctionExecutionAutoConfiguration.html[`FunctionExecutionAutoConfiguration`] class +corresponds to both the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/function/config/EnableGemfireFunctionExecutions.html[`@EnableGemfireFunctionExecutions`] +and SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/function/config/EnableGemfireFunctions.html[`@EnableGemfireFunctions`] annotations. -Whether you need to {spring-data-geode-docs-html}/#function-execution[_execute_] a `Function` -or {spring-data-geode-docs-html}/#function-implementation[_implement_] a `Function`, SBDG will detect the Function -definition and auto-configure it appropriately for use in your Spring Boot application. You only need to define -the Function execution or implementation in a package below the main `@SpringBootApplication` class. +Whether you need to {spring-data-geode-docs-html}/#function-execution[execute] +or {spring-data-geode-docs-html}/#function-implementation[implement] a `Function`, SBDG detects the Function definition +and auto-configures it appropriately for use in your Spring Boot application. You need only define the Function +execution or implementation in a package below the main `@SpringBootApplication` class: .Declare a Function Execution +==== [source,java] ---- package example.app.functions; @@ -343,10 +373,12 @@ interface MyCustomerApplicationFunctions { } ---- +==== Then you can inject the Function execution into any application component and use it: .Use the Function +==== [source,java] ---- package example.app.service; @@ -355,7 +387,7 @@ package example.app.service; class CustomerService { @Autowired - private MyCustomerapplicationFunctions customerFunctions; + private MyCustomerApplicationFunctions customerFunctions; void analyzeCustomerSentiment(Customer customer) { @@ -367,44 +399,48 @@ class CustomerService { } } ---- +==== -The same pattern basically applies to Function implementations, except in the implementation case, SBDG "registers" -the Function implementation for use (i.e. to be called by a Function execution). +The same pattern basically applies to Function implementations, except in the implementation case, SBDG registers +the Function implementation for use (that is, to be called by a Function execution). -The point is, you are simply focusing on defining the logic required by your application, and not worrying about -how Functions are registered, called, etc. SBDG is handling this concern for you! +Doing so lets you focus on defining the logic required by your application and not worry about how Functions +are registered, called, and so on. SBDG handles this concern for you. NOTE: Function implementations are typically defined and registered on the server-side. -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-enablerepositories]] ==== `@EnableGemfireRepositories` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/GemFireRepositoriesAutoConfigurationRegistrar.html[`GemFireRepositoriesAutoConfigurationRegistrar`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.html[`@EnableGemfireRepositories`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/GemFireRepositoriesAutoConfigurationRegistrar.html[`GemFireRepositoriesAutoConfigurationRegistrar`] class +corresponds to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/repository/config/EnableGemfireRepositories.html[`@EnableGemfireRepositories`] annotation. -Like Functions, you are only concerned with the data access operations (e.g. basic CRUD and simple Queries) required by -your application to carry out its functions, not how to create and perform them (e.g. `Region.get(key)` -& `Region.put(key, obj)`) or execute (e.g. `Query.execute(arguments)`). +As with Functions, you need concern yourself only with the data access operations (such as basic CRUD and simple queries) +required by your application to carry out its operation, not with how to create and perform them (for example, +`Region.get(key)` and `Region.put(key, obj)`) or execute them (for example, `Query.execute(arguments)`). -Simply define your Spring Data Repository: +Start by defining your Spring Data Repository: .Define an application-specific Repository +==== [source,java] ---- package example.app.repo; interface CustomerRepository extends CrudRepository { - List findBySentimentEqualTo(Sentiment sentiment); + List findBySentimentEqualTo(Sentiment sentiment); } ---- +==== -And use it: +Then you can inject the Repository into an application component and use it: .Using the application-specific Repository +==== [source,java] ---- package example.app.sevice; @@ -412,108 +448,115 @@ package example.app.sevice; @Service class CustomerService { - @Autowired - private CustomerRepository repository; + @Autowired + private CustomerRepository repository; - public void processCustomersWithSentiment(Sentiment sentiment) { + public void processCustomersWithSentiment(Sentiment sentiment) { - this.repository.findBySentimentEqualTo(sentiment).forEach(customer -> { /* ... */ }); + this.repository.findBySentimentEqualTo(sentiment) + .forEach(customer -> { /* ... */ }); - // ... - } + // ... + } } ---- +==== - -Your application-specific _Repository_ simply needs to be declared in a package below the main `@SpringBootApplication` -class. Again, you are only focusing on the data access operations and queries required to carry out the functions +Your application-specific Repository simply needs to be declared in a package below the main `@SpringBootApplication` +class. Again, you are focusing only on the data access operations and queries required to carry out the operatinons of your application, nothing more. -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-enablelogging]] ==== `@EnableLogging` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/LoggingAutoConfiguration.html[`LoggingAutoConfiguration`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html[`@EnableLogging`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/LoggingAutoConfiguration.html[`LoggingAutoConfiguration`] class +corresponds to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html[`@EnableLogging`] annotation. Logging is an essential application concern to understand what is happening in the system along with when and where -the event occurred. As such, SBDG auto-configures logging for {geode-name} by default, using the default log-level, -"_config_". +the events occurred. By default, SBDG auto-configures logging for {geode-name} with the default log-level, "`config`". -If you wish to change an aspect of logging, such as the log-level, you would typically do this in Spring Boot -`application.properties`: +You can change any aspect of logging, such as the log-level, in Spring Boot `application.properties`: .Change the log-level for {geode-name} +==== [source,txt] ---- # Spring Boot application.properites. spring.data.gemfire.cache.log-level=debug ---- +==== -Other aspects may be configured as well, such as the log file size and disk space limits for the file system location -used to store the {geode-name} log files at runtime. +NOTE: The 'spring.data.gemfire.logging.level' property is an alias for `spring.data.gemfire.cache.log-level`. -Under-the-hood, {geode-name}'s logging is based on Log4j. Therefore, you can configure {geode-name} logging using any -logging provider (e.g. Logback) and configuration metadata appropriate for that logging provider so long as you supply -the necessary adapter between Log4j and whatever logging system you are using. For instance, if you include -`org.springframework.boot:spring-boot-starter-logging` then you will be using Logback and you will need the +You can also configure other aspects, such as the log file size and disk space limits for the filesystem location used +to store the {geode-name} log files at runtime. + +Under the hood, {geode-name}'s logging is based on Log4j. Therefore, you can configure {geode-name} logging to use any +logging provider (such as Logback) and configuration metadata appropriate for that logging provider so long as you +supply the necessary adapter between Log4j and whatever logging system you use. For instance, if you include +`org.springframework.boot:spring-boot-starter-logging`, you are using Logback and you will need the `org.apache.logging.log4j:log4j-to-slf4j` adapter. [[geode-configuration-declarative-auto-configuration-enablepdx]] ==== `@EnablePdx` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/PdxSerializationAutoConfiguration.html[`PdxSerializationAutoConfiguration`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html[`@EnablePdx`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/PdxSerializationAutoConfiguration.html[`PdxSerializationAutoConfiguration`] class +corresponds to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html[`@EnablePdx`] annotation. -Anytime you need to send an object over the network, overflow or persist an object to disk, then your application domain -object must be _serializable_. It would be painful to have to implement `java.io.Serializable` in everyone of your -application domain objects (e.g. `Customer`) that would potentially need to be serialized. +Any time you need to send an object over the network or overflow or persist an object to disk, your application domain +model object must be serializable. It would be painful to have to implement `java.io.Serializable` in every one of your +application domain model objects (such as `Customer`) that would potentially need to be serialized. -Furthermore, using _Java Serialization_ may not be ideal (e.g. the most portable or efficient) in all cases, -or even possible in other cases (e.g. when you are using a 3rd party library for which you have no control over). +Furthermore, using Java Serialization may not be ideal (it may not be the most portable or efficient solution) in all +cases or even possible in other cases (such as when you use a third party library over which you have no control). -In these situations, you need to be able to send your object anywhere without unduly requiring the class type -to be serializable as well as to exist on the classpath for every place it is sent. Indeed, the final destination -may not even be a Java application! This is where {geode-name} -{apache-geode-docs}/developing/data_serialization/gemfire_pdx_serialization.html[PDX Serialization] steps into help. +In these situations, you need to be able to send your object anywhere, anytime without unduly requiring the class type +to be serializable and exist on the classpath in every place it is sent. Indeed, the final destination may not even be +a Java application. This is where {geode-name} +{apache-geode-docs}/developing/data_serialization/gemfire_pdx_serialization.html[PDX Serialization] steps in to help. -However, you don't have to figure out how to configure PDX to identify the application class types that will need to be -serialized. You simply define your class type: +However, you need not figure out how to configure PDX to identify the application class types that needs to be +serialized. Instead, you can define your class type as follows: .Customer class +==== [source,java] ---- @Region("Customers") class Customer { - @Id - private Long id; + @Id + private Long id; - @Indexed - private String name; + @Indexed + private String name; - // ... + // ... } ---- +==== -And, SBDG's _Auto-configuration_ will handle the rest! +SBDG's auto-configuration handles the rest. -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-enablesecurity]] ==== `@EnableSecurity` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/ClientSecurityAutoConfiguration.html[`ClientSecurityAutoConfiguration`] class +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/ClientSecurityAutoConfiguration.html[`ClientSecurityAutoConfiguration`] class and {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/PeerSecurityAutoConfiguration.html[`PeerSecurityAutoConfiguration`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html[`@EnableSecurity`] annotation, but applies -Security, and specifically, Authentication/Authorization configuration for both clients and servers. +correspond to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html[`@EnableSecurity`] annotation, +but they apply security (specifically, authentication and authorization (auth) configuration) for both clients +and servers. Configuring your Spring Boot, {geode-name} `ClientCache` application to properly authenticate with a cluster of secure -{geode-name} servers is as simple as setting a _username_ and _password_ in Spring Boot `application.properties`: +{geode-name} servers is as simple as setting a username and a password in Spring Boot `application.properties`: .Supplying Authentication Credentials +==== [source,txt] ---- # Spring Boot application.properties @@ -521,45 +564,47 @@ Configuring your Spring Boot, {geode-name} `ClientCache` application to properly spring.data.gemfire.security.username=Batman spring.data.gemfire.security.password=r0b!n5ucks ---- +==== -NOTE: Authentication is even easier to configure in a managed environment like PCF when using PCC; -you don't have to do anything! +NOTE: Authentication is even easier to configure in a managed environment, such as PCF when using PCC. You need not do +anything. -Authorization is configured on the server-side and is made simple with SBDG and the help of https://shiro.apache.org/[Apache Shiro]. -Of course, this assumes you are using SBDG to configure and bootstrap your {geode-name} cluster in the first place, -which is <>, and made even easier with SBDG. +Authorization is configured on the server-side and is made simple with SBDG and the help of +https://shiro.apache.org/[Apache Shiro]. +Of course, this assumes you use SBDG to configure and bootstrap your {geode-name} cluster in the first place, which is +even easier with SBDG. See <>. -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-enablessl]] ==== `@EnableSsl` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/SslAutoConfiguration.html[`SslAutoConfiguration`] class -corresponds to the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html[`@EnableSsl`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/SslAutoConfiguration.html[`SslAutoConfiguration`] class +corresponds to the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html[`@EnableSsl`] annotation. -Configuring SSL for secure transport (TLS) between your Spring Boot, {geode-name} `ClientCache` application and the -cluster can be a real problematic task, especially to get correct from the start. So, it is something that SBDG makes -simple to do out-of-the-box. +Configuring SSL for secure transport (TLS) between your Spring Boot, {geode-name} `ClientCache` application and an +{geode-name} cluster can be a real problem, especially to get right from the start. So, it is something that SBDG +makes as simple as possible. -Simply supply a `trusted.keystore` file containing the certificates in a well-known location (e.g. root of your -application classpath) and SBDG's _Auto-configuration_ will kick in and handle of the rest. +You can supply a `trusted.keystore` file containing the certificates in a well-known location (such as the root of your +application classpath), and SBDG's auto-configuration steps in to handle the rest. -This is useful during development, but we highly recommend using a more secure procedure (e.g. integrating with a +This is useful during development, but we highly recommend using a more secure procedure (such as integrating with a secure credential store like LDAP, CredHub or Vault) when deploying your Spring Boot application to production. -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-enablespringsession]] ==== `@EnableGemFireHttpSession` -NOTE: The {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/SpringSessionAutoConfiguration.html[`SpringSessionAutoConfiguration`] class -corresponds to the {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/EnableSsl.html[`@EnableSsl`] annotation. +NOTE: The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/SpringSessionAutoConfiguration.html[`SpringSessionAutoConfiguration`] class +corresponds to the SSDG {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/EnableGemFireHttpSession.html[`@EnableGemFireHttpSession`] annotation. -Configuring {geode-name} to serve as the (HTTP) Session state caching provider using Spring Session is as simple as -including the correct starter, e.g. `spring-geode-starter-session`. +Configuring {geode-name} to serve as the (HTTP) session state caching provider by using Spring Session requires that +you only include the correct starter, that is `spring-geode-starter-session`: .Using Spring Session -[source,xml] +==== [subs="verbatim,attributes"] ---- @@ -568,47 +613,49 @@ including the correct starter, e.g. `spring-geode-starter-session`. {revnumber} ---- +==== -With Spring Session, and specifically Spring Session for {geode-name} (SSDG), on the classpath of your Spring Boot, -{geode-name} `ClientCache` Web application, you can manage your (HTTP) Session state with {geode-name}. No further -configuration is needed. SBDG _Auto-configuration_ detects Spring Session on the application classpath and does -the right thing. +With Spring Session -- and specifically Spring Session for {geode-name} (SSDG) -- on the classpath of your Spring Boot, +{geode-name} `ClientCache` Web application, you can manage your (HTTP) session state with {geode-name}. No further +configuration is needed. SBDG auto-configuration detects Spring Session on the application classpath and does the rest. -TIP: Refer to the <> for more details. +TIP: See <> for more details. [[geode-configuration-declarative-auto-configuration-regiontemplates]] ==== RegionTemplateAutoConfiguration The SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/RegionTemplateAutoConfiguration.html[`RegionTemplateAutoConfiguration`] class -has no corresponding SDG _Annotation_. However, the _Auto-configuration_ of a `GemfireTemplate` for every single -{geode-name} `Region` defined and declared in your Spring Boot application is supplied by SBDG never-the-less. +has no corresponding SDG annotation. However, the auto-configuration of a `GemfireTemplate` for every {geode-name} +`Region` defined and declared in your Spring Boot application is still supplied by SBDG. -For example, if you defined a Region using: +For example, you can define a Region by using: .Region definition using JavaConfig +==== [source,java] ---- @Configuration class GeodeConfiguration { + @Bean("Customers") + ClientRegionFactoryBean customersRegion(GemFireCache cache) { - @Bean("Customers") - ClientRegionFactoryBean customersRegion(GemFireCache cache) { + ClientRegionFactoryBean customersRegion = + new ClientRegionFactoryBean<>(); - ClientRegionFactoryBean customersRegion = - new ClientRegionFactoryBean<>(); + customersRegion.setCache(cache); + customersRegion.setShortcut(ClientRegionShortcut.PROXY); - customersRegion.setCache(cache); - customersRegion.setShortcut(ClientRegionShortcut.PROXY); - - return customersRegion; - } + return customersRegion; + } } ---- +==== -Alternatively, you could define the "_Customers_" Region using: +Alternatively, you can define the `Customers` Region by using `@EnableEntityDefinedRegions`: .Region definition using `@EnableEntityDefinedRegions` +==== [source,java] ---- @Configuration @@ -617,30 +664,33 @@ class GeodeConfiguration { } ---- +==== -Then, SBDG will supply a `GemfireTemplate` instance that you can use to perform low-level, data access operations -(indirectly) on the "_Customers_" Region: +Then SBDG supplies a `GemfireTemplate` instance that you can use to perform low-level data-access operations +(indirectly) on the `Customers` Region: .Use the `GemfireTemplate` to access the "Customers" Region +==== [source,java] ---- @Repository class CustomersDao { - @Autowired - @Qualifier("customersTemplate") - private GemfireTemplate customersTemplate; + @Autowired + @Qualifier("customersTemplate") + private GemfireTemplate customersTemplate; - Customer findById(Long id) { - return this.customerTemplate.get(id); - } + Customer findById(Long id) { + return this.customerTemplate.get(id); + } } ---- +==== -You do not need to explicitly configure `GemfireTemplates` for each Region you need to have low-level data access to -(e.g. such as when you are not using the Spring Data Repository abstraction). +You need not explicitly configure `GemfireTemplates` for each Region to which you need low-level data access (such as +when you are not using the Spring Data Repository abstraction). -Be careful to "qualify" the `GemfireTemplate` for the Region you need data access to, especially given that you will -probably have more than 1 Region defined in your Spring Boot application. +Be careful to qualify the `GemfireTemplate` for the Region to which you need data access, especially given that you +probably have more than one Region defined in your Spring Boot application. -TIP: Refer to the <> for more details. +TIP: See <> for more details. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-declarative.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-declarative.adoc index 60cf9c38..c7bfc7b6 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-declarative.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-declarative.adoc @@ -3,64 +3,65 @@ :geode-name: {apache-geode-name} -The primary purpose of any software development framework is to help you be _productive_ as _quickly_ and as _easily_ -as possible, and to do so in a _reliable_ manner. +The primary purpose of any software development framework is to help you be productive as quickly and as easily as +possible and to do so in a reliable manner. As application developers, we want a framework to provide constructs that are both intuitive and familiar so that their -behaviors are boringly predictable. This provided convenience not only helps you hit the ground running in the right -direction sooner but increases your focus on the application domain so you are able to better understand the problem -you are trying to solve in the first place. Once the problem domain is well understood, you are more apt to make -informed decisions about the design, which leads to better outcomes, faster. +behaviors are predictable. This provided convenience not only helps you hit the ground running in the right direction +sooner but increases your focus on the application domain so that you can better understand the problem you are trying +to solve in the first place. Once the problem domain is well understood, you are more apt to make informed decisions +about the design, which leads to better outcomes, faster. -This is exactly what Spring Boot's _auto-configuration_ provides for you... enabling features, services and supporting -infrastructure for Spring applications in a loosely integrated way by using conventions (e.g. classpath) that ultimately -helps you keep your attention and focus on solving the problem at hand and not on the plumbing. +This is exactly what Spring Boot's auto-configuration provides for you. It enables features, functionality, services +and supporting infrastructure for Spring applications in a loosely integrated way by using conventions (such as the +classpath) that ultimately help you keep your attention and focus on solving the problem at hand and not on the plumbing. -For example, if you are building a Web application, simply include the `org.springframework.boot:spring-boot-starter-web` -dependency on your application classpath. Not only will Spring Boot enable you to build Spring Web MVC Controllers -appropriate to your application UC (your responsibility), but will also bootstrap your Web app in an embedded Servlet -Container on startup (Boot's responsibility). +For example, if you are building a web application, you can include the `org.springframework.boot:spring-boot-starter-web` +dependency on your application classpath. Not only does Spring Boot enable you to build Spring Web MVC Controllers +appropriate to your application UC (your responsibility), but it also bootstraps your web application in an embedded +Servlet container on startup (Spring Boot's responsibility). -This saves you from having to handle many low-level, repetitive and tedious development tasks that are highly error-prone -when you are simply trying to solve problems. You don't have to care how the plumbing works until you do. And, when you -do, you will be better informed and prepared to do so. +This saves you from having to handle many low-level, repetitive, and tedious development tasks that are error-prone and +easy to get wrong when you are trying to solve problems. You need not care how the plumbing works until you need to +customize something. And, when you do, you are better informed and prepared to do so. -It is also equally essential that frameworks, like Spring Boot, get out of the way quickly when application requirements -diverge from the provided defaults. The is the beautiful and powerful thing about Spring Boot and why it is second -to none in its class. +It is also equally essential that frameworks, such as Spring Boot, get out of the way quickly when application +requirements diverge from the provided defaults. This is the beautiful and powerful thing about Spring Boot and why +it is second to none in its class. -Still, _auto-configuration_ does not solve every problem all the time. Therefore, you will need to use declarative -configuration in some cases, whether expressed as bean definitions, in properties or by some other means. This is so -frameworks don't leave things to chance, especially when they are ambiguous. The framework simply gives you a choice. +Still, auto-configuration does not solve every problem all the time. Therefore, you need to use declarative +configuration in some cases, whether expressed as bean definitions, in properties, or by some other means. This is so +that frameworks do not leave things to chance, especially when things are ambiguous. The framework gives you choice. -Now, that we explained the motivation behind this chapter, let's outline what we will discuss: +Keeping our goals in mind, this chapter: -* Refer you to the SDG _Annotations_ covered by SBDG's _Auto-configuration_ -* List all SDG _Annotations_ not covered by SBDG's _Auto-configuration_ -* Cover the SBDG, SSDG and SDG _Annotations_ that must be declared explicitly and that provide the most value -and productivity when getting started using either {geode-name} in Spring [Boot] applications. +* Refers you to the SDG annotations covered by SBDG's auto-configuration. +* Lists all SDG annotations not covered by SBDG's auto-configuration. +* Covers the SBDG, SSDG and SDG annotations that you must explicitly declare and that provide the most value +and productivity when getting started with {geode-name} in Spring [Boot] applications. NOTE: SDG refers to {spring-data-geode-website}[Spring Data for {geode-name}]. SSDG refers to -{spring-session-data-gemfire-website}[Spring Session for {geode-name}] and SBDG refers to -_Spring Boot for {geode-name}_, this project. +{spring-session-data-gemfire-website}[Spring Session for {geode-name}]. SBDG refers to +Spring Boot for {geode-name} (this project). -TIP: The list of SDG _Annotations_ covered by SBDG's _Auto-configuration_ is discussed in detail in the <>, -in the section, <>. +TIP: The list of SDG annotations covered by SBDG's auto-configuration is discussed in detail in the <>, +in the <> section. -To be absolutely clear about which SDG Annotations we are referring to, we mean the SDG _Annotations_ in the package: -{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/package-summary.html[org.springframework.data.gemfire.config.annotation]. +To be absolutely clear about which SDG annotations we are referring to, we mean the SDG annotations in the +{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/package-summary.html[`org.springframework.data.gemfire.config.annotation`] +package. -Additionally, in subsequent sections, we will cover which _Annotations_ are added by SBDG. +In subsequent sections, we also cover which annotations are added by SBDG. [[geode-configuration-declarative-auto-configuration]] === Auto-configuration -_Auto-configuration_ was explained in complete detail in the chapter, "<>". +We explained auto-configuration in detail in the "<>" chapter. [[geode-configuration-declarative-annotations]] -=== Annotations not covered by Auto-configuration +=== Annotations Not Covered by Auto-configuration -The following SDG _Annotations_ are not implicitly applied by SBDG's _Auto-configuration_: +The following SDG annotations are not implicitly applied by SBDG's auto-configuration: * `@EnableAutoRegionLookup` * `@EnableBeanFactoryLocator` @@ -88,9 +89,10 @@ The following SDG _Annotations_ are not implicitly applied by SBDG's _Auto-confi * `@EnableStatistics` * `@UseGemFireProperties` -TIP: This was also covered <>. +NOTE: This content was also covered in <>. -Part of the reason for this is because several of the _Annotations_ are server-specific: +One reason SBDG does not provide auto-configuration for several of the annotations is because the annotations +are server-specific: * `@EnableCacheServer(s)` * `@EnableGatewayReceiver` @@ -101,132 +103,140 @@ Part of the reason for this is because several of the _Annotations_ are server-s * `@EnableMemcachedServer` * `@EnableRedisServer` -And, we <> that SBDG is opinionated about providing a `ClientCache` -instance out-of-the-box. +Also, we <> that SBDG is opinionated about providing a `ClientCache` +instance. -Other _Annotations_ are driven by need, for example: +Other annotations are driven by need, including: -* `@EnableAutoRegionLookup` & `@EnableBeanFactoryLocator` - really only useful when mixing configuration metadata -formats, e.g. Spring config with {geode-name} `cache.xml`. This is usually only the case if you have legacy `cache.xml` -config to begin with, otherwise, don't do this! -* `@EnableCompression` - requires the Snappy Compression Library on your application classpath. -* `@EnableDiskStore(s)` - only used for overflow and persistence. -* `@EnableOffHeap` - enables data to be stored in main memory, which is only useful when your application data -(i.e. Objects stored in {geode-name}) are generally uniform in size. -* `@EnableGemFireAsLastResource` - only needed in the context of JTA Transactions. -* `@EnableStatistics` - useful if you need runtime metrics, however enabling statistics gathering does consume -considerable system resources (e.g. CPU & Memory). +* `@EnableAutoRegionLookup` and `@EnableBeanFactoryLocator`: Really useful only when mixing configuration metadata +formats, such as Spring config with {geode-name} `cache.xml`. This is usually the case only if you have legacy +`cache.xml` config to begin with. Otherwise, you should not use these annotations. +* `@EnableCompression`: Requires the Snappy Compression Library to be on your application classpath. +* `@EnableDiskStore(s)` Used only for overflow and persistence. +* `@EnableOffHeap`: Enables data to be stored in main memory, which is useful only when your application data (that is, +objects stored in {geode-name}) are generally uniform in size. +* `@EnableGemFireAsLastResource`: Needed only in the context of JTA Transactions. +* `@EnableStatistics`: Useful if you need runtime metrics. However, enabling statistics gathering does consume +considerable system resources (CPU & Memory). -While still other _Annotations_ require more careful planning, for example: +Still other annotations require more careful planning: * `@EnableEviction` * `@EnableExpiration` * `@EnableIndexing` -One in particular is used exclusively for Unit Testing: +One annotation is used exclusively for unit testing: * `@EnableGemFireMockObjects` -The bottom-line is, a framework should not _Auto-configure_ every possible feature, especially when the features -consume additional system resources, or requires more careful planning as determined by the use case. +The bottom-line is that a framework should not auto-configure every possible feature, especially when the features +consume additional system resources or require more careful planning (as determined by the use case). -Still, all of these _Annotations_ are available for the application developer to use when needed. +However, all of these annotations are available for the application developer to use when needed. [[geode-configuration-declarative-annotations-productivity]] === Productivity Annotations -This section calls out the _Annotations_ we believe to be most beneficial for your application development purposes when -using {geode-name} in Spring Boot applications. +This section calls out the annotations we believe to be most beneficial for your application development purposes when +using {geode-name} in Spring [Boot] applications. [[geode-configuration-declarative-annotations-productivity-enableclusteraware]] ==== `@EnableClusterAware` (SBDG) -The `@EnableClusterAware` annotation is arguably the most powerful and valuable _Annotation_ in the set of _Annotations_! - -When you annotate your main `@SpringBootApplication` class with `@EnableClusterAware`: +The `@EnableClusterAware` annotation is arguably the most powerful and valuable annotation. .Declaring `@EnableClusterAware` +==== [source,java] ---- @SpringBootApplication @EnableClusterAware class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -Your Spring Boot, {geode-name} `ClientCache` application is able to seamlessly switch between client/server -and local-only topologies with no code or configuration changes, regardless of the runtime environment -(e.g. local/standalone vs. cloud-managed environments). +When you annotate your main `@SpringBootApplication` class with `@EnableClusterAware`, your Spring Boot, {geode-name} +`ClientCache` application is able to seamlessly switch between client/server and local-only topologies with no code +or configuration changes, regardless of the runtime environment (such as local/standalone versus cloud-managed +environments). -When a cluster of {geode-name} servers is detected, the client application will send and receive data to and from the -cluster. If a cluster is not available, then the client automatically switches to storing data locally on the client -using `LOCAL` Regions. +When a cluster of {geode-name} servers is detected, the client application sends and receives data to and from the +{geode-name} cluster. If a cluster is not available, the client automatically switches to storing data locally on the +client by using `LOCAL` Regions. Additionally, the `@EnableClusterAware` annotation is meta-annotated with SDG's -{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html[`@EnableClusterConfiguration`] annotation. +{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html[`@EnableClusterConfiguration`] +annotation. -The `@EnableClusterConfiguration` enables configuration metadata defined on the client (e.g. Region and Index -definitions) as needed by the application based on requirements and use cases, to be sent to the cluster of servers. -If those schema objects are not already present, they will be created by the servers in the cluster in such a way that -the servers will remember the configuration on restart as well as provide the configuration to new servers joining -the cluster when scaling out. This feature is careful not to stomp on any existing Region or Index objects already -present on the servers, particularly since you may already have data stored in the Regions. +The `@EnableClusterConfiguration` annotation lets configuration metadata defined on the client (such as Region and Index +definitions, as needed by the application based on requirements and use cases) be sent to the cluster of servers. If +those schema objects are not already present, they are created by the servers in the cluster in such a way that the +servers remember the configuration on restart as well as provide the configuration to new servers that join the cluster +when it is scaled out. This feature is careful not to stomp on any existing Region or Index objects already defined on +the servers, particularly since you may already have critical data stored in the Regions. -The primary motivation behind the `@EnableClusterAware` annotation is to allow you to switch environments with very -little effort. It is a very common development practice to debug and test your application locally, in your IDE, -then push up to a production-like environment for more rigorous integration testing. +The primary motivation for the `@EnableClusterAware` annotation is to let you switch environments with minimal effort. +It is a common development practice to debug and test your application locally (in your IDE) and then push up to a +production-like (staging) environment for more rigorous integration testing. -By default, the configuration metadata is sent to the cluster using a non-secure HTTP connection. Using HTTPS, changing -host and port, and configuring the data management policy used by the servers when creating Regions is all configurable. +By default, the configuration metadata is sent to the cluster by using a non-secure HTTP connection. However, you can +configure HTTPS, change the host and port, and configure the data management policy used by the servers when creating +Regions. -TIP: Refer to the section in the SDG Reference Guide on +TIP: See the section in the SDG reference documentation on {spring-data-geode-docs-html}/#bootstrap-annotation-config-cluster[Configuring Cluster Configuration Push] for more details. [[geode-configuration-declarative-annotations-productivity-enableclusteraware-strictmatch]] ===== @EnableClusterAware, strictMatch -The `strictMatch` attribute has been added to the `@EnableClusterAware` annotation to enable _fail-fast_ behavior. +The `strictMatch` attribute has been added to the `@EnableClusterAware` annotation to enable fail-fast behavior. `strictMatch` is set to `false` by default. -Essentially, when you set `strictMatch` to `true`, then you are saying that your Spring Boot, {geode-name} `ClientCache` -application requires an {geode-name} cluster to exist, i.e. the application requires a client/server topology -to operate and that the application should fail to start and run if a cluster is not present. The application -should not startup in a LOCAL-only capacity. +Essentially, when you set `strictMatch` to `true`, your Spring Boot, {geode-name} `ClientCache` application requires +an {geode-name} cluster to exist. That is, the application requires a client/server topology to operate, and the +application should fail to start if a cluster is not present. The application should not startup in a local-only +capacity. -When `strictMatch` is set to `true` and an {geode-name} cluster is not present, then your Spring Boot, {geode-name} -`ClientCache` application will fail to start with a `ClusterNotFoundException`. The application will not attempt to -startup in a LOCAL-only capacity. +When `strictMatch` is set to `true` and an {geode-name} cluster is not available, your Spring Boot, {geode-name} +`ClientCache` application fails to start with a `ClusterNotFoundException`. The application does not attempt to +start in a local-only capacity. -You can explicitly set the `strictMatch` attribute programmatically using the `@EnableClusterAware` annotation: +You can explicitly set the `strictMatch` attribute programmatically by using the `@EnableClusterAware` annotation: .Set `@EnableClusterAware.strictMatch` +==== [source,java] ---- @SpringBootApplication @EnableClusterAware(strictMatch = true) class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -Alternatively, you can set `strictMatch` using the corresponding property in Spring Boot `application.properties`: +Alternatively, you can set `strictMatch` attribute by using the corresponding property +in Spring Boot `application.properties`: .Set `strictMatch` using a property +==== [source,properties] ---- # Spring Boot application.properties spring.boot.data.gemfire.cluster.condition.match.strict=true ---- +==== -This is convenient when you need to apply this configuration setting conditionally based on a Spring Profile. +This is convenient when you need to apply this configuration setting conditionally, based on a Spring profile. -When you adjust the _log-level_ of the `org.springframework.geode.config.annotation.ClusterAwareConfiguration` _Logger_ -to `INFO`, then you will get more details from the `@EnableClusterAware` functionality when applying the logic -to determine the presence of an {geode-name} cluster, such as which explicitly or implicitly configured connections -were successful. +When you adjust the log level of the `org.springframework.geode.config.annotation.ClusterAwareConfiguration` logger +to `INFO`, you get more details from the `@EnableClusterAware` functionality when applying the logic to determine +the presence of an {geode-name} cluster, such as which explicitly or implicitly configured connections were successful. -For example: +The following example shows typical output: .`@EnableClusterAware` INFO log output +==== [source,txt] ---- 2021-01-20 14:02:28,740 INFO fig.annotation.ClusterAwareConfiguration: 476 - Failed to connect to localhost[40404] @@ -235,122 +245,139 @@ For example: 2021-01-20 14:02:28,746 INFO fig.annotation.ClusterAwareConfiguration: 576 - Cluster was found; Auto-configuration made [1] successful connection(s); 2021-01-20 14:02:28,746 INFO fig.annotation.ClusterAwareConfiguration: 586 - Spring Boot application is running in a client/server topology, using a standalone Apache Geode-based cluster ---- +==== -NOTE: An attempt is always made to connect to `localhost` on the default _Locator_ port, `10334`, -as well as the default `CacheServer` port, `40404`. +NOTE: An attempt is always made to connect to `localhost` on the default `Locator` port, `10334`, and the default +`CacheServer` port, `40404`. -TIP: You can force a successful match always by setting the `spring.boot.data.gemfire.cluster.condition.match` property +TIP: You can force a successful match by setting the `spring.boot.data.gemfire.cluster.condition.match` property to `true` in Spring Boot `application.properties`. This is sometimes useful for testing purposes. [[geode-configuration-declarative-annotations-productivity-regions]] -==== `@EnableCachingDefinedRegions`, `@EnableClusterDefinedRegions` & `@EnableEntityDefinedRegions` (SDG) +==== `@EnableCachingDefinedRegions`, `@EnableClusterDefinedRegions` and `@EnableEntityDefinedRegions` (SDG) -These _Annotations_ are used to create Regions in the cache to manage your application data. +These annotations are used to create Regions in the cache to manage your application data. -Of course, you can create Regions using Java configuration and the Spring API as follows: +You can create Regions by using Java configuration and the Spring API as follows: .Creating a Region with Spring JavaConfig +==== [source,java] ---- @Configuration class GeodeConfiguration { - @Bean("Customers") - ClientRegionFactoryBean customersRegion(GemFireCache cache) { + @Bean("Customers") + ClientRegionFactoryBean customersRegion(GemFireCache cache) { - ClientRegionFactoryBean customers = new ClientRegionFactoryBean<>(); + ClientRegionFactoryBean customers = + new ClientRegionFactoryBean<>(); - customers.setCache(cache); - customers.setShortcut(ClientRegionShortcut.PROXY); + customers.setCache(cache); + customers.setShortcut(ClientRegionShortcut.PROXY); - return customers; - } + return customers; + } } ---- +==== -Or XML: +You can do the same in XML: .Creating a client Region using Spring XML +==== [source,xml] ---- ---- +==== -However, using the provided Annotations is far easier, especially during development when the complete Region -configuration may be unknown and you simply want to create a Region to persist your application data and move on. +However, using the provided annotations is far easier, especially during development, when the complete Region +configuration may be unknown and you want only to create a Region to persist your application data and move on. [[geode-configuration-declarative-annotations-productivity-regions-enablecachingdefined]] ===== `@EnableCachingDefinedRegions` The `@EnableCachingDefinedRegions` annotation is used when you have application components registered in the Spring -Container that are annotated with Spring or JSR-107, JCache {spring-framework-docs}/integration.html#cache-jsr-107[annotations]. +container that are annotated with Spring or JSR-107 JCache +{spring-framework-docs}/integration.html#cache-jsr-107[annotations]. -Caches that identified by name in the caching annotations are used to create Regions holding the data you want cached. +Caches that are identified by name in the caching annotations are used to create Regions that hold the data +you want cached. -For example, given: +Consider the following example: .Defining Regions based on Spring or JSR-107 JCache Annotations +==== [source,java] ---- @Service class CustomerService { - @Cacheable(cacheNames = "CustomersByAccountNumber", key = "#account.number") - Customer findBy(Account account) { - // ... - } + @Cacheable(cacheNames = "CustomersByAccountNumber", key = "#account.number") + Customer findBy(Account account) { + // ... + } } ---- +==== -When your main `@SpringBootApplication` class is annotated with `@EnableCachingDefinedRegions`: +Further consider the following example, in which the main `@SpringBootApplication` class is annotated with +`@EnableCachingDefinedRegions`: .Using `@EnableCachingDefinedRegions` +==== [source,java] ---- @SpringBootApplication @EnableCachingDefineRegions class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -Then, SBDG would create a client `PROXY` Region (or `PARTITION_REGION` if your application were a peer member of the -cluster) with the name "_CustomersByAccountNumber_" as if you created the Region using either the JavaConfig or XML -approaches shown above. +With this setup, SBDG would create a client `PROXY` Region (or `PARTITION_REGION` if your application were a peer member +of the {geode-name} cluster) with a name of "`CustomersByAccountNumber`", as though you created the Region by using +either the Java configuration or XML approaches shown earlier. -You can use the `clientRegionShortcut` or `serverRegionShortcut` attribute to change the data management policy of the -Regions created on the client or servers, respectively. +You can use the `clientRegionShortcut` or `serverRegionShortcut` attribute to change the data management policy of +the Regions created on the client or servers, respectively. -For client Regions, you can additionally assign a specific Pool of connections used by the client `*PROXY` Regions -to send data to the cluster by setting the `poolName` attribute. +For client Regions, you can also set the `poolName` attribute to assign a specific `Pool` of connections to be used by +the client `*PROXY` Regions to send data to the cluster. [[geode-configuration-declarative-annotations-productivity-regions-enableentitydefined]] ===== `@EnableEntityDefinedRegions` -Like `@EnableCachingDefinedRegions`, `@EnableEntityDefinedRegions` allows you to create Regions based on the entity +As with `@EnableCachingDefinedRegions`, `@EnableEntityDefinedRegions` lets you create Regions based on the entity classes you have defined in your application domain model. -For instance, if you have entity class annotated with SDG's -{spring-data-geode-javadoc}/org/springframework/data/gemfire/mapping/annotation/Region.html[`@Region`] mapping annotation: +For instance, consider an entity class annotated with SDG's +{spring-data-geode-javadoc}/org/springframework/data/gemfire/mapping/annotation/Region.html[`@Region`] +mapping annotation: .Customer entity class annotated with `@Region` +==== [source,java] ---- @Region("Customers") class Customer { - @Id - private Long id; + @Id + private Long id; - @Indexed - private String name; + @Indexed + private String name; } ---- +==== -Then SBDG will create Regions from the name specified in the `@Region` mapping annotation on the entity class. In this -case, the `Customer` application-defined entity class will result in the creation of a Region named "_Customers_" when -the main `@SpringBootApplication` class is annotated with `@EnableEntityDefinedRegions`: +For this class, SBDG creates Regions from the name specified in the `@Region` mapping annotation on the entity class. +In this case, the `Customer` application-defined entity class results in the creation of a Region named "`Customers`" +when the main `@SpringBootApplication` class is annotated with `@EnableEntityDefinedRegions`: .Using `@EnableEntityDefinedRegions` +==== [source,java] ---- @SpringBootApplication @@ -358,30 +385,31 @@ the main `@SpringBootApplication` class is annotated with `@EnableEntityDefinedR clientRegionShortcut = ClientRegionShortcut.CACHING_PROXY) class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -Like the `@EnableCachingDefinedRegions` annotation, you can set the client and server Region data management policy -using the `clientRegionShortcut` and `serverRegionShortcut` attributes, respectively, as well as set a dedicated Pool +As with the `@EnableCachingDefinedRegions` annotation, you can set the client and server Region data management policy +by using the `clientRegionShortcut` and `serverRegionShortcut` attributes, respectively, and set a dedicated `Pool` of connections used by client Regions with the `poolName` attribute. -However, unlike the `@EnableCachingDefinedRegions` annotation, users are required to specify either the `basePackage`, -or the type-safe alternative, `basePackageClasses` attribute (recommended) when using the `@EnableEntityDefinedRegions` -annotation. +However, unlike the `@EnableCachingDefinedRegions` annotation, you must specify either the `basePackage` attribute +or the type-safe `basePackageClasses` attribute (recommended) when you use the `@EnableEntityDefinedRegions` annotation. Part of the reason for this is that `@EnableEntityDefinedRegions` performs a component scan for the entity classes -defined by your application. The component scan loads each class to inspect the _Annotation_ metadata for that class. -This is not unlike the JPA entity scan when working with JPA providers like Hibernate. +defined by your application. The component scan loads each class to inspect the annotation metadata for that class. +This is not unlike the JPA entity scan when working with JPA providers, such as Hibernate. -Therefore, it is customary to limit the scope of the scan, otherwise you end up potentially loading many classes -unnecessarily so. After all, the JVM uses dynamic linking to only load classes when needed. +Therefore, it is customary to limit the scope of the scan. Otherwise, you end up potentially loading many classes +unnecessarily. After all, the JVM uses dynamic linking to load classes only when needed. -Both the `basePackages` and `basePackageClasses` attributes accept an array of values. With `basePackageClasses` you -only need to refer to a single class type in that package and every class in that package as well as classes in the -sub-packages will be scanned to determine if the class type represents an entity. A class type is an entity if it -is annotated with the `@Region` mapping annotation, otherwise it is not considered an entity. +Both the `basePackages` and `basePackageClasses` attributes accept an array of values. With `basePackageClasses`, you +need only refer to a single class type in that package and every class in that package as well as classes in the +sub-packages are scanned to determine if the class type represents an entity. A class type is an entity if it is +annotated with the `@Region` mapping annotation. Otherwise, it is not considered to be an entity. -By example, suppose you had the following structure: +For example, suppose you had the following structure: .Entity Scan +==== [source,txt] ---- - example.app.crm.model @@ -397,132 +425,150 @@ By example, suppose you had the following structure: .. . ---- +==== -Then, you could configure the `@EnableEntityDefinedRegions` as follows: +Then you could configure the `@EnableEntityDefinedRegions` as follows: .Targeting with `@EnableEntityDefinedRegions` +==== [source,java] ---- @SpringBootApplication @EnableEntityDefinedRegions(basePackageClasses = { NonEntity.class, Account.class } ) class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -If `Customer`, `Address`, `PhoneNumber` and `Account` were all entity classes properly annotated with `@Region`, then -the component scan would pick up all these classes and create Regions for them. The `NonEntity` class only serves as -a marker in this case pointing to where (i.e. what package) the scan should begin. +If `Customer`, `Address`, `PhoneNumber` and `Account` were all entity classes properly annotated with `@Region`, +the component scan would pick up all these classes and create Regions for them. The `NonEntity` class serves only as +a marker in this case, to point to where (that is, which package) the scan should begin. -Additionally, the `@EnableEntityDefinedRegions` annotation provides _include_ and _exclude_ filters, the same as +Additionally, the `@EnableEntityDefinedRegions` annotation provides include and exclude filters, the same as the core Spring Frameworks `@ComponentScan` annotation. -TIP: Refer to the SDG Reference Guide on {spring-data-geode-docs-html}/#bootstrap-annotation-config-regions[Configuring Regions] +TIP: See the SDG reference documentation on +{spring-data-geode-docs-html}/#bootstrap-annotation-config-regions[Configuring Regions] for more details. [[geode-configuration-declarative-annotations-productivity-regions-enableclusterdefined]] ===== `@EnableClusterDefinedRegions` -Sometimes it is ideal or even necessary to pull configuration from the cluster (rather than push to the cluster). -That is, you want the Regions defined on the servers to be created on the client and used by your application. +Sometimes, it is ideal or even necessary to pull configuration from the cluster (rather than push configuration to the +cluster). That is, you want the Regions defined on the servers to be created on the client and used by your application. -This is as simple as annotating your main `@SpringBootApplication` class with `@EnableClusterDefinedRegions`: +To do so, annotate your main `@SpringBootApplication` class with `@EnableClusterDefinedRegions`: .Using `@EnableClusterDefinedRegions` +==== [source,java] ---- @SpringBootApplication @EnableClusterDefinedRegions class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -Every Region that exists on the cluster of servers will have a corresponding `PROXY` Region defined and created on the -client as a bean in your Spring Boot application. +Every Region that exists on the servers in the {geode-name} cluster will have a corresponding `PROXY` Region defined +and created on the client as a bean in your Spring Boot application. -If the cluster of servers defines a Region called "_ServerRegion_" you can inject the client `PROXY` Region -by the same name (i.e. "_ServerRegion_") into your Spring Boot application and use it: +If the cluster of servers defines a Region called "`ServerRegion`", you can inject a client `PROXY` Region with +the same name ("`ServerRegion`") into your Spring Boot application: .Using a server-side Region on the client +==== [source,java] ---- @Component class SomeApplicationComponent { - @Resource(name = "ServerRegion") - private Region serverRegion; + @Resource(name = "ServerRegion") + private Region serverRegion; - public void someMethod() { + public void someMethod() { - EntityType entity = new EntityType(); + EntityType entity = new EntityType(); - this.serverRegion.put(1, entity); + this.serverRegion.put(1, entity); - // ... - } + // ... + } } ---- +==== -Of course, SBDG _auto-configures_ a `GemfireTemplate` for the "_ServerRegion_" Region (as described <>), -so a better way to interact with the client `PROXY` Region corresponding to the "_ServerRegion_" Region on the server +SBDG auto-configures a `GemfireTemplate` for the "`ServerRegion`" Region +(see <>), +so a better way to interact with the client `PROXY` Region that corresponds to the "`ServerRegion`" Region on the server is to inject the template: .Using a server-side Region on the client with a template +==== [source,java] ---- @Component class SomeApplicationComponent { - @Autowired - @Qualifier("serverRegionTemplate") - private GemfireTemplate serverRegionTemplate; + @Autowired + @Qualifier("serverRegionTemplate") + private GemfireTemplate serverRegionTemplate; - public void someMethod() { + public void someMethod() { - EntityType entity = new EntityType(); + EntityType entity = new EntityType(); - this.serverRegionTemplate.put(1, entity); + this.serverRegionTemplate.put(1, entity); - //... - } + //... + } } ---- +==== -TIP: Refer to the SDG Reference Guide on {spring-data-geode-docs-html}/#bootstrap-annotation-config-region-cluster-defined[Configuring Cluster-defined Regions] +TIP: See the SDG reference documentation on +{spring-data-geode-docs-html}/#bootstrap-annotation-config-region-cluster-defined[Configuring Cluster-defined Regions] for more details. [[geode-configuration-declarative-annotations-productivity-enableindexing]] ==== `@EnableIndexing` (SDG) -Only when using `@EnableEntityDefinedRegions` can you also use the `@EnableIndexing` annotation. This is because -`@EnableIndexing` requires the entities to be scanned and analyzed for mapping metadata defined on the class type -of the entity. This includes annotations like Spring Data Commons `@Id` annotation as well as SDG provided annotations, -`@Indexed` and `@LuceneIndexed`. +You can also use the `@EnableIndexing` annotation -- but only when you use `@EnableEntityDefinedRegions`. This is +because `@EnableIndexing` requires the entities to be scanned and analyzed for mapping metadata (defined on the class +type of the entity). This includes annotations such as the Spring Data Commons `@Id` annotation and the annotations +provided by SDG, such as `@Indexed` and `@LuceneIndexed`. -The `@Id` annotation identifies the (primary) key of the entity. The `@Indexed` defines OQL Indexes on object fields -which are used in the predicates of your OQL Queries. The `@LuceneIndexed` annotation is used to define Apache Lucene -Indexes required for searches. +The `@Id` annotation identifies the (primary) key of the entity. The `@Indexed` annotation defines OQL indexes on object +fields, which can be used in the predicates of your OQL queries. The `@LuceneIndexed` annotation is used to define the +Apache Lucene Indexes required for searches. -NOTE: Lucene Indexes can only be created on `PARTITION` Regions, and `PARTITION` Regions are only defined -on the server-side. +NOTE: Lucene Indexes can only be created on `PARTITION` Regions, and `PARTITION` Regions can only be defined on +the server side. You may have noticed that the `Customer` entity class's `name` field was annotated with `@Indexed`. +Consider the following listing: + .Customer entity class with `@Indexed` annotated `name` field +==== [source,java] ---- @Region("Customers") class Customer { - @Id - private Long id; + @Id + private Long id; - @Indexed - private String name; + @Indexed + private String name; } ---- +==== -As a result, when our main `@SpringBootApplication` class is annotated with `@EnableIndexing`: +As a result, when our main `@SpringBootApplication` class is annotated with `@EnableIndexing`, an {geode-name} OQL Index +for the `Customer.name` field is created, allowing OQL queries on customers by name to use this Index: .Using `@EnableIndexing` +==== [source,java] ---- @SpringBootApplication @@ -530,176 +576,185 @@ As a result, when our main `@SpringBootApplication` class is annotated with `@En @EnableIndexing class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -An {geode-name} OQL Index for the `Customer.name` field will be created thereby making OQL Queries on Customers by name -use this Index. +NOTE: Keep in mind that OQL Indexes are not persistent between restarts (that is, {geode-name} maintains Indexes +in memory only). An OQL Index is always rebuilt when the node is restarted. -NOTE: Keep in mind that OQL Indexes are not persistent between restarts (i.e. {geode-name} maintains Indexes in-memory -only). An OQL Index is always rebuilt when the node is restarted. +When you combine `@EnableIndexing` with either `@EnableClusterConfiguration` or `@EnableClusterAware`, the Index +definitions are pushed to the server-side Regions where OQL queries are generally executed. -When you combine `@EnableIndexing` with either `@EnableClusterConfiguration` or `@EnableClusterAware`, then the Index -definitions will be pushed to the server-side Regions where OQL Queries are generally executed. - -TIP: Refer to the SDG Reference Guide on {spring-data-geode-docs-html}/#bootstrap-annotation-config-region-indexes[Configuring Indexes] +TIP: See the SDG reference documentation on +{spring-data-geode-docs-html}/#bootstrap-annotation-config-region-indexes[Configuring Indexes] for more details. [[geode-configuration-declarative-annotations-productivity-enableexpiration]] ==== `@EnableExpiration` (SDG) -It is often useful to define both _Eviction_ and _Expiration_ policies, particularly with a system like {geode-name}, -especially given it primarily keeps data in-memory, on the JVM Heap. As you can imagine your data volume size may far -exceed the amount of available JVM Heap memory and/or keeping too much data on the JVM Heap can cause Garbage Collection -(GC) issues. +It is often useful to define both eviction and expiration policies, particularly with a system like {geode-name}, +because it primarily keeps data in memory (on the JVM Heap). Your data volume size may far exceed the amount of +available JVM Heap memory, and keeping too much data on the JVM Heap can cause Garbage Collection (GC) issues. TIP: You can enable off-heap (or main memory usage) capabilities by declaring SDG's `@EnableOffHeap` annotation. -Refer to the SDG Reference Guide on {spring-data-geode-docs-html}/#bootstrap-annotation-config-region-off-heap[Configuring Off-Heap Memory] +See the SDG reference documentation on +{spring-data-geode-docs-html}/#bootstrap-annotation-config-region-off-heap[Configuring Off-Heap Memory] for more details. -Defining _Eviction_ and _Expiration_ policies is a useful for limiting what is kept in memory and for how long. +Defining eviction and expiration policies lets you limit what is kept in memory and for how long. -While {spring-data-geode-docs-html}/#bootstrap-annotation-config-region-eviction[configuring _Eviction_] is easy with -SDG, we particularly want to call out _Expiration_ since -{spring-data-geode-docs-html}/#bootstrap-annotation-config-region-expiration[configuring _Expiration_] has special -support in SDG. +While {spring-data-geode-docs-html}/#bootstrap-annotation-config-region-eviction[configuring eviction] is easy with SDG, +we particularly want to call out expiration since +{spring-data-geode-docs-html}/#bootstrap-annotation-config-region-expiration[configuring expiration] has special support +in SDG. -With SDG, it is possible to define the _Expiration_ policies associated with a particular application class type on the -class type itself, using the {spring-data-geode-javadoc}/org/springframework/data/gemfire/expiration/Expiration.html[`@Expiration`], +With SDG, you can define the expiration policies associated with a particular application class type on the class type +itself, by using the {spring-data-geode-javadoc}/org/springframework/data/gemfire/expiration/Expiration.html[`@Expiration`], {spring-data-geode-javadoc}/org/springframework/data/gemfire/expiration/IdleTimeoutExpiration.html[`@IdleTimeoutExpiration`] and {spring-data-geode-javadoc}/org/springframework/data/gemfire/expiration/TimeToLiveExpiration.html[`@TimeToLiveExpiration`] annotations. -TIP: Refer to the {geode-name} {apache-geode-docs}/developing/expiration/how_expiration_works.html[User Guide] -for more details on the different Expiration Types (i.e. _Idle Timeout_ (TTI) vs. _Time-To-Live_ (TTL)). +TIP: See the {geode-name} {apache-geode-docs}/developing/expiration/how_expiration_works.html[User Guide] +for more details on the different expiration types -- that is _Idle Timeout_ (TTI) versus _Time-to-Live_ (TTL). For example, suppose we want to limit the number of `Customers` maintained in memory for a period of time (measured in -seconds) based on the last time a `Customer` was accessed (e.g. _read_). We can the define an _Idle Timeout_ Expiration -policy on our `Customer` class type, like so: +seconds) based on the last time a `Customer` was accessed (for example, the last time a `Customer` was read). To do so, +we can define an idle timeout expiration (TTI) policy on our `Customer` class type: -.Customer entity class with `@Indexed` annotated `name` field +.Customer entity class with Idle Timeout Expiration (TTI) +==== [source,java] ---- @Region("Customers") @IdleTimeoutExpiration(action = "INVALIDATE", timeout = "300") class Customer { - @Id - private Long id; + @Id + private Long id; - @Indexed - private String name; + @Indexed + private String name; } ---- +==== -The `Customer` entry in the "_Customers_" Region will be `invalidated` after `300 seconds` (or `5 minutes`). +The `Customer` entry in the `Customers` Region is `invalidated` after 300 seconds (5 minutes). -All we need to do to enable annotation-based Expiration policies is annotate our main `@SpringBootApplication` class +To enable annotation-based expiration policies, we need to annotate our main `@SpringBootApplication` class with `@EnableExpiration`: .Enabling Expiration +==== [source,java] ---- @SpringBootApplication @EnableExpiration class SpringBootApacheGeodeApplication { } ---- +==== -NOTE: Technically, this entity class specific Annotation-based Expiration policy is implemented using {geode-name}'s +NOTE: Technically, this entity-class-specific annotation-based expiration policy is implemented by using {geode-name}'s {apache-geode-javadoc}/org/apache/geode/cache/CustomExpiry.html[`CustomExpiry`] interface. -TIP: Refer to the SDG Reference Guide for more details on -{spring-data-geode-docs-html}/#bootstrap-annotation-config-region-expiration[configuring Expiration], along with -{spring-data-geode-docs-html}/#bootstrap:region:expiration:annotation[Annotation-based Data Expiration] in particular. +TIP: See the SDG reference doccumentation for more details on +{spring-data-geode-docs-html}/#bootstrap-annotation-config-region-expiration[configuring expiration], along with +{spring-data-geode-docs-html}/#bootstrap:region:expiration:annotation[annotation-based data expiration] in particular. [[geode-configuration-declarative-annotations-productivity-enablemockobjects]] ==== `@EnableGemFireMockObjects` (STDG) -_Software Testing_ in general, and _Unit Testing_ in particular, are a very important development tasks to ensure -the quality of your Spring Boot applications. +Software testing in general and unit testing in particular are a very important development tasks to ensure the quality +of your Spring Boot applications. -{geode-name} can make testing difficult in some cases, especially when tests have to be written as _Integration Tests_ -in order to assert the correct behavior. This can be very costly and lengthens the feedback cycle. Fortunately, it is -possible to write _Unit Tests_ as well! +{geode-name} can make testing difficult in some cases, especially when tests have to be written as integration tests +to assert the correct behavior. This can be very costly and lengthens the feedback cycle. Fortunately, you can write +unit tests as well. -Spring has your back and once again provides a framework for testing Spring Boot applications using {geode-name}. This -is where the {spring-test-data-gemfire-website}[Spring Test for {geode-name} (STDG)] project can help, particularly with -_Unit Testing_. +Spring provides a framework for testing Spring Boot applications that use {geode-name}. This is where the +{spring-test-data-gemfire-website}[Spring Test for {geode-name} (STDG)] project can help, particularly with +unit testing. -For example, if you do not care what {geode-name} would actually do in certain cases and only care about the "contract", -which is what mocking a collaborator is all about, then you could effectively mock {geode-name} objects in order to -isolate the "_Subject Under Test_" (SUT) and focus on the interaction(s) or outcomes you expect to happen. +For example, if you do not care what {geode-name} would actually do in certain cases and only care about the "`contract`", +which is what mocking a collaborator is all about, you could effectively mock {geode-name} objects to isolate the SUT, +or "`Subject Under Test`", and focus on the interactions or outcomes you expect to happen. -With STDG, you don't have to change a bit of configuration to enable mocks in the _Unit Tests_ for your Spring Boot -applications. You simply only need to annotate the test class with `@EnableGemFireMockObjects`, like so: +With STDG, you need not change a bit of configuration to enable mock objects in the unit tests for your Spring Boot +applications. You need only annotate the test class with `@EnableGemFireMockObjects`: .Using Mock {geode-name} Objects +==== [source,java] ---- @RunWith(SpringRunner.class) @SpringBootTest class MyApplicationTestClass { - @Test - public void someTestCase() { - // ... - } + @Test + public void someTestCase() { + // ... + } - @Configuration - @EnableGemFireMockObjects - static class GeodeConfiguration { } + @Configuration + @EnableGemFireMockObjects + static class GeodeConfiguration { } } ---- +==== -Your Spring Boot configuration of {geode-name} will return mock objects for all {geode-name} objects, such as Regions. +Your Spring Boot configuration of {geode-name} returns mock objects for all {geode-name} objects, such as Regions. Mocking {geode-name} objects even works for objects created from the productivity annotations discussed in the previous -sections above. +sections. -For example, given the following Spring Boot, {geode-name} `ClientCache` application class: +For example, consider the following Spring Boot, {geode-name} `ClientCache` application class: .Main `@SpringBootApplication` class under test +==== [source,java] ---- @SpringBootApplication @EnableEntityDefinedRegions(basePackageClasses = Customer.class) class SpringBootApacheGeodeClientCacheApplication { } ---- +==== -The "_Customers_" Region defined by the `Customer` entity class and created by the `@EnableEntityDefinedRegions` -annotation would be a "mock" Region and not an actual Region. You can still inject the Region in your test as before -and assert interactions on the Region based on your application workflows: +In the preceding example, the `"Customers`" Region defined by the `Customer` entity class and created by +the `@EnableEntityDefinedRegions` annotation would be a mock Region and not an actual Region. You can still inject +the Region in your test and assert interactions on the Region based on your application workflows: .Using Mock {geode-name} Objects +==== [source,java] ---- @RunWith(SpringRunner.class) @SpringBootTest class MyApplicationTestClass { - @Resource(name = "Customers") - private Region customers; + @Resource(name = "Customers") + private Region customers; - @Test - public void someTestCase() { + @Test + public void someTestCase() { - Customer jonDoe = new Customer(1, "Jon Doe"); + Customer jonDoe = new Customer(1, "Jon Doe"); - // Use the application in some way and test the interaction on the "Customers" Region + // Use the application in some way and test the interaction on the "Customers" Region - assertThat(this.customers).containsValue(jonDoe); + assertThat(this.customers).containsValue(jonDoe); - // ... - } + // ... + } } ---- +==== -There are many more things that STDG can do for you in both _Unit & Integration Testing_. +There are many more things that STDG can do for you in both unit testing and integration testing. -Refer to the https://github.com/spring-projects/spring-test-data-geode#unit-testing-with-stdg[documentation on Unit Testing] +See the https://github.com/spring-projects/spring-test-data-geode#unit-testing-with-stdg[documentation on unit testing] for more details. -It is possible to https://github.com/spring-projects/spring-test-data-geode#integration-testing-with-stdg[write _Integration Tests_] -using STDG as well. Writing _Integration Tests_ is an essential concern when you need to assert whether your -application OQL Queries are well-formed, for instance. There are many other valid cases where _Integration Testing_ +You can https://github.com/spring-projects/spring-test-data-geode#integration-testing-with-stdg[write integration tests] +that use STDG as well. Writing integration tests is an essential concern when you need to assert whether your +application OQL queries are well-formed, for instance. There are many other valid cases where integration testing is also applicable. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-externalized.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-externalized.adoc index 33611180..e17167a9 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-externalized.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-externalized.adoc @@ -3,27 +3,28 @@ :geode-name: {apache-geode-name} -Like Spring Boot itself (see {spring-boot-docs-html}/boot-features-external-config.html[here]), Spring Boot -for {geode-name} (SBDG) supports externalized configuration. +Like Spring Boot itself (see {spring-boot-docs-html}/boot-features-external-config.html[Spring Boot's documentation]), +Spring Boot for {geode-name} (SBDG) supports externalized configuration. -By externalized configuration, we mean configuration metadata stored in a Spring Boot -{spring-boot-docs-html}/boot-features-external-config.html#boot-features-external-config-application-property-files[`application.properties` file], -for instance. Properties can even be delineated by concern, broken out into individual properties files, that are -perhaps only enabled by a specific {spring-boot-docs-html}/boot-features-external-config.html#boot-features-external-config-profile-specific-properties[Profile]. +By externalized configuration, we mean configuration metadata stored in Spring Boot +{spring-boot-docs-html}/boot-features-external-config.html#boot-features-external-config-application-property-files[`application.properties`]. +You can even separate concerns by addressing each concern in an individual properties file. Optionally, you could also +enable any given property file for only a specific {spring-boot-docs-html}/boot-features-external-config.html#boot-features-external-config-profile-specific-properties[profile]. -There are many other powerful things you can do, such as, but not limited to, using +You can do many other powerful things, such as (but not limited to) using {spring-boot-docs-html}/boot-features-external-config.html#boot-features-external-config-placeholders-in-properties[placeholders] in properties, {spring-boot-docs-html}/boot-features-external-config.html#boot-features-encrypting-properties[encrypting] -properties, and so on. What we are particularly interested in, in this section, is -{spring-boot-docs-html}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[type-safety]. +properties, and so on. In this section, we focus particularly on +{spring-boot-docs-html}/boot-features-external-config.html#boot-features-external-config-typesafe-configuration-properties[type safety]. -Like Spring Boot, Spring Boot for {geode-name} provides a hierarchy of classes used to capture configuration for several +Like Spring Boot, Spring Boot for {geode-name} provides a hierarchy of classes that captures configuration for several {geode-name} features in an associated `@ConfigurationProperties` annotated class. Again, the configuration metadata is -specified as well-known, documented properties in 1 or more Spring Boot `application.properties` files. +specified as well-known, documented properties in one or more Spring Boot `application.properties` files. -For instance, I may have configured my Spring Boot, `ClientCache` application as follows: +For instance, a Spring Boot, {geode-name} `ClientCache` application might be configured as follows: .Spring Boot `application.properties` containing Spring Data properties for {geode-name} +==== [source,properties] ---- # Spring Boot application.properties used to configure {geode-name} @@ -43,101 +44,109 @@ spring.data.gemfire.logging.log-file=/path/to/geode.log # Configure the client's connection Pool to the servers in the cluster spring.data.gemfire.pool.locators=10.105.120.16[11235],boombox[10334] - ---- +==== -There are many other properties a user may use to externalize the configuration of their Spring Boot, -{geode-name} applications. You may refer to the Spring Data for {geode-name} (SDG) configuration annotations -{spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/package-frame.html[Javadoc] -for specific configuration properties as needed. Specifically, review the "_enabling_" annotation attributes. +You can use many other properties to externalize the configuration of your Spring Boot, {geode-name} applications. +See the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/package-frame.html[Javadoc] +for specific configuration properties. Specifically, review the `enabling` annotation attributes. -There may be cases where you require access to the configuration metadata (specified in properties) -in your Spring Boot applications themselves, perhaps to further inspect or act on a particular configuration setting. - -Of course, you can access any property using Spring's {spring-framework-javadoc}/org/springframework/core/env/Environment.html[`Environment`] abstraction, -like so: +You may sometimes require access to the configuration metadata (specified in properties) in your Spring Boot +applications themselves, perhaps to further inspect or act on a particular configuration setting. You can access any +property by using Spring's {spring-framework-javadoc}/org/springframework/core/env/Environment.html[`Environment`] +abstraction: .Using the Spring `Environment` +==== [source,java] ---- @Configuration class GeodeConfiguration { - void readConfigurationFromEnvironment(Environment environment) { - boolean copyOnRead = environment.getProperty("spring.data.gemfire.cache.copy-on-read", Boolean.TYPE, false); - } + + void readConfigurationFromEnvironment(Environment environment) { + boolean copyOnRead = environment.getProperty("spring.data.gemfire.cache.copy-on-read", + Boolean.TYPE, false); + } } ---- +==== -While using the `Environment` is a nice approach, you might need access to additional properties or want to access -the property values in a type-safe manner. Therefore, it is now possible, thanks to SBDG's auto-configured -configuration processor, to access the configuration metadata using provided `@ConfigurationProperties` classes. +While using `Environment` is a nice approach, you might need access to additional properties or want to access +the property values in a type-safe manner. Therefore, you can now, thanks to SBDG's auto-configured configuration +processor, access the configuration metadata by using `@ConfigurationProperties` classes. -Following on to our example above, I can now do the following: +To add to the preceding example, you can now do the following: .Using `GemFireProperties` +==== [source,java] ---- - @Component class MyApplicationComponent { - @Autowired - private GemFireProperties gemfireProperties; + @Autowired + private GemFireProperties gemfireProperties; - public void someMethodUsingGemFireProperties() { + public void someMethodUsingGemFireProperties() { - boolean copyOnRead = this.gemfireProperties.getCache().isCopyOnRead(); + boolean copyOnRead = this.gemfireProperties.getCache().isCopyOnRead(); - // do something with `copyOnRead` - } + // do something with `copyOnRead` + } } ---- +==== Given a handle to {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/configuration/GemFireProperties.html[`GemFireProperties`], -you can access any of the configuration properties used to configure {geode-name} in a Spring context. You simply only -need to autowire an instance of `GemFireProperties` into your application component. +you can access any of the configuration properties that are used to configure {geode-name} in a Spring context. You need +only autowire an instance of `GemFireProperties` into your application component. -A complete reference to the SBDG provided `@ConfigurationProperties` classes and supporting classes is available -{spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/configuration/package-frame.html[here]. +See the complete reference for the +{spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/configuration/package-frame.html[SBDG `@ConfigurationProperties` classes and supporting classes]. [[geode-configuration-externalized-session]] === Externalized Configuration of Spring Session -The same capability applies to accessing the externalized configuration of Spring Session when using {geode-name} as -your (HTTP) Session state caching provider. +You can access the externalized configuration of Spring Session when you use {geode-name} as your (HTTP) session state +caching provider. -In this case, you simply only need to acquire a reference to an instance of the +In this case, you need only acquire a reference to an instance of the {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/configuration/SpringSessionProperties.html[`SpringSessionProperties`] class. -As before, you would specify Spring Session for {geode-name} (SSDG) properties as follows: +As shown earlier in this chapter, you can specify Spring Session for {geode-name} (SSDG) properties as follows: -.Spring Boot `application.properties` for Spring Session using {geode-name} as the (HTTP) Session state caching provider +.Spring Boot `application.properties` for Spring Session using {geode-name} as the (HTTP) session state caching provider +==== [source,properties] ---- -# Spring Boot application.properties used to configure {geode-name} as a Session state caching provider in Spring Session +# Spring Boot application.properties used to configure {geode-name} as a (HTTP) session state caching provider +# in Spring Session spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds=300 spring.session.data.gemfire.session.region.name=UserSessions - ---- +==== -Then, in your application: +Then, in your application, you can do something similar to the following example: .Using `SpringSessionProperties` +==== [source,java] ---- @Component class MyApplicationComponent { - @Autowired - private SpringSessionProperties springSessionProperties; + @Autowired + private SpringSessionProperties springSessionProperties; - public void someMethodUsingSpringSessionProperties() { + public void someMethodUsingSpringSessionProperties() { - String sessionRegionName = this.springSessionProperties.getSession().getRegion().getName(); + String sessionRegionName = this.springSessionProperties + .getSession().getRegion().getName(); - // do something with `sessionRegionName` - } + // do something with `sessionRegionName` + } } ---- +==== diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-properties.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-properties.adoc index eb921c82..45a13731 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/configuration-properties.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/configuration-properties.adoc @@ -3,154 +3,152 @@ :geode-name: {apache-geode-name} -The following 2 reference sections cover documented and well-known properties recognized and processed by -_Spring Data for {geode-name}_ (SDG) as well as _Spring Session for {geode-name}_ (SSDG). +The following reference sections cover documented and well-known properties recognized and processed by Spring Data +for {geode-name} (SDG) and Spring Session for {geode-name} (SSDG). -These properties may be used in Spring Boot `application.properties` files, or as JVM System properties, to configure -different aspects of or enable individual features of {geode-name} in a Spring application. When combined with the power -of Spring Boot, magical things begin to happen. +These properties may be used in Spring Boot `application.properties` or as JVM System properties, to configure different +aspects of or enable individual features of {geode-name} in a Spring application. When combined with the power of +Spring Boot, they give you the ability to quickly create an application that uses {geode_name}. [[geode-configuration-metadata-springdata]] === Spring Data Based Properties -The following properties all have a `spring.data.gemfire.*` prefix. For example, to set the cache `copy-on-read` +The following properties all have a `spring.data.gemfire.*` prefix. For example, to set the cache `copy-on-read` property, use `spring.data.gemfire.cache.copy-on-read` in Spring Boot `application.properties`. - .`spring.data.gemfire.*` properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| name | Name of the {geode-name}. | SpringBasedCacheClientApplication | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#name--[ClientCacheApplication.name] -| locators | Comma-delimited list of Locator endpoints formatted as: locator1[port1],...,locatorN[portN]. | [] | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#locators--[PeerCacheApplication.locators] -| use-bean-factory-locator | Enable the SDG BeanFactoryLocator when mixing Spring config with {geode-name} native config (e.g. cache.xml) and you wish to configure {geode-name} objects declared in `cache.xml` with Spring. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#useBeanFactoryLocator--[ClientCacheApplication.useBeanFactoryLocator] +| `name` | Name of the {geode-name}. | `SpringBasedCacheClientApplication` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#name--[`ClientCacheApplication.name`] +| `locators` | Comma-delimited list of Locator endpoints formatted as: `locator1[port1],...,locatorN[portN]`. | [] | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#locators--[`PeerCacheApplication.locators`] +| `use-bean-factory-locator` | Enable the SDG `BeanFactoryLocator` when mixing Spring config with {geode-name} native config (such as `cache.xml`) and you wish to configure {geode-name} objects declared in `cache.xml` with Spring. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#useBeanFactoryLocator--[`ClientCacheApplication.useBeanFactoryLocator`] |===================================================================================================================== - .`spring.data.gemfire.*` _GemFireCache_ properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| cache.copy-on-read | Configure whether a copy of an object returned from Region.get(key) is made. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#copyOnRead--[ClientCacheApplication.copyOnRead] -| cache.critical-heap-percentage | Percentage of heap at or above which the cache is considered in danger of becoming inoperable. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#criticalHeapPercentage--[ClientCacheApplication.criticalHeapPercentage] -| cache.critical-off-heap-percentage | Percentage of off-heap at or above which the cache is considered in danger of becoming inoperable. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#criticalOffHeapPercentage--[ClientCacheApplication.criticalOffHeapPercentage] -| cache.enable-auto-region-lookup | Configure whether to lookup Regions configured in {geode-name} native config and declare them as Spring beans. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAutoRegionLookup.html#enabled--[EnableAutoRegionLookup.enable] -| cache.eviction-heap-percentage | Percentage of heap at or above which the eviction should begin on Regions configured for HeapLRU eviction. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#evictionHeapPercentage--[ClientCacheApplication.evictionHeapPercentage] -| cache.eviction-off-heap-percentage | Percentage of off-heap at or above which the eviction should begin on Regions configured for HeapLRU eviction. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#evictionOffHeapPercentage--[ClientCacheApplication.evictionOffHeapPercentage] -| cache.log-level | Configure the log-level of an {geode-name} cache. | config | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#logLevel--[ClientCacheApplication.logLevel] -| cache.name | Alias for 'spring.data.gemfire.name'. | SpringBasedCacheClientApplication | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#name--[ClientCacheApplication.name] -| cache.compression.bean-name | Name of a Spring bean implementing org.apache.geode.compression.Compressor. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableCompression.html#compressorBeanName--[EnableCompression.compressorBeanName] -| cache.compression.region-names | Comma-delimited list of Region names for which compression will be configured. | [] | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableCompression.html#regionNames--[EnableCompression.regionNames] -| cache.off-heap.memory-size | Determines the size of off-heap memory used by {geode-name} in megabytes (m) or gigabytes (g); for example 120g. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableOffHeap.html#memorySize--[EnableOffHeap.memorySize] -| cache.off-heap.region-names | Comma-delimited list of Region names for which off-heap will be configured. | [] | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableOffHeap.html#regionNames--[EnableOffHeap.regionNames] +| `cache.copy-on-read` | Configure whether a copy of an object returned from `Region.get(key)` is made. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#copyOnRead--[`ClientCacheApplication.copyOnRead`] +| `cache.critical-heap-percentage` | Percentage of heap at or above which the cache is considered in danger of becoming inoperable. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#criticalHeapPercentage--[`ClientCacheApplication.criticalHeapPercentage`] +| `cache.critical-off-heap-percentage` | Percentage of off-heap at or above which the cache is considered in danger of becoming inoperable. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#criticalOffHeapPercentage--[`ClientCacheApplication.criticalOffHeapPercentage`] +| `cache.enable-auto-region-lookup` | Whether to lookup Regions configured in {geode-name} native configuration and declare them as Spring beans. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAutoRegionLookup.html#enabled--[`EnableAutoRegionLookup.enable`] +| `cache.eviction-heap-percentage` | Percentage of heap at or above which the eviction should begin on Regions configured for HeapLRU eviction. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#evictionHeapPercentage--[`ClientCacheApplication.evictionHeapPercentage`] +| `cache.eviction-off-heap-percentage` | Percentage of off-heap at or above which the eviction should begin on Regions configured for HeapLRU eviction. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#evictionOffHeapPercentage--[`ClientCacheApplication.evictionOffHeapPercentage`] +| `cache.log-level` | Configure the log-level of an {geode-name} cache. | `config` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#logLevel--[`ClientCacheApplication.logLevel`] +| `cache.name` | Alias for `spring.data.gemfire.name`. | `SpringBasedCacheClientApplication` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#name--[`ClientCacheApplication.name`] +| `cache.compression.bean-name` | Name of a Spring bean that implements `org.apache.geode.compression.Compressor`. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableCompression.html#compressorBeanName--[`EnableCompression.compressorBeanName`] +| `cache.compression.region-names` | Comma-delimited list of Region names for which compression is configured. | `[]` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableCompression.html#RegionNames--[EnableCompression.RegionNames] +| cache.off-heap.memory-size | Determines the size of off-heap memory used by {geode-name} in megabytes (m) or gigabytes (g) -- for example, `120g` | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableOffHeap.html#memorySize--[`EnableOffHeap.memorySize`] +| `cache.off-heap.region-names` | Comma-delimited list of Region names for which off-heap is configured. | `[]` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableOffHeap.html#RegionNames--[`EnableOffHeap.RegionNames`] |===================================================================================================================== - .`spring.data.gemfire.*` _ClientCache_ properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| cache.client.durable-client-id | Used only for clients in a client/server installation. If set, this indicates that the client is durable and identifies the client. The ID is used by servers to reestablish any messaging that was interrupted by client downtime. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#durableClientId--[ClientCacheApplication.durableClientId] -| cache.client.durable-client-timeout | Used only for clients in a client/server installation. Number of seconds this client can remain disconnected from its server and have the server continue to accumulate durable events for it. | 300 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#durableClientTimeout--[ClientCacheApplication.durableClientTimeout] -| cache.client.keep-alive | Configure whether the server should keep the durable client's queues alive for the timeout period. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#keepAlive--[ClientCacheApplication.keepAlive] +| `cache.client.durable-client-id` | Used only for clients in a client/server installation. If set, this indicates that the client is durable and identifies the client. The ID is used by servers to reestablish any messaging that was interrupted by client downtime. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#durableClientId--[`ClientCacheApplication.durableClientId`] +| `cache.client.durable-client-timeout` | Used only for clients in a client/server installation. Number of seconds this client can remain disconnected from its server and have the server continue to accumulate durable events for it. | `300` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#durableClientTimeout--[`ClientCacheApplication.durableClientTimeout`] +| `cache.client.keep-alive` | Whether the server should keep the durable client's queues alive for the timeout period. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#keepAlive--[`ClientCacheApplication.keepAlive`] |===================================================================================================================== - .`spring.data.gemfire.*` peer _Cache_ properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| cache.peer.enable-auto-reconnect | Configure whether member (Locators & Servers) will attempt to reconnect and reinitialize the cache after it has been forced out of the cluster by a network partition event or has otherwise been shunned by other members. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#enableAutoReconnect--[PeerCacheApplication.enableAutoReconnect] -| cache.peer.lock-lease | Configures the length, in seconds, of distributed lock leases obtained by this cache. | 120 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#lockLease--[PeerCacheApplication.lockLease] -| cache.peer.lock-timeout | Configures the number of seconds a cache operation will wait to obtain a distributed lock lease. | 60 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#lockTimeout--[PeerCacheApplication.lockTimeout] -| cache.peer.message-sync-interval | Configures the frequency (in seconds) at which a message will be sent by the primary cache-server to all the secondary cache-server nodes to remove the events which have already been dispatched from the queue. | 1 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#messageSyncInterval--[PeerCacheApplication.messageSyncInterval] -| cache.peer.search-timeout | Configures the number of seconds a cache get operation can spend searching for a value. | 300 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#searchTimeout--[PeerCacheApplication.searchTimeout] -| cache.peer.use-cluster-configuration | Configures whether this cache member node would pull it's configuration meta-data from the cluster-based Cluster Configuration Service. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#useClusterConfiguration--[PeerCacheApplication.useClusterConfiguration] +| `cache.peer.enable-auto-reconnect` | Whether a member (a Locator or Server) try to reconnect and reinitialize the cache after it has been forced out of the cluster by a network partition event or has otherwise been shunned by other members. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#enableAutoReconnect--[`PeerCacheApplication.enableAutoReconnect`] +| `cache.peer.lock-lease` | The length, in seconds, of distributed lock leases obtained by this cache. | `120` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#lockLease--[`PeerCacheApplication.lockLease`] +| `cache.peer.lock-timeout` | The number of seconds a cache operation waits to obtain a distributed lock lease. | `60` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#lockTimeout--[`PeerCacheApplication.lockTimeout`] +| `cache.peer.message-sync-interval` | The frequency (in seconds) at which a message is sent by the primary cache-server to all the secondary cache-server nodes to remove the events that have already been dispatched from the queue. | `1` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#messageSyncInterval--[`PeerCacheApplication.messageSyncInterval`] +| `cache.peer.search-timeout` | The number of seconds a cache get operation can spend searching for a value. | `300` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#searchTimeout--[`PeerCacheApplication.searchTimeout`] +| `cache.peer.use-cluster-configuration` | Whether this cache member node pulls its configuration metadata from the cluster-based cluster configuration service. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/PeerCacheApplication.html#useClusterConfiguration--[`PeerCacheApplication.useClusterConfiguration`] |===================================================================================================================== - .`spring.data.gemfire.*` _CacheServer_ properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| cache.server.auto-startup | Configures whether the CacheServer should be started automatically at runtime. | true | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#autoStartup--[CacheServerApplication.autoStartup] -| cache.server.bind-address | Configures the IP address or hostname that this cache server will listen on. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#bindAddress--[CacheServerApplication.bindAddress] -| cache.server.hostname-for-clients | Configures the IP address or hostname that server locators will tell clients that this cache server is listening on. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#hostnameForClients--[CacheServerApplication.hostNameForClients] -| cache.server.load-poll-interval | Configures the frequency in milliseconds to poll the load probe on this cache server. | 5000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#loadPollInterval--[CacheServerApplication.loadPollInterval] -| cache.server.max-connections | Configures the maximum client connections allowed. | 800 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxConnections--[CacheServerApplication.maxConnections] -| cache.server.max-message-count | Configures the maximum number of messages that can be enqueued in a client queue. | 230000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxMessageCount--[CacheServerApplication.maxMessageCount] -| cache.server.max-threads | Configures the maximum number of threads allowed in this cache server to service client requests. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxThreads--[CacheServerApplication.maxThreads] -| cache.server.max-time-between-pings | Configures the maximum amount of time between client pings. | 60000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxTimeBetweenPings--[CacheServerApplication.maxTimeBetweenPings] -| cache.server.message-time-to-live | Configures the time (in seconds) after which a message in the client queue will expire. | 180 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#messageTimeToLive--[CacheServerApplication.messageTimeToLive] -| cache.server.port | Configures the port on which this cache server listens for clients. | 40404 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#port--[CacheServerApplication.port] -| cache.server.socket-buffer-size | Configures buffer size of the socket connection to this CacheServer. | 32768 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#socketBufferSize--[CacheServerApplication.socketBufferSize] -| cache.server.subscription-capacity | Configures the capacity of the client queue. | 1 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#subscriptionCapacity--[CacheServerApplication.subscriptionCapacity] -| cache.server.subscription-disk-store-name | Configures the name of the DiskStore for client subscription queue overflow. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#subscriptionDiskStoreName--[CacheServerApplication.subscriptionDiskStoreName] -| cache.server.subscription-eviction-policy | Configures the eviction policy that is executed when capacity of the client subscription queue is reached. | none | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#subscriptionEvictionPolicy--[CacheServerApplication.subscriptionEvictionPolicy] -| cache.server.tcp-no-delay | Configures the outgoing Socket connection tcp-no-delay setting. | true | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#tcpNoDelay--[CacheServerApplication.tcpNoDelay] +| `cache.server.auto-startup` | Whether the `CacheServer` should be started automatically at runtime. | `true` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#autoStartup--[`CacheServerApplication.autoStartup`] +| `cache.server.bind-address` | The IP address or hostname on which this cache server listens. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#bindAddress--[`CacheServerApplication.bindAddress`] +| `cache.server.hostname-for-clients` | The IP address or hostname that server locators tell to clients to indicate the IP address on which the cache server listens. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#hostnameForClients--[`CacheServerApplication.hostNameForClients`] +| `cache.server.load-poll-interval` | The frequency in milliseconds at which to poll the load probe on this cache server. | `5000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#loadPollInterval--[`CacheServerApplication.loadPollInterval`] +| `cache.server.max-connections` | The maximum client connections. | `800` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxConnections--[`CacheServerApplication.maxConnections`] +| `cache.server.max-message-count` | The maximum number of messages that can be in a client queue. | `230000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxMessageCount--[`CacheServerApplication.maxMessageCount`] +| `cache.server.max-threads` | The maximum number of threads allowed in this cache server to service client requests. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxThreads--[`CacheServerApplication.maxThreads`] +| `cache.server.max-time-between-pings` | The maximum amount of time between client pings. | `60000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#maxTimeBetweenPings--[`CacheServerApplication.maxTimeBetweenPings`] +| `cache.server.message-time-to-live` | The time (in seconds) after which a message in the client queue expires. | `180` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#messageTimeToLive--[`CacheServerApplication.messageTimeToLive`] +| `cache.server.port` | The port on which this cache server listens for clients. | `40404` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#port--[`CacheServerApplication.port`] +| `cache.server.socket-buffer-size` | The buffer size of the socket connection to this `CacheServer`. | `32768` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#socketBufferSize--[`CacheServerApplication.socketBufferSize`] +| `cache.server.subscription-capacity` | The capacity of the client queue. | `1` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#subscriptionCapacity--[`CacheServerApplication.subscriptionCapacity`] +| `cache.server.subscription-disk-store-name` | The name of the disk store for client subscription queue overflow. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#subscriptionDiskStoreName--[`CacheServerApplication.subscriptionDiskStoreName`] +| `cache.server.subscription-eviction-policy` | The eviction policy that is executed when the capacity of the client subscription queue is reached. | `none` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#subscriptionEvictionPolicy--[`CacheServerApplication.subscriptionEvictionPolicy`] +| `cache.server.tcp-no-delay` | The outgoing socket connection tcp-no-delay setting. | `true` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/CacheServerApplication.html#tcpNoDelay--[`CacheServerApplication.tcpNoDelay`] |===================================================================================================================== -_CacheServer_ properties can be further targeted at specific _CacheServer_ instances, using an option bean name -of the `CacheServer` bean defined in the Spring application context. For example: +`CacheServer` properties can be further targeted at specific `CacheServer` instances by using an optional bean name +of the `CacheServer` bean defined in the Spring `ApplicationContext`. Consider the following example: +==== [source,properties] ---- spring.data.gemfire.cache.server.[].bind-address=... ---- - +==== .`spring.data.gemfire.*` Cluster properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| cluster.region.type | Configuration setting used to specify the data management policy used when creating Regions on the servers in the cluster. | {apache-geode-javadoc}/org/apache/geode/cache/RegionShortcut.html#PARTITION[RegionShortcut.PARTITION] | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#serverRegionShortcut--[EnableClusterConfiguration.serverRegionShortcut] +| `cluster.Region.type` | Specifies the data management policy used when creating Regions on the servers in the cluster. | {apache-geode-javadoc}/org/apache/geode/cache/RegionShortcut.html#PARTITION[`RegionShortcut.PARTITION`] | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#serverRegionShortcut--[`EnableClusterConfiguration.serverRegionShortcut`] |===================================================================================================================== - .`spring.data.gemfire.*` _DiskStore_ properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| disk.store.allow-force-compaction | Configures whether to allow DiskStore.forceCompaction() to be called on Regions using a DiskStore. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#allowForceCompaction--[EnableDiskStore.allowForceCompaction] -| disk.store.auto-compact | Configures whether to cause the disk files to be automatically compacted. | true | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#autoCompact--[EnableDiskStore.autoCompact] -| disk.store.compaction-threshold | Configures the threshold at which an oplog will become compactable. | 50 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#compactionThreshold--[EnableDiskStore.compactionThreshold] -| disk.store.directory.location | Configures the system directory where the `DiskStore` (oplog) files will be stored. | [] | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskDirectories--[EnableDiskStore.diskDirectories.location] -| disk.store.directory.size | Configures the amount of disk space allowed to store DiskStore (oplog) files. | 21474883647 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskDirectories--[EnableDiskStore.diskDirectories.size] -| disk.store.disk-usage-critical-percentage | Configures the critical threshold for disk usage as a percentage of the total disk volume. | 99.0 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskUsageCriticalPercentage--[EnableDiskStore.diskUsageCriticalPercentage] -| disk.store.disk-usage-warning-percentage | Configures the warning threshold for disk usage as a percentage of the total disk volume. | 90.0 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskUsageWarningPercentage--[EnableDiskStore.diskUsageWarningPercentage] -| disk.store.max-oplog-size | Configures the maximum size in megabytes a single oplog (operation log) is allowed to be. | 1024 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#maxOplogSize--[EnableDiskStore.maxOplogSize] -| disk.store.queue-size | Configures the maximum number of operations that can be asynchronously queued. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#queueSize--[EnableDiskStore.queueSize] -| disk.store.time-interval | Configures the number of milliseconds that can elapse before data written asynchronously is flushed to disk. | 1000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#timeInterval--[EnableDiskStore.timeInterval] -| disk.store.write-buffer-size | Configures the write buffer size in bytes. | 32768 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#writeBufferSize--[EnableDiskStore.writeBufferSize] +| `disk.store.allow-force-compaction` | Whether to allow `DiskStore.forceCompaction()` to be called on Regions that use a disk store. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#allowForceCompaction--[`EnableDiskStore.allowForceCompaction`] +| `disk.store.auto-compact` | Whether to cause the disk files to be automatically compacted. | `true` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#autoCompact--[`EnableDiskStore.autoCompact`] +| `disk.store.compaction-threshold` | The threshold at which an oplog becomes compactible. | `50` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#compactionThreshold--[`EnableDiskStore.compactionThreshold`] +| `disk.store.directory.location` | The system directory where the `DiskStore` (oplog) files are stored. | `[]` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskDirectories--[`EnableDiskStore.diskDirectories.location`] +| `disk.store.directory.size` | The amount of disk space allowed to store disk store (oplog) files. | `21474883647` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskDirectories--[`EnableDiskStore.diskDirectories.size`] +| `disk.store.disk-usage-critical-percentage` | The critical threshold for disk usage as a percentage of the total disk volume. | `99.0` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskUsageCriticalPercentage--[`EnableDiskStore.diskUsageCriticalPercentage`] +| `disk.store.disk-usage-warning-percentage` | The warning threshold for disk usage as a percentage of the total disk volume. | `90.0` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#diskUsageWarningPercentage--[`EnableDiskStore.diskUsageWarningPercentage`] +| `disk.store.max-oplog-size` | The maximum size (in megabytes) a single oplog (operation log) can be. | `1024` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#maxOplogSize--[`EnableDiskStore.maxOplogSize`] +| `disk.store.queue-size` | The maximum number of operations that can be asynchronously queued. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#queueSize--[`EnableDiskStore.queueSize`] +| `disk.store.time-interval` | The number of milliseconds that can elapse before data written asynchronously is flushed to disk. | `1000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#timeInterval--[`EnableDiskStore.timeInterval`] +| `disk.store.write-buffer-size` | Configures the write buffer size in bytes. | `32768` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableDiskStore.html#writeBufferSize--[`EnableDiskStore.writeBufferSize`] |===================================================================================================================== -_DiskStore_ properties can be further targeted at specific _DiskStores_ using the -{apache-geode-javadoc}/org/apache/geode/cache/DiskStore.html#getName--[`DiskStore.name`]. +`DiskStore` properties can be further targeted at specific `DiskStore` instances by setting the +{apache-geode-javadoc}/org/apache/geode/cache/DiskStore.html#getName--[`DiskStore.name`] property. -For instance, you may specify directory location of the files for a specific, named `DiskStore` using: +For example, you can specify directory location of the files for a specific, named `DiskStore` by using: +==== [source,properties] ---- spring.data.gemfire.disk.store.Example.directory.location=/path/to/geode/disk-stores/Example/ ---- +==== -The directory location and size of the _DiskStore_ files can be further divided into multiple locations and size -using array syntax, as in: +The directory location and size of the `DiskStore` files can be further divided into multiple locations and size +using array syntax: +==== [source,properties] ---- spring.data.gemfire.disk.store.Example.directory[0].location=/path/to/geode/disk-stores/Example/one @@ -158,183 +156,174 @@ spring.data.gemfire.disk.store.Example.directory[0].size=4096000 spring.data.gemfire.disk.store.Example.directory[1].location=/path/to/geode/disk-stores/Example/two spring.data.gemfire.disk.store.Example.directory[1].size=8192000 ---- +==== -Both the name and array index are optional and you can use any combination of name and array index. Without a name, -the properties apply to all _DiskStores_. Without array indexes, all [named] _DiskStore_ files will be stored in the -specified location and limited to the defined size. - +Both the name and array index are optional, and you can use any combination of name and array index. Without a name, +the properties apply to all `DiskStore` instances. Without array indexes, all named `DiskStore` files are stored in +the specified location and limited to the defined size. .`spring.data.gemfire.*` Entity properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| entities.base-packages | Comma-delimited list of package names indicating the start points for the entity scan. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableEntityDefinedRegions.html#basePackages--[EnableEntityDefinedRegions.basePackages] +| `entities.base-packages` | Comma-delimited list of package names indicating the start points for the entity scan. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableEntityDefinedRegions.html#basePackages--[`EnableEntityDefinedRegions.basePackages`] |===================================================================================================================== - .`spring.data.gemfire.*` Locator properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| locator.host | Configures the IP address or hostname of the system NIC to which the embedded Locator will be bound to listen for connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLocator.html#host--[EnableLocator.host] -| locator.port | Configures the network port to which the embedded Locator will listen for connections. | 10334 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLocator.html#port--[EnableLocator.port] +| `locator.host` | The IP address or hostname of the system NIC to which the embedded Locator is bound to listen for connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLocator.html#host--[`EnableLocator.host`] +| locator.port | The network port to which the embedded Locator will listen for connections. | `10334` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLocator.html#port--[`EnableLocator.port`] |===================================================================================================================== - .`spring.data.gemfire.*` Logging properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| logging.level | Configures the log-level of an {geode-name} cache; Alias for 'spring.data.gemfire.cache.log-level'. | config | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logLevel--[EnableLogging.logLevel] -| logging.log-disk-space-limit | Configures the amount of disk space allowed to store log files. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logDiskSpaceLimit--[EnableLogging.logDiskSpaceLimit] -| logging.log-file | Configures the pathname of the log file used to log messages. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logFile--[EnableLogging.logFile] -| logging.log-file-size | Configures the maximum size of a log file before the log file is rolled. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logFileSizeLimit--[EnableLogging.logFileSize] +| `logging.level` | The log level of an {geode-name} cache. Alias for 'spring.data.gemfire.cache.log-level'. | `config` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logLevel--[`EnableLogging.logLevel`] +| `logging.log-disk-space-limit` | The amount of disk space allowed to store log files. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logDiskSpaceLimit--[`EnableLogging.logDiskSpaceLimit`] +| `logging.log-file` | The pathname of the log file used to log messages. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logFile--[`EnableLogging.logFile`] +| `logging.log-file-size` | The maximum size of a log file before the log file is rolled. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html#logFileSizeLimit--[`EnableLogging.logFileSize`] |===================================================================================================================== - .`spring.data.gemfire.*` Management properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| management.use-http | Configures whether to use the HTTP protocol to communicate with a {geode-name} Manager. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#useHttp--[EnableClusterConfiguration.useHttp] -| management.http.host | Configures the IP address or hostname of the {geode-name} Manager running the HTTP service. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#host--[EnableClusterConfiguration.host] -| management.http.port | Configures the port used by the {geode-name} Manager's HTTP service to listen for connections. | 7070 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#port--[EnableClusterConfiguration.port] +| `management.use-http` | Whether to use the HTTP protocol to communicate with an {geode-name} Manager. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#useHttp--[`EnableClusterConfiguration.useHttp`] +| `management.http.host` | The IP address or hostname of the {geode-name} Manager that runs the HTTP service. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#host--[`EnableClusterConfiguration.host`] +| `management.http.port` | The port used by the {geode-name} Manager's HTTP service to listen for connections. | `7070` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html#port--[`EnableClusterConfiguration.port`] |===================================================================================================================== - .`spring.data.gemfire.*` Manager properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| manager.access-file | Configures the Access Control List (ACL) file used by the Manager to restrict access to the JMX MBeans by the clients. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#accessFile--[EnableManager.accessFile] -| manager.bind-address | Configures the IP address or hostname of the system NIC used by the Manager to bind and listen for JMX client connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#bindAddress--[EnableManager.bindAddress] -| manager.hostname-for-clients | Configures the hostname given to JMX clients to ask the Locator for the location of the Manager. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#hostnameForClients--[EnableManager.hostNameForClients] -| manager.password-file | By default, the JMX Manager will allow clients without credentials to connect. If this property is set to the name of a file then only clients that connect with credentials that match an entry in this file will be allowed. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#passwordFile--[EnableManager.passwordFile] -| manager.port | Configures the port used by th Manager to listen for JMX client connections. | 1099 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#port--[EnableManager.port] -| manager.start | Configures whether to start the Manager service at runtime. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#start--[EnableManager.start] -| manager.update-rate | Configures the rate, in milliseconds, at which this member will push updates to any JMX Managers. | 2000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#updateRate--[EnableManager.updateRate] +| `manager.access-file` | The access control list (ACL) file used by the Manager to restrict access to the JMX MBeans by the clients. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#accessFile--[`EnableManager.accessFile`] +| manager.bind-address | The IP address or hostname of the system NIC used by the Manager to bind and listen for JMX client connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#bindAddress--[`EnableManager.bindAddress`] +| `manager.hostname-for-clients` | The hostname given to JMX clients to ask the Locator for the location of the Manager. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#hostnameForClients--[`EnableManager.hostNameForClients`] +| `manager.password-file` | By default, the JMX Manager lets clients without credentials connect. If this property is set to the name of a file, only clients that connect with credentials that match an entry in this file are allowed. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#passwordFile--[`EnableManager.passwordFile`] +| `manager.port` | The port used by the Manager to listen for JMX client connections. | `1099` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#port--[`EnableManager.port`] +| `manager.start` | Whether to start the Manager service at runtime. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#start--[`EnableManager.start`] +| `manager.update-rate` | The rate, in milliseconds, at which this member pushes updates to any JMX Managers. | `2000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableManager.html#updateRate--[`EnableManager.updateRate`] |===================================================================================================================== - .`spring.data.gemfire.*` PDX properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| pdx.disk-store-name | Configures the name of the DiskStore used to store PDX type meta-data to disk when PDX is persistent. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#diskStoreName--[EnablePdx.diskStoreName] -| pdx.ignore-unread-fields | Configures whether PDX ignores fields that were unread during deserialization. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#ignoreUnreadFields--[EnablePdx.ignoreUnreadFields] -| pdx.persistent | Configures whether PDX persists type meta-data to disk. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#persistent--[EnablePdx.persistent] -| pdx.read-serialized | Configures whether a Region entry is returned as a PdxInstance or deserialized back into object form on read. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#readSerialized--[EnablePdx.readSerialized] -| pdx.serialize-bean-name | Configures the name of a custom Spring bean implementing org.apache.geode.pdx.PdxSerializer. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#serializerBeanName--[EnablePdx.serializerBeanName] +| `pdx.disk-store-name` | The name of the `DiskStore` used to store PDX type metadata to disk when PDX is persistent. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#diskStoreName--[`EnablePdx.diskStoreName`] +| `pdx.ignore-unread-fields` | Whether PDX ignores fields that were unread during deserialization. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#ignoreUnreadFields--[`EnablePdx.ignoreUnreadFields`] +| `pdx.persistent` | Whether PDX persists type metadata to disk. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#persistent--[`EnablePdx.persistent`] +| `pdx.read-serialized` | Whether a Region entry is returned as a `PdxInstance` or deserialized back into object form on read. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#readSerialized--[`EnablePdx.readSerialized`] +| `pdx.serialize-bean-name` | The name of a custom Spring bean that implements `org.apache.geode.pdx.PdxSerializer`. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePdx.html#serializerBeanName--[`EnablePdx.serializerBeanName`] |===================================================================================================================== - .`spring.data.gemfire.*` Pool properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| pool.free-connection-timeout | Configures the timeout used to acquire a free connection from a Pool. | 10000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#freeConnectionTimeout--[EnablePool.freeConnectionTimeout] -| pool.idle-timeout | Configures the amount of time a connection can be idle before expiring (and closing) the connection. | 5000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#idleTimeout--[EnablePool.idleTimeout] -| pool.load-conditioning-interval | Configures the interval for how frequently the pool will check to see if a connection to a given server should be moved to a different server to improve the load balance. | 300000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#loadConditioningInterval--[EnablePool.loadConditioningInterval] -| pool.locators | Comma-delimited list of Locator endpoints in the format: locator1[port1],...,locatorN[portN] | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#locators--[EnablePool.locators] -| pool.max-connections | Configures the maximum number of client to server connections that a Pool will create. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#maxConnections--[EnablePool.maxConnections] -| pool.min-connections | Configures the minimum number of client to server connections that a Pool will maintain. | 1 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#minConnections--[EnablePool.minConnections] -| pool.multi-user-authentication | Configures whether the created Pool can be used by multiple authenticated users. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#multiUserAuthentication--[EnablePool.multiUserAuthentication] -| pool.ping-interval | Configures how often to ping servers to verify that they are still alive. | 10000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#pingInterval--[EnablePool.pingInterval] -| pool.pr-single-hop-enabled | Configures whether to perform single-hop data access operations between the client and servers. When true the client is aware of the location of partitions on servers hosting Regions with DataPolicy.PARTITION. | true | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#prSingleHopEnabled--[EnablePool.prSingleHopEnabled] -| pool.read-timeout | Configures the number of milliseconds to wait for a response from a server before timing out the operation and trying another server (if any are available). | 10000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#readTimeout--[EnablePool.readTimeout] -| pool.ready-for-events | Configures whether to signal the server that the client is prepared and ready to receive events. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#readyForEvents--[ClientCacheApplication.readyForEvents] -| pool.retry-attempts | Configures the number of times to retry a request after timeout/exception. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#retryAttempts--[EnablePool.retryAttempts] -| pool.server-group | Configures the group that all servers a Pool connects to must belong to. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#serverGroup--[EnablePool.serverGroup] -| pool.servers | Comma-delimited list of CacheServer endpoints in the format: server1[port1],...,serverN[portN] | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#servers--[EnablePool.servers] -| pool.socket-buffer-size | Configures the socket buffer size for each connection made in all Pools. | 32768 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#socketBufferSize--[EnablePool.socketBufferSize] -| pool.statistic-interval | Configures how often to send client statistics to the server. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#statisticInterval--[EnablePool.statisticInterval] -| pool.subscription-ack-interval | Configures the interval in milliseconds to wait before sending acknowledgements to the CacheServer for events received from the server subscriptions. | 100 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionAckInterval--[EnablePool.subscriptionAckInterval] -| pool.subscription-enabled | Configures whether the created Pool will have server-to-client subscriptions enabled. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionEnabled--[EnablePool.subscriptionEnabled] -| pool.subscription-message-tracking-timeout | Configures the messageTrackingTimeout attribute which is the time-to-live period, in milliseconds, for subscription events the client has received from the server. | 900000 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionMessageTrackingTimeout--[EnablePool.subscriptionMessageTrackingTimeout] -| pool.subscription-redundancy | Configures the redundancy level for all Pools server-to-client subscriptions. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionRedundancy--[EnablePool.subsriptionRedundancy] -| pool.thread-local-connections | Configures the thread local connections policy for all Pools. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#threadLocalConnections--[EnablePool.threadLocalConnections] +| `pool.free-connection-timeout` | The timeout used to acquire a free connection from a Pool. | `10000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#freeConnectionTimeout--[`EnablePool.freeConnectionTimeout`] +| `pool.idle-timeout` | The amount of time a connection can be idle before expiring (and closing) the connection. | `5000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#idleTimeout--[`EnablePool.idleTimeout`] +| `pool.load-conditioning-interval` | The interval for how frequently the Pool checks to see if a connection to a given server should be moved to a different server to improve the load balance. | `300000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#loadConditioningInterval--[`EnablePool.loadConditioningInterval`] +| `pool.locators` | Comma-delimited list of locator endpoints in the format of `locator1[port1],...,locatorN[portN]` | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#locators--[`EnablePool.locators`] +| `pool.max-connections` | The maximum number of client to server connections that a Pool will create. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#maxConnections--[EnablePool.maxConnections] +| `pool.min-connections` | The minimum number of client to server connections that a Pool maintains. | `1` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#minConnections--[`EnablePool.minConnections`] +| `pool.multi-user-authentication` | Whether the created Pool can be used by multiple authenticated users. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#multiUserAuthentication--[`EnablePool.multiUserAuthentication`] +| `pool.ping-interval` | How often to ping servers to verify that they are still alive. | `10000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#pingInterval--[`EnablePool.pingInterval`] +| `pool.pr-single-hop-enabled` | Whether to perform single-hop data access operations between the client and servers. When `true`, the client is aware of the location of partitions on servers that host Regions with `DataPolicy.PARTITION`. | `true` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#prSingleHopEnabled--[`EnablePool.prSingleHopEnabled`] +| `pool.read-timeout` | The number of milliseconds to wait for a response from a server before timing out the operation and trying another server (if any are available). | `10000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#readTimeout--[`EnablePool.readTimeout`] +| `pool.ready-for-events` | Whether to signal the server that the client is prepared and ready to receive events. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#readyForEvents--[`ClientCacheApplication.readyForEvents`] +| `pool.retry-attempts` | The number of times to retry a request after timeout/exception. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#retryAttempts--[`EnablePool.retryAttempts`] +| `pool.server-group` | The group that all servers to which a Pool connects must belong. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#serverGroup--[`EnablePool.serverGroup`] +| `pool.servers` | Comma-delimited list of `CacheServer` endpoints in the format of `server1[port1],...,serverN[portN]` | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#servers--[`EnablePool.servers`] +| `pool.socket-buffer-size` | The socket buffer size for each connection made in all Pools. | `32768` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#socketBufferSize--[`EnablePool.socketBufferSize`] +| `pool.statistic-interval` | How often to send client statistics to the server. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#statisticInterval--[`EnablePool.statisticInterval`] +| pool.subscription-ack-interval | The interval in milliseconds to wait before sending acknowledgements to the `CacheServer` for events received from the server subscriptions. | `100` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionAckInterval--[`EnablePool.subscriptionAckInterval`] +| `pool.subscription-enabled` | Whether the created Pool has server-to-client subscriptions enabled. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionEnabled--[`EnablePool.subscriptionEnabled`] +| `pool.subscription-message-tracking-timeout` | The `messageTrackingTimeout` attribute, which is the time-to-live period, in milliseconds, for subscription events the client has received from the server. | `900000` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionMessageTrackingTimeout--[`EnablePool.subscriptionMessageTrackingTimeout`] +| `pool.subscription-redundancy` | The redundancy level for all Pools server-to-client subscriptions. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#subscriptionRedundancy--[`EnablePool.subsriptionRedundancy`] +| `pool.thread-local-connections` | The thread local connections policy for all Pools. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnablePool.html#threadLocalConnections--[`EnablePool.threadLocalConnections`] |===================================================================================================================== - .`spring.data.gemfire.*` Security properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| security.username | Configures the name of the user used to authenticate with the servers. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityUsername--[EnableSecurity.securityUsername] -| security.password | Configures the user password used to authenticate with the servers. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityPassword--[EnableSecurity.securityPassword] -| security.properties-file | Configures the system pathname to a properties file containing security credentials. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#securityPropertiesFile--[EnableAuth.propertiesFile] -| security.client.accessor | X | X | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientAccessor--[EnableAuth.clientAccessor] -| security.client.accessor-post-processor | The callback that should be invoked in the post-operation phase, which is when the operation has completed on the server but before the result is sent to the client. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientAccessorPostProcessor--[EnableAuth.clientAccessorPostProcessor] -| security.client.authentication-initializer | Static creation method returning an AuthInitialize object, which obtains credentials for peers in a cluster. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#clientAuthenticationInitializer--[EnableSecurity.clientAuthentiationInitializer] -| security.client.authenticator | Static creation method returning an Authenticator object used by a cluster member (Locator, Server) to verify the credentials of a connecting client. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientAuthenticator--[EnableAuth.clientAuthenticator] -| security.client.diffie-hellman-algorithm | Used for authentication. For secure transmission of sensitive credentials like passwords, you can encrypt the credentials using the Diffie-Hellman key-exchange algorithm. Do this by setting the security-client-dhalgo system property on the clients to the name of a valid, symmetric key cipher supported by the JDK. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientDiffieHellmanAlgorithm--[EnableAuth.clientDiffieHellmanAlgorithm] -| security.log.file | Configures the pathname to a log file used for security log messages. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#securityLogFile--[EnableAuth.securityLogFile] -| security.log.level | Configures the log-level for security log messages. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#securityLogLevel--[EnableAuth.securityLogLevel] -| security.manager.class-name | Configures name of a class implementing org.apache.geode.security.SecurityManager. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityManagerClassName--[EnableSecurity.securityManagerClassName] -| security.peer.authentication-initializer | Static creation method returning an AuthInitialize object, which obtains credentials for peers in a cluster. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#peerAuthenticationInitializer--[EnableSecurity.peerAuthenticationInitializer] -| security.peer.authenticator | Static creation method returning an Authenticator object, which is used by a peer to verify the credentials of a connecting node. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#peerAuthenticator--[EnableAuth.peerAuthenticator] -| security.peer.verify-member-timeout | Configures the timeout in milliseconds used by a peer to verify membership of an unknown authenticated peer requesting a secure connection. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#peerVerifyMemberTimeout--[EnableAuth.peerVerifyMemberTimeout] -| security.post-processor.class-name | Configures the name of a class implementing the org.apache.geode.security.PostProcessor interface that can be used to change the returned results of Region get operations. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityPostProcessorClassName--[EnableSecurity.securityPostProcessorClassName] -| security.shiro.ini-resource-path | Configures the {geode-name} System Property referring to the location of an Apache Shiro INI file that configures the Apache Shiro Security Framework in order to secure {geode-name}. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#shiroIniResourcePath--[EnableSecurity.shiroIniResourcePath] +| `security.username` | The name of the user used to authenticate with the servers. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityUsername--[`EnableSecurity.securityUsername`] +| `security.password` | The user password used to authenticate with the servers. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityPassword--[`EnableSecurity.securityPassword`] +| `security.properties-file` | The system pathname to a properties file that contains security credentials. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#securityPropertiesFile--[`EnableAuth.propertiesFile`] +| `security.client.accessor` | X | X | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientAccessor--[`EnableAuth.clientAccessor`] +| `security.client.accessor-post-processor` | The callback that should be invoked in the post-operation phase, which is when the operation has completed on the server but before the result is sent to the client. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientAccessorPostProcessor--[`EnableAuth.clientAccessorPostProcessor`] +| `security.client.authentication-initializer` | Static creation method that returns an `AuthInitialize` object, which obtains credentials for peers in a cluster. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#clientAuthenticationInitializer--[`EnableSecurity.clientAuthentiationInitializer`] +| `security.client.authenticator` | Static creation method that returns an `Authenticator` object used by a cluster member (Locator or Server) to verify the credentials of a connecting client. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientAuthenticator--[`EnableAuth.clientAuthenticator`] +| `security.client.diffie-hellman-algorithm` | Used for authentication. For secure transmission of sensitive credentials (such as passwords), you can encrypt the credentials by using the Diffie-Hellman key-exchange algorithm. You can do so by setting the `security-client-dhalgo` system property on the clients to the name of a valid, symmetric key cipher supported by the JDK. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#clientDiffieHellmanAlgorithm--[`EnableAuth.clientDiffieHellmanAlgorithm`] +| `security.log.file` | The pathname to a log file used for security log messages. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#securityLogFile--[`EnableAuth.securityLogFile`] +| `security.log.level` | The log level for security log messages. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#securityLogLevel--[`EnableAuth.securityLogLevel`] +| `security.manager.class-name` | The name of a class that implements `org.apache.geode.security.SecurityManager`. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityManagerClassName--[`EnableSecurity.securityManagerClassName`] +| `security.peer.authentication-initializer` | Static creation method that returns an `AuthInitialize` object, which obtains credentials for peers in a cluster. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#peerAuthenticationInitializer--[`EnableSecurity.peerAuthenticationInitializer`] +| `security.peer.authenticator` | Static creation method that returns an `Authenticator` object, which is used by a peer to verify the credentials of a connecting node. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#peerAuthenticator--[`EnableAuth.peerAuthenticator`] +| security.peer.verify-member-timeout | The timeout in milliseconds used by a peer to verify membership of an unknown authenticated peer requesting a secure connection. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableAuth.html#peerVerifyMemberTimeout--[`EnableAuth.peerVerifyMemberTimeout`] +| `security.post-processor.class-name` | The name of a class that implements the `org.apache.geode.security.PostProcessor` interface that can be used to change the returned results of Region get operations. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#securityPostProcessorClassName--[`EnableSecurity.securityPostProcessorClassName`] +| `security.shiro.ini-resource-path` | The {geode-name} System property that refers to the location of an Apache Shiro INI file that configures the Apache Shiro Security Framework in order to secure {geode-name}. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSecurity.html#shiroIniResourcePath--[`EnableSecurity.shiroIniResourcePath`] |===================================================================================================================== - .`spring.data.gemfire.*` SSL properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| security.ssl.certificate.alias.cluster | Configures the alias to the stored SSL certificate used by the cluster to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[EnableSsl.componentCertificateAliases] -| security.ssl.certificate.alias.default-alias | Configures the default alias to the stored SSL certificate used to secure communications across the entire {geode-name} system. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#defaultCertificateAlias--[EnableSsl.defaultCertificateAlias] -| security.ssl.certificate.alias.gateway | Configures the alias to the stored SSL certificate used by the WAN Gateway Senders/Receivers to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[EnableSsl.componentCertificateAliases] -| security.ssl.certificate.alias.jmx | Configures the alias to the stored SSL certificate used by the Manager's JMX based JVM MBeanServer and JMX clients to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[EnableSsl.componentCertificateAliases] -| security.ssl.certificate.alias.locator | Configures the alias to the stored SSL certificate used by the Locator to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[EnableSsl.componentCertificateAliases] -| security.ssl.certificate.alias.server | Configures the alias to the stored SSL certificate used by clients and servers to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[EnableSsl.componentCertificateAliases] -| security.ssl.certificate.alias.web | Configures the alias to the stored SSL certificate used by the embedded HTTP server to secure communications (HTTPS). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[EnableSsl.componentCertificateAliases] -| security.ssl.ciphers | Comma-separated list of SSL ciphers or “any”. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#ciphers--[EnableSsl.ciphers] -| security.ssl.components | Comma-delimited list of {geode-name} components (e.g. WAN) to be configured for SSL communication. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#components--[EnableSsl.components] -| security.ssl.keystore | Configures the system pathname to the Java KeyStore file storing certificates for SSL. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#keystore--[EnableSsl.keystore] -| security.ssl.keystore.password | Configures the password used to access the Java KeyStore file. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#keystorePassword--[EnableSsl.keystorePassword] -| security.ssl.keystore.type | Configures the password used to access the Java KeyStore file (e.g. JKS). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#keystoreType--[EnableSsl.keystoreType] -| security.ssl.protocols | Comma-separated list of SSL protocols or “any”. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#protocols--[EnableSsl.protocols] -| security.ssl.require-authentication | Configures whether 2-way authentication is required. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#requireAuthentication--[EnableSsl.requireAuthentication] -| security.ssl.truststore | Configures the system pathname to the trust store (Java KeyStore file) storing certificates for SSL. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#truststore--[EnableSsl.truststore] -| security.ssl.truststore.password | Configures the password used to access the trust store (Java KeyStore file). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#truststorePassword--[EnableSsl.truststorePassword] -| security.ssl.truststore.type | Configures the password used to access the trust store (Java KeyStore file; e.g. JKS). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#truststoreType--[EnableSsl.truststoreType] -| security.ssl.web-require-authentication | Configures whether 2-way HTTP authentication is required. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#webRequireAuthentication--[EnableSsl.webRequireAuthentication] +| `security.ssl.certificate.alias.cluster` | The alias to the stored SSL certificate used by the cluster to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[`EnableSsl.componentCertificateAliases`] +| `security.ssl.certificate.alias.default-alias` | The default alias to the stored SSL certificate used to secure communications across the entire {geode-name} system. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#defaultCertificateAlias--[`EnableSsl.defaultCertificateAlias`] +| `security.ssl.certificate.alias.gateway` | The alias to the stored SSL certificate used by the WAN Gateway Senders/Receivers to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[`EnableSsl.componentCertificateAliases`] +| `security.ssl.certificate.alias.jmx` | The alias to the stored SSL certificate used by the Manager's JMX-based JVM MBeanServer and JMX clients to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[`EnableSsl.componentCertificateAliases`] +| `security.ssl.certificate.alias.locator` | The alias to the stored SSL certificate used by the Locator to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[`EnableSsl.componentCertificateAliases`] +| `security.ssl.certificate.alias.server` | The alias to the stored SSL certificate used by clients and servers to secure communications. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[`EnableSsl.componentCertificateAliases`] +| `security.ssl.certificate.alias.web` | The alias to the stored SSL certificate used by the embedded HTTP server to secure communications (HTTPS). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#componentCertificateAliases--[`EnableSsl.componentCertificateAliases`] +| `security.ssl.ciphers` | Comma-separated list of SSL ciphers or `any`. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#ciphers--[`EnableSsl.ciphers`] +| `security.ssl.components` | Comma-delimited list of {geode-name} components (for example, WAN) to be configured for SSL communication. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#components--[`EnableSsl.components`] +| `security.ssl.keystore` | The system pathname to the Java KeyStore file storing certificates for SSL. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#keystore--[`EnableSsl.keystore`] +| `security.ssl.keystore.password` | The password used to access the Java KeyStore file. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#keystorePassword--[`EnableSsl.keystorePassword`] +| `security.ssl.keystore.type` | The password used to access the Java KeyStore file (for example, JKS). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#keystoreType--[`EnableSsl.keystoreType`] +| `security.ssl.protocols` | Comma-separated list of SSL protocols or `any`. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#protocols--[`EnableSsl.protocols`] +| `security.ssl.require-authentication` | Whether two-way authentication is required. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#requireAuthentication--[`EnableSsl.requireAuthentication`] +| `security.ssl.truststore` | The system pathname to the trust store (Java KeyStore file) that stores certificates for SSL. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#truststore--[`EnableSsl.truststore`] +| `security.ssl.truststore.password` | The password used to access the trust store (Java KeyStore file). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#truststorePassword--[`EnableSsl.truststorePassword`] +| `security.ssl.truststore.type` | The password used to access the trust store (Java KeyStore file -- for example, JKS). | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#truststoreType--[`EnableSsl.truststoreType`] +| `security.ssl.web-require-authentication` | Whether two-way HTTP authentication is required. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html#webRequireAuthentication--[`EnableSsl.webRequireAuthentication`] |===================================================================================================================== - .`spring.data.gemfire.*` Service properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| service.http.bind-address | Configures the IP address or hostname of the system NIC used by the embedded HTTP server to bind and listen for HTTP(S) connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#bindAddress--[EnableHttpService.bindAddress] -| service.http.port | Configures the port used by the embedded HTTP server to listen for HTTP(S) connections. | 7070 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#port--[EnableHttpService.port] -| service.http.ssl-require-authentication | Configures whether 2-way HTTP authentication is required. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#sslRequireAuthentication--[EnableHttpService.sslRequireAuthentication] -| service.http.dev-rest-api-start | Configures whether to start the Developer REST API web service. A full installation of {geode-name} is required and you must set the $GEODE environment variable. | false | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#startDeveloperRestApi--[EnableHttpService.startDeveloperRestApi] -| service.memcached.port | Configures the port of the embedded Memcached server (service). | 11211| {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.html#port--[EnableMemcachedServer.port] -| service.memcached.protocol | Configures the protocol used by the embedded Memcached server (service). | ASCII | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.html#protocol--[EnableMemcachedServer.protocol] -| service.redis.bind-address | Configures the IP address or hostname of the system NIC used by the embedded Redis server to bind an listen for connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableRedisServer.html#bindAddress--[EnableRedis.bindAddress] -| service.redis.port | Configures the port used by the embedded Redis server to listen for connections. | 6479 | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableRedisServer.html#port--[EnableRedisServer.port] +| `service.http.bind-address` | The IP address or hostname of the system NIC used by the embedded HTTP server to bind and listen for HTTP(S) connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#bindAddress--[`EnableHttpService.bindAddress`] +| `service.http.port` | The port used by the embedded HTTP server to listen for HTTP(S) connections. | `7070` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#port--[`EnableHttpService.port`] +| `service.http.ssl-require-authentication` | Whether two-way HTTP authentication is required. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#sslRequireAuthentication--[`EnableHttpService.sslRequireAuthentication`] +| `service.http.dev-rest-api-start` | Whether to start the Developer REST API web service. A full installation of {geode-name} is required, and you must set the `$GEODE` environment variable. | `false` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableHttpService.html#startDeveloperRestApi--[`EnableHttpService.startDeveloperRestApi`] +| `service.memcached.port` | The port of the embedded Memcached server (service). | `11211`| {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.html#port--[`EnableMemcachedServer.port`] +| `service.memcached.protocol` | The protocol used by the embedded Memcached server (service). | `ASCII` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableMemcachedServer.html#protocol--[`EnableMemcachedServer.protocol`] +| `service.redis.bind-address` | The IP address or hostname of the system NIC used by the embedded Redis server to bind and listen for connections. | | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableRedisServer.html#bindAddress--[`EnableRedis.bindAddress`] +| `service.redis.port` | The port used by the embedded Redis server to listen for connections. | `6479` | {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableRedisServer.html#port--[`EnableRedisServer.port`] |===================================================================================================================== @@ -342,31 +331,29 @@ specified location and limited to the defined size. [[geode-configuration-metadata-springsession]] === Spring Session Based Properties -The following properties all have a `spring.session.data.gemfire.*` prefix. For example, to set the Session Region -name, use `spring.session.data.gemfire.session.region.name` in Spring Boot `application.properties`. - +The following properties all have a `spring.session.data.gemfire.*` prefix. For example, to set the session Region name, +set `spring.session.data.gemfire.session.region.name` in Spring Boot `application.properties`. .`spring.session.data.gemfire.*` properties [width="90%",options="header"] |===================================================================================================================== | Name | Description | Default | From -| cache.client.pool.name | Name of the Pool used to send data access operations between the client and server(s). | gemfirePool | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#poolName--[EnableGemFireHttpSession.poolName] -| cache.client.region.shortcut | Configures the DataPolicy used by the client Region to manage (HTTP) Session state. | {apache-geode-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html#PROXY[ClientRegionShortcut.PROXY] | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#clientRegionShortcut--[EnableGemFireHttpSession.clientRegionShortcut] -| cache.server.region.shortcut | Configures the DataPolicy used by the server Region to manage (HTTP) Session state. | {apache-geode-javadoc}/org/apache/geode/cache/RegionShortcut.html#PARTITION[RegionShortcut.PARTITION] | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#serverRegionShortcut--[EnableGemFireHttpSession.serverRegionShortcut] -| session.attributes.indexable | Configures names of Session attributes for which an Index will be created. | [] | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#indexableSessionAttributes--[EnableGemFireHttpSession.indexableSessionAttributes] -| session.expiration.max-inactive-interval-seconds | Configures the number of seconds in which a Session can remain inactive before it expires. | 1800 | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#maxInactiveIntervalSeconds--[EnableGemFireHttpSession.maxInactiveIntervalSeconds] -| session.region.name | Configures name of the (client/server) Region used to manage (HTTP) Session state. | ClusteredSpringSessions | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#regionName--[EnableGemFireHttpSession.regionName] -| session.serializer.bean-name | Configures the name of a Spring bean implementing org.springframework.session.data.gemfire.serialization.SessionSerializer. | | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#sessionSerializerBeanName--[EnableGemFireHttpSession.sessionSerializerBeanName] +| `cache.client.pool.name` | Name of the pool used to send data access operations between the client and servers. | `gemfirePool` | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#poolName--[`EnableGemFireHttpSession.poolName`] +| `cache.client.Region.shortcut` | The `DataPolicy` used by the client Region to manage (HTTP) session state. | {apache-geode-javadoc}/org/apache/geode/cache/client/ClientRegionShortcut.html#PROXY[`ClientRegionShortcut.PROXY`] | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#clientRegionShortcut--[`EnableGemFireHttpSession.clientRegionShortcut`] +| `cache.server.Region.shortcut` | The `DataPolicy` used by the server Region to manage (HTTP) session state. | {apache-geode-javadoc}/org/apache/geode/cache/RegionShortcut.html#PARTITION[`RegionShortcut.PARTITION`] | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#serverRegionShortcut--[`EnableGemFireHttpSession.serverRegionShortcut`] +| `session.attributes.indexable` | The names of session attributes for which an Index is created. | `[]` | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#indexableSessionAttributes--[`EnableGemFireHttpSession.indexableSessionAttributes`] +| `session.expiration.max-inactive-interval-seconds` | Configures the number of seconds in which a session can remain inactive before it expires. | `1800` | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#maxInactiveIntervalSeconds--[`EnableGemFireHttpSession.maxInactiveIntervalSeconds`] +| `session.Region.name` | The name of the (client/server) Region used to manage (HTTP) session state. | `ClusteredSpringSessions` | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#RegionName--[`EnableGemFireHttpSession.RegionName`] +| `session.serializer.bean-name` | The name of a Spring bean that implements `org.springframework.session.data.gemfire.serialization.SessionSerializer`. | | {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/EnableGemFireHttpSession.html#sessionSerializerBeanName--[`EnableGemFireHttpSession.sessionSerializerBeanName`] |===================================================================================================================== [[geode-configuration-metadata-apachegeode]] === {geode-name} Properties -While it is not recommended to use {geode-name} properties directly in your Spring applications, SBDG will not prevent -you from doing so. A complete reference to the {geode-name} specific properties can be found -{apache-geode-docs}/reference/topics/gemfire_properties.html[here]. +While we do not recommend using {geode-name} properties directly in your Spring applications, SBDG does not prevent you +from doing so. See the {apache-geode-docs}/reference/topics/gemfire_properties.html[complete reference to the {geode-name} specific properties]. -WARNING: {geode-name} is very strict about the properties that maybe specified in a `gemfire.properties` file. You -cannot mix Spring properties with `gemfire.*` properties in an {geode-name} `gemfire.properties` file. +WARNING: {geode-name} is very strict about the properties that may be specified in a `gemfire.properties` file. +You cannot mix Spring properties with `gemfire.*` properties in an {geode-name} `gemfire.properties` file. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/continuous-query.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/continuous-query.adoc index e6a25dd6..dae69807 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/continuous-query.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/continuous-query.adoc @@ -3,31 +3,32 @@ :geode-name: {apache-geode-name} -Arguably, the most invaluable of applications are those that can process a stream of events as they happen, -and intelligently react in near real-time to the countless changes in the data over time. The most useful -of frameworks are those that can make processing a stream of events as they happen, as easy as possible. +Some applications must process a stream of events as they happen and intelligently react in (near) real-time to +the countless changes in the data over time. Those applications need frameworks that can make processing a stream +of events as they happen as easy as possible. Spring Boot for {geode-name} does just that, without users having to perform any complex setup or configure any -necessary infrastructure components to enable such functionality. Developers can simply define the criteria for the -data they are interested in and implement a handler to process the stream of events as they occur. +necessary infrastructure components to enable such functionality. Developers can define the criteria for the +data of interest and implement a handler (listener) to process the stream of events as they occur. -{geode-name} make defining criteria for data of interests easy when using -{apache-geode-docs}/developing/continuous_querying/chapter_overview.html[Continuous Query (CQ)]. With CQ, you can -express the criteria matching the data of interests using a query predicate. {geode-name} implements -the {apache-geode-docs}/developing/querying_basics/query_basics.html[Object Query Language (OQL)] for defining -and executing queries. OQL is not unlike SQL, and supports projections, query predicates, ordering and aggregates. -And, when used in CQs, they execute continuously, firing events when the data changes in such ways as to match -the criteria expressed in the query predicate. +{apache-geode-docs}/developing/continuous_querying/chapter_overview.html[Continuous Query (CQ)] lets you +easily define your criteria for the data you need. With CQ, you can express the criteria that match the data you need +by specifying a query predicate. {geode-name} implements the +{apache-geode-docs}/developing/querying_basics/query_basics.html[Object Query Language (OQL)] +for defining and executing queries. OQL resembles SQL and supports projections, query predicates, ordering, +and aggregates. Also, when used in CQs, they execute continuously, firing events when the data changes in such ways +as to match the criteria expressed in the query predicate. -Spring Boot for {geode-name} combines the ease of expressing interests in data using an OQL query statement with -implementing the listener handler callback, in 1 easy step. +Spring Boot for {geode-name} combines the ease of identifying the data you need by using an OQL query statement with +implementing the listener callback (handler) in one easy step. -For example, suppose we want to perform some follow up action anytime a customer's financial loan application -is either approved or denied. +For example, suppose you want to perform some follow-up action when a customer's financial loan application is either +approved or denied. -First, the application model for our `EligibilityDecision` class might look something like: +First, the application model for our `EligibilityDecision` class might look something like the following: .EligibilityDecision class +==== [source,java] ---- @Region("EligibilityDecisions") @@ -48,16 +49,17 @@ class EligibilityDecision { } } ---- +==== -Then, we can implement and declare our CQ event handler methods to be notified when a decision -is either APPROVED or DENIED: +Then we can implement and declare our CQ event handler methods to be notified when an eligibility decision is either +`APPROVED` or `DENIED`: +==== [source,java] ---- @Component class EligibilityDecisionPostProcessor { - @ContinuousQuery(name = "ApprovedDecisionsHandler", query = "SELECT decisions.* FROM /EligibilityDecisions decisions @@ -75,12 +77,14 @@ class EligibilityDecisionPostProcessor { } } ---- +==== -Thus, anytime eligibility is processed and a decision as been made, either approved or denied, our application -will get notified, and as an application developer, you are free to code your handler and respond to the event -anyway you like. And, because our Continuous Query handler class is a component, or bean in the Spring -`ApplicationContext`, you can auto-wire any other beans necessary to carry out the application's intended function. +Thus, when eligibility is processed and a decision has been made, either approved or denied, our application gets +notified, and as an application developer, you are free to code your handler and respond to the event any way you like. +Also, because our Continuous Query (CQ) handler class is a component (or a bean in the Spring `ApplicationContext`) +you can auto-wire any other beans necessary to carry out the application's intended function. -This is not unlike Spring's {spring-framework-docs}/integration.html#jms-annotated[Annotation-driven listener endpoints] -used in (JMS) message listeners/handlers, except in Spring Boot for {geode-name}, you do not need to do anything special -to enable this functionality. Just declare the `@ContinuousQuery` annotation on any POJO method and off you go. +This is not unlike Spring's {spring-framework-docs}/integration.html#jms-annotated[annotation-driven listener endpoints], +which are used in (JMS) message listeners and handlers, except in Spring Boot for {geode-name}, you need not do anything +special to enable this functionality. You can declare the `@ContinuousQuery` annotation on any POJO method and go to +work on other things. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/data-serialization.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/data-serialization.adoc index 37c35706..831426fe 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/data-serialization.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/data-serialization.adoc @@ -3,62 +3,65 @@ :geode-name: {apache-geode-name} -Anytime data is overflowed or persisted to disk, transferred between clients and servers, peers in a cluster or between -different clusters in a multi-site topology, then all data stored in {geode-name} must be serializable. +Anytime data is overflowed or persisted to disk, transferred between clients and servers, transferred between peers +in a cluster or between different clusters in a multi-site WAN topology, all data stored in {geode-name} must be +serializable. -To serialize objects in Java, object types must implement the `java.io.Serializable` interface. However, if you have -a large number of application domain object types that currently do not implement `java.io.Serializable`, then -refactoring hundreds or even thousands of class types to implement `Serializable` would be a tedious task just to -store and manage those objects in {geode-name}. +To serialize objects in Java, object types must implement the `java.io.Serializable` interface. However, if you have a +large number of application domain object types that currently do not implement `java.io.Serializable`, refactoring +hundreds or even thousands of class types to implement `java.io.Serializable` would be a tedious task just to store +and manage those objects in {geode-name}. -Additionally, it is not just your application domain object types you necessarily need to worry about either. If you -used 3rd party libraries in your application domain model, any types referred to by your application domain object types -stored in {geode-name} must be serializable too. This type explosion may bleed into class types for which you may have +Additionally, it is not only your application domain object types you necessarily need to consider. If you used +third-party libraries in your application domain model, any types referred to by your application domain object types +stored in {geode-name} must also be serializable. This type explosion may bleed into class types for which you may have no control over. -Furthermore, Java serialization is not the most efficient format given that meta-data about your types is stored with -the data itself. Therefore, even though Java serialized bytes are more descriptive, it adds a great deal of overhead. +Furthermore, Java serialization is not the most efficient format, given that metadata about your types is stored with +the data itself. Therefore, even though Java serialized bytes are more descriptive, it adds a great deal of overhead. -Then, along came serialization using {geode-name}'s {apache-geode-docs}/developing/data_serialization/gemfire_pdx_serialization.html[PDX] -format. PDX stands for _Portable Data Exchange_, and achieves 4 goals: +Then, along came serialization using {geode-name}'s +{apache-geode-docs}/developing/data_serialization/gemfire_pdx_serialization.html[PDX] format. +PDX stands for Portable Data Exchange and achieves four goals: -1. Separates type meta-data from the data itself making the bytes more efficient during transfer. {geode-name} maintains -a type registry storing type meta-data about the objects serialized using PDX. +* Separates type metadata from the data itself, streamlining the bytes during transfer. {geode-name} maintains a type +registry that stores type metadata about the objects serialized with PDX. -2. Supports versioning as your application domain types evolve. It is not uncommon to have old and new applications -deployed to production, running simultaneously, sharing data, and possibly using different versions of the same domain -types. PDX allows fields to be added or removed while still preserving interoperability between old and new application -clients without loss of data. +* Supports versioning as your application domain types evolve. It is common to have old and new versions of the same +application deployed to production, running simultaneously, sharing data, and possibly using different versions of the +same domain types. PDX lets fields be added or removed while still preserving interoperability between old and new +application clients without loss of data. -3. Enables objects stored as PDX bytes to be queried without being de-serialized. Constant de/serialization of data -is a resource intensive task adding to the latency of each data request when redundancy is enabled. Since data must be -replicated across peers in the cluster to preserve High Availability (HA), and serialized to be transferred, keeping -data serialized is more efficient when data is updated frequently since it will likely need to be transferred again -in order to maintain consistency in the face of redundancy and availability. +* Enables objects stored as PDX to be queried without being de-serialized. Constant serialization and deserialization of +data is a resource-intensive task that adds to the latency of each data request when redundancy is enabled. Since data +is replicated across peers in the cluster to preserve High Availability (HA) and must be serialized to be transferred, +keeping data serialized is more efficient when data is updated frequently, since it is likely the data will need to be +transferred again in order to maintain consistency in the face of redundancy and availability. -4. Enables interoperability between native language clients (e.g. C/C++/C#) and Java language clients, with each +* Enables interoperability between native language clients (such as C, C++ and C#) and Java language clients, with each being able to access the same data set regardless from where the data originated. -However, PDX is not without its limitations either. +However, PDX does have limitations. -For instance, unlike Java serialization, PDX does not handle cyclic dependencies. Therefore, you must be careful -how you structure and design your application domain object types. +For instance, unlike Java serialization, PDX does not handle cyclic dependencies. Therefore, you must be careful how you +structure and design your application domain object types. Also, PDX cannot handle field type changes. Furthermore, while {geode-name}'s general {apache-geode-docs}/developing/data_serialization/gemfire_data_serialization.html[Data Serialization] -handles {apache-geode-docs}/developing/delta_propagation/chapter_overview.html[deltas], this is not achievable without -de-serializing the object bytes since it involves a method invocation, which defeats 1 of the key benefits of PDX, -preserving format to avoid the cost of de/serialization. +handles {apache-geode-docs}/developing/delta_propagation/chapter_overview.html[Deltas], this is not achievable without +de-serializing the object, since it involves a method invocation, which defeats one of the key benefits of PDX: +preserving format to avoid the cost of serialization and deserialization. -However, we think the benefits of using PDX greatly outweigh the limitations and therefore have enabled PDX by default -when using Spring Boot for {geode-name}. +However, we think the benefits of using PDX outweigh the limitations and, therefore, have enabled PDX by default. -There is nothing special you need to do. Simply code your types and rest assured that objects of those types will be -properly serialized when overflowed/persisted to disk, transferred between clients and servers, or peers in a cluster -and even when data is transferred over the WAN when using {geode-name}'s multi-site topology. +You need do nothing special. You can code your domain types and rest assured that objects of those domain types are +properly serialized when overflowed and persisted to disk, transferred between clients and servers, transferred between +peers in a cluster, and even when data is transferred over the network when you use {geode-name}'s multi-site WAN +topology. .EligibilityDecision is automatically serialiable without implementing Java Serializable. +==== [source,java] ---- @Region("EligibilityDecisions") @@ -66,52 +69,57 @@ class EligibilityDecision { // ... } ---- +==== -TIP: {geode-name} does {apache-geode-docs}/developing/data_serialization/java_serialization.html[support] the standard +NOTE: {geode-name} does {apache-geode-docs}/developing/data_serialization/java_serialization.html[support] the standard Java Serialization format. === SDG `MappingPdxSerializer` vs. {geode-name}'s `ReflectionBasedAutoSerializer` Under-the-hood, Spring Boot for {geode-name} {spring-data-geode-docs-html}/#bootstrap-annotation-config-pdx[enables] -and uses Spring Data for {geode-name}'s {spring-data-geode-javadoc}/org/springframework/data/gemfire/mapping/MappingPdxSerializer.html[MappingPdxSerializer] -to serialize your application domain objects using PDX. +and uses Spring Data for {geode-name}'s +{spring-data-geode-javadoc}/org/springframework/data/gemfire/mapping/MappingPdxSerializer.html[`MappingPdxSerializer`] +to serialize your application domain objects with PDX. -TIP: Refer to the SDG {spring-data-geode-docs-html}/#mapping.pdx-serializer[Reference Guide] for more details +TIP: See the SDG {spring-data-geode-docs-html}/#mapping.pdx-serializer[Reference Guide] for more details on the `MappingPdxSerializer` class. -The `MappingPdxSerializer` offers several advantages above and beyond {geode-name}'s own -{apache-geode-javadoc}/org/apache/geode/pdx/ReflectionBasedAutoSerializer.html[ReflectionBasedAutoSerializer] class. +The `MappingPdxSerializer` class offers several advantages above and beyond {geode-name}'s own +{apache-geode-javadoc}/org/apache/geode/pdx/ReflectionBasedAutoSerializer.html[`ReflectionBasedAutoSerializer`] class. -TIP: Refer to {geode-name}'s {apache-geode-docs}/developing/data_serialization/auto_serialization.html[User Guide] +TIP: See {geode-name}'s {apache-geode-docs}/developing/data_serialization/auto_serialization.html[User Guide] for more details about the `ReflectionBasedAutoSerializer`. -The SDG `MappingPdxSerializer` offers the following capabilities: +The SDG `MappingPdxSerializer` class offers the following benefits and capabilities: -1. PDX serialization is based on Spring Data's powerful mapping infrastructure and meta-data, as such... +* PDX serialization is based on Spring Data's powerful mapping infrastructure and metadata. -2. Includes support for both `includes` and `excludes` with {spring-data-geode-docs-html}/#mapping.pdx-serializer.type-filtering[type filtering]. -Additionally, type filters can be implemented using Java's `java.util.function.Predicate` interface as opposed to -{geode-name}'s limited regex capabilities provided by the `ReflectionBasedAutoSerializer` class. By default, +* Includes support for both `includes` and `excludes` with first-class +{spring-data-geode-docs-html}/#mapping.pdx-serializer.type-filtering[type filtering]. +Additionally, you can implement type filters by using Java's `java.util.function.Predicate` interface as opposed to +the limited regex capabilities provided by {geode-name}'s `ReflectionBasedAutoSerializer` class. By default, `MappingPdxSerializer` excludes all types in the following packages: `java`, `org.apache.geode`, `org.springframework` -& `com.gemstone.gemfire`. +and `com.gemstone.gemfire`. -3. Handles {spring-data-geode-docs-html}/#mapping.pdx-serializer.transient-properties[transient object fields & properties] -when either Java's `transient` keyword or Spring Data's `@Transient` annotation is used. +* Handles {spring-data-geode-docs-html}/#mapping.pdx-serializer.transient-properties[transient object fields +and properties] when either Java's `transient` keyword or Spring Data's `@Transient` annotation is used. -4. Handles {spring-data-geode-docs-html}/#mapping.pdx-serializer.read-only-properties[read-only object properties]. +* Handles {spring-data-geode-docs-html}/#mapping.pdx-serializer.read-only-properties[read-only object properties]. -5. Automatically determines the identifier of your entities when you annotate the appropriate entity field or property -with Spring Data's {spring-data-commons-javadoc}/org/springframework/data/annotation/Id.html[@Id] annotation. +* Automatically determines the identifier of your entities when you annotate the appropriate entity field or property +with Spring Data's {spring-data-commons-javadoc}/org/springframework/data/annotation/Id.html[`@Id`] annotation. -6. Allows `o.a.g.pdx.PdxSerializers` to be registered in order to {spring-data-geode-docs-html}/#mapping.pdx-serializer.custom-serialization[customize the serialization] -of nested entity field/property types. +* Lets additional `o.a.g.pdx.PdxSerializers` be registered to +{spring-data-geode-docs-html}/#mapping.pdx-serializer.custom-serialization[customize the serialization] +of nested entity/object field and property types. -Number two above deserves special attention since the `MappingPdxSerializer` "excludes" all Java, Spring and {geode-name} -types, by default. But, what happens when you need to serialize 1 of those types? +The support for `includes` and `excludes` deserves special attention, since the `MappingPdxSerializer` excludes all Java, +Spring, and {geode-name} types, by default. However, what happens when you need to serialize one of those types? -For example, suppose you need to be able to serialize objects of type `java.security.Principal`. Well, then you can -override the excludes by registering an "include" type filter, like so: +For example, suppose you need to serialize objects of type `java.security.Principal`. Then you can override the excludes +by registering an `include` type filter: +==== [source,java] ---- package example.app; @@ -139,6 +147,7 @@ class SpringBootApacheGeodeClientCacheApplication { } } ---- +==== -TIP: Normally, you do not need to explicitly declare SDG's `@EnablePdx` annotation to enable and configure PDX. -However, if you want to override auto-configuration, as we have demonstrated above, then this is what you must do. +TIP: Normally, you need not explicitly declare SDG's `@EnablePdx` annotation to enable and configure PDX. However, +if you want to override auto-configuration, as we have demonstrated above, you must do this. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/data.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/data.adoc index c3438939..a4d43f5e 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/data.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/data.adoc @@ -4,71 +4,76 @@ One of the most important tasks during development is ensuring your Spring Boot application handles data correctly. -In order to verify the accuracy, integrity and availability of your data, your application needs data to work with. +To verify the accuracy, integrity, and availability of your data, your application needs data with which to work. -For those already familiar with Spring Boot's support for {spring-boot-docs-html}/howto.html#howto-initialize-a-database-using-spring-jdbc[SQL database initialization], +For those of you already familiar with Spring Boot's support for +{spring-boot-docs-html}/howto.html#howto-initialize-a-database-using-spring-jdbc[SQL database initialization], the approach when using {geode-name} should be easy to understand. {geode-name} provides built-in support, similar in function to Spring Boot's SQL database initialization, by using: -* _Gfsh's_ {apache-geode-docs}/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_C7DB8A800D6244AE8FF3ADDCF139DCE4[import/export] data commands. -* {apache-geode-docs}/managing/cache_snapshots/chapter_overview.html[Snapshot Service] -* {apache-geode-docs}/developing/storing_data_on_disk/chapter_overview.html[Persistence] with {apache-geode-docs}/managing/disk_storage/chapter_overview.html[Disk Storage] +* Gfsh's {apache-geode-docs}/tools_modules/gfsh/quick_ref_commands_by_area.html#topic_C7DB8A800D6244AE8FF3ADDCF139DCE4[import/export] data commands. +* {apache-geode-docs}/managing/cache_snapshots/chapter_overview.html[Snapshot service] +* {apache-geode-docs}/developing/storing_data_on_disk/chapter_overview.html[Persistence] with {apache-geode-docs}/managing/disk_storage/chapter_overview.html[disk storage] -For example, by enabling Persistence with Disk Storage, you could {apache-geode-docs}/managing/disk_storage/backup_restore_disk_store.html[backup and restore] +For example, by enabling persistence with disk storage, you could +{apache-geode-docs}/managing/disk_storage/backup_restore_disk_store.html[backup and restore] persistent `DiskStore` files from one cluster to another. -Alternatively, using {geode-name}'s _Snapshot Service_, you can export data contained in targeted `Regions` from one -cluster during shutdown and import the data into another cluster on startup. The _Snapshot Service_ allows you to filter -data while its being imported and exported. +Alternatively, using {geode-name}'s Snapshot Service, you can export data contained in targeted `Regions` from one +cluster during shutdown and import the data into another cluster on startup. The Snapshot Service lets you filter data +while it is being imported and exported. -Finally, {geode-name} Shell (_Gfsh_) commands can be used to {spring-data-geode-docs-html}/tools_modules/gfsh/command-pages/export.html#topic_263B70069BFC4A7185F86B3272011734[export data] +Finally, you can use {geode-name} shell (Gfsh) commands to +{spring-data-geode-docs-html}/tools_modules/gfsh/command-pages/export.html#topic_263B70069BFC4A7185F86B3272011734[export data] and {apache-geode-docs}/tools_modules/gfsh/command-pages/import.html#topic_jw2_2ld_2l[import data]. -TIP: Spring Data for {geode-name} (SDG) contains dedicated support for {spring-data-geode-docs-html}/#bootstrap:region:persistence[Persistence] +TIP: Spring Data for {geode-name} (SDG) contains dedicated support for +{spring-data-geode-docs-html}/#bootstrap:region:persistence[persistence] and the {spring-data-geode-docs-html}/#bootstrap:snapshot[Snapshot Service]. -In all cases, the files generated by _persistence_, the _Snapshot Service_ and _Gfsh's_ `export` command are in a -proprietary, binary format. +In all cases, the files generated by persistence, the Snapshot Service and Gfsh's `export` command are in a proprietary +binary format. Furthermore, none of these approaches are as convenient as Spring Boot's database initialization automation. Therefore, Spring Boot for {geode-name} (SBDG) offers support to import data from JSON into {geode-name} as PDX. -Unlike Spring Boot, SBDG offers support to export data as well. Data is imported and exported in JSON format, by default. +Unlike Spring Boot, SBDG offers support to export data as well. By default, data is imported and exported in JSON format. NOTE: SBDG does not provide an equivalent to Spring Boot's `schema.sql` file. The best way to define the data structures -(i.e. `Regions`) managing your data is with SDG's Annotation-based configuration support for defining cache `Regions` -from your application's {spring-data-geode-docs-html}/#bootstrap-annotation-config-regions[entity classes] or indirectly -from Spring and JSR-107, JCache {spring-data-geode-docs-html}/#bootstrap-annotation-config-caching[caching annotations]. +(the `Region` instances) that manage your data is with SDG's annotation-based configuration support for defining cache +`Region` instances from your application's {spring-data-geode-docs-html}/#bootstrap-annotation-config-regions[entity classes] +or indirectly from Spring and JSR-107 or JCache {spring-data-geode-docs-html}/#bootstrap-annotation-config-caching[caching annotations]. -TIP: Refer to SBDG's <> on the same. +TIP: See SBDG's <> on the same. -WARNING: While this feature has utility and many edge cases were thought through and tested thoroughly, there are still -some limitations that need to be ironed out. See https://github.com/spring-projects/spring-boot-data-geode/issues/82[Issue-82] -and https://github.com/spring-projects/spring-boot-data-geode/issues/83[Issue-83] for more details. The Spring team -strongly recommends that this feature only be used for development and testing purposes. +WARNING: While this feature works and many edge cases were thought through and tested thoroughly, there are still some +limitations that need to be ironed out. See https://github.com/spring-projects/spring-boot-data-geode/issues/82[issue-82] +and https://github.com/spring-projects/spring-boot-data-geode/issues/83[issue-83] for more details. The Spring team +strongly recommends that this feature be used only for development and testing purposes. [[geode-data-using-import]] === Importing Data -You can import data into a `Region` by defining a JSON file containing the JSON object(s) you wish to load. The JSON -file must follow the naming convention below and be placed in the root of your application classpath: +You can import data into a `Region` by defining a JSON file that contain the JSON objects you wish to load. The JSON +file must follow a predefined naming convention and be placed in the root of your application classpath: `data-.json` -NOTE: `` refers to the lowercase "name" of the `Region` as defined by -{apache-geode-javadoc}/org/apache/geode/cache/Region.html#getName--[Region.getName()]. +NOTE: `` refers to the lowercase "name" of the `Region`, as defined by +{apache-geode-javadoc}/org/apache/geode/cache/Region.html#getName--[`Region.getName()`]. -For example, if you have a `Region` named "_Orders_", then you would create a JSON file called `data-orders.json` -and place it in the root of your application classpath (e.g. in `src/test/resources`). +For example, if you have a `Region` named "Orders", you would create a JSON file called `data-orders.json` and place it +in the root of your application classpath (for example, in `src/test/resources`). -Create JSON files for each `Region` implicitly defined (e.g. by using `@EnableEntityDefinedRegions`) or explicitly -defined (i.e. with `ClientRegionFactoryBean` in _JavaConfig_) in your Spring Boot application configuration that you -want to load with data. +Create JSON files for each `Region` that is implicitly defined (for example, by using `@EnableEntityDefinedRegions`) +or explicitly defined (with `ClientRegionFactoryBean` in Java configuration) in your Spring Boot application +configuration that you want to load with data. -The JSON file containing JSON data for _Orders_ might appear as follows: +The JSON file that contains JSON data for the "Orders" `Region` might appear as follows: .`data-orders.json` +==== [source,json] ---- [{ @@ -113,10 +118,13 @@ The JSON file containing JSON data for _Orders_ might appear as follows: ] }] ---- +==== -The application entity classes matching the JSON data might look something like: +The application entity classes that matches the JSON data from the JSON file might look something like the following +listing: -.Point-of-Sale (POS) Application Model Classes +.Point-of-Sale (POS) Application Domain Model Classes +==== [source,java] ---- @Region("Orders") @@ -145,26 +153,29 @@ class Product { } ---- +==== -As seen above, the object model and corresponding JSON can be arbitrarily complex with a hierarchy of objects -having complex types. +As the preceding listings show, the object model and corresponding JSON can be arbitrarily complex with a hierarchy of +objects that have complex types. [[geode-data-using-import-metadata]] ==== JSON metadata -You will notice a few other details contained in the object model and JSON shown above. +We want to draw your attention to a few other details contained in the object model and JSON shown +<>. [[geode-data-using-import-metadata-attype]] ===== The `@type` metadata field -First, we declared an `@type` JSON metadata field. This field does not map to any specific field or property of -the application domain model class (e.g. `PurchaseOrder`). Rather, it tells the framework and {geode-name}'s JSON/PDX -converter the type of object the JSON data would map to if you were to request an object (i.e. by calling +First, we declared a `@type` JSON metadata field. This field does not map to any specific field or property of +the application domain model class (such as `PurchaseOrder`). Rather, it tells the framework and {geode-name}'s JSON/PDX +converter the type of object the JSON data would map to if you were to request an object (by calling `PdxInstance.getObject()`). -For example: +Consider the following example: .Deserializing PDX as an Object +==== [source,java] ---- @Repository @@ -183,31 +194,35 @@ class OrdersRepository { } } ---- +==== Basically, the `@type` JSON metadata field informs the `PdxInstance.getObject()` method about the type of Java object -the JSON object will map to. Otherwise, the `PdxInstance.getObject()` method would silently return a `PdxInstance`. +to which the JSON object maps. Otherwise, the `PdxInstance.getObject()` method would silently return a `PdxInstance`. It is possible for {geode-name}'s PDX serialization framework to return a `PurchaseOrder` from `Region.get(key)` as well, but it depends on the value of PDX's `read-serialized`, cache-level configuration setting, among other factors. -NOTE: When JSON is imported into a `Region` as PDX, the {apache-geode-javadoc}/org/apache/geode/pdx/PdxInstance.html#getClassName--[PdxInstance.getClassName()] -does not refer to a valid Java class. It is {apache-geode-javadoc}/org/apache/geode/pdx/JSONFormatter.html#JSON_CLASSNAME[JSONFormatter.JSON_CLASSNAME]. +NOTE: When JSON is imported into a `Region` as PDX, the +{apache-geode-javadoc}/org/apache/geode/pdx/PdxInstance.html#getClassName--[`PdxInstance.getClassName()`] +does not refer to a valid Java class. It is +{apache-geode-javadoc}/org/apache/geode/pdx/JSONFormatter.html#JSON_CLASSNAME[`JSONFormatter.JSON_CLASSNAME`]. As a result, `Region` data access operations, such as `Region.get(key)`, return a `PdxInstance` and not a Java object. -TIP: You may need to proxy `Region` "read" data access operations (e.g. `Region.get(key)`) by setting the SBDG property -`spring.boot.data.gemfire.cache.region.advice.enabled` to `true`. When this property is set, `Regions` are proxied to -wrap a `PdxInstance` in a `PdxInstanceWrapper` in order to appropriately handle the `PdxInstance.getObject()` call in -your application code. +TIP: You may need to proxy `Region` read data access operations (such as `Region.get(key)`) by setting the SBDG property +`spring.boot.data.gemfire.cache.region.advice.enabled` to `true`. When this property is set, `Region` instances are +proxied to wrap a `PdxInstance` in a `PdxInstanceWrapper` to appropriately handle the `PdxInstance.getObject()` call +in your application code. [[geode-data-using-import-metadata-id]] -===== The `id` field & `@identifier` metadata field +===== The `id` field and the `@identifier` metadata field -The top-level objects in your JSON must have an identifier, such as an "id" field. This identifier is used as the -object's (or `PdxInstance`'s) identity and "key" when stored in the `Region` (e.g. `Region.put(key, object)`). +Top-level objects in your JSON must have an identifier, such as an `id` field. This identifier is used as the identity +and key of the object (or `PdxInstance`) when stored in the `Region` (for example, `Region.put(key, object)`). -You will have noticed the the JSON for the _Orders_ above declared an "id" field as the identifier: +You may have noticed that the JSON for the "Orders" `Region` shown earlier declared an `id` field as the identifier: .PurchaseOrder identifier ("id") +==== [source,text] ---- [{ @@ -215,20 +230,22 @@ You will have noticed the the JSON for the _Orders_ above declared an "id" field "id": 1, ... ---- +==== -This follows the same convention used in Spring Data. Typically, Spring Data mapping infrastructure looks for a POJO -field or property annotated with {spring-data-commons-javadoc}/org/springframework/data/annotation/Id.html[@Id]. If no -field or property is annotated with `@Id`, then the framework falls back to searching for a field or property named "id". +This follows the same convention used in Spring Data. Typically, Spring Data mapping infrastructure looks for a POJO +field or property annotated with {spring-data-commons-javadoc}/org/springframework/data/annotation/Id.html[`@Id`]. If no +field or property is annotated with `@Id`, the framework falls back to searching for a field or property named `id`. -In Spring Data for {geode-name} (SDG), this `@Id` annotated, or "id" named field or property is used as the identifier, +In Spring Data for {geode-name}, this `@Id`-annotated or `id`-named field or property is used as the identifier and as the key for the object when storing it into a `Region`. -However, what happens when an object, or entity does not have a surrogate id defined? Perhaps the application domain -model class is appropriately and simply using "natural" identifiers, which is quite common in practice. +However, what happens when an object or entity does not have a surrogate ID defined? Perhaps the application domain +model class is appropriately using natural identifiers, which is quite common in practice. Consider a `Book` class defined as follows: .Book class +==== [source,java] ---- @Region("Books") @@ -245,8 +262,9 @@ class Book { } ---- +==== -As declared in the `Book` class above, the identifier for `Book` is its `ISBN` since the `isbn` field was annotated with +As declared in the `Book` class, the identifier for `Book` is its `ISBN`, since the `isbn` field was annotated with Spring Data's `@Id` mapping annotation. However, we cannot know this by searching for an `@Id` annotation in JSON. You might be tempted to argue that if the `@type` metadata field is set, we would know the class type and could load @@ -256,12 +274,13 @@ format. There might not be a class definition, which would lead to a `NoClassDef So, what then? -In this case, SBDG allows you to declare the `@identifier` JSON metadata field to inform the framework -what to use as the identifier for the object. +In this case, SBDG lets you declare the `@identifier` JSON metadata field to inform the framework what to use as +the identifier for the object. -For example: +Consider the following example: .Using "@identifer" +==== [source,json] ---- { @@ -276,117 +295,123 @@ For example: "title": "Cloud Native Java" } ---- +==== -Here, the `@identifier` JSON metadata field informs the framework that the "isbn" field is the identifier for a `Book`. +The `@identifier` JSON metadata field informs the framework that the `isbn` field is the identifier for a `Book`. [[geode-data-using-import-conditional]] ==== Conditionally Importing Data While the Spring team recommends that users should only use this feature when developing and testing their Spring Boot -applications with {geode-name}, a user may occasionally use this feature in production. +applications with {geode-name}, you may still occasionally use this feature in production. -Users might use this feature in production to preload a (REPLICATE) Region with "reference" data. Reference data is -largely static, infrequently changing and non-transactional. Preloading reference data is particularly useful in caching -use cases, where you want to "warm" the cache. +You might use this feature in production to preload a (REPLICATE) Region with reference data. Reference data is largely +static, infrequently changing, and non-transactional. Preloading reference data is particularly useful when you want to +warm the cache. -When using this feature for development and testing purposes, you can simply put your `Region` specific JSON files in -`src/test/resources`. This ensures the files will not be included in your application artifact (e.g. JAR, WAR) when -deployed to production. +When you use this feature for development and testing purposes, you can put your `Region`-specific JSON files in +`src/test/resources`. This ensures that the files are not included in your application artifact (such as a JAR or WAR) +when built and deployed to production. -However, if you must use this feature to preload data in your production environment, then you can still "conditionally" -load data from JSON. To do so configure the `spring.boot.data.gemfire.cache.data.import.active-profiles` property set to -the Spring profile(s) that must be active for the import to take effect. +However, if you must use this feature to preload data in your production environment, you can still conditionally load +data from JSON. To do so, configure the `spring.boot.data.gemfire.cache.data.import.active-profiles` property set to +the Spring profiles that must be active for the import to take effect. -For example: +Consider the following example: .Conditional Importing JSON +==== [source,properties] ---- # Spring Boot application.properties spring.boot.data.gemfire.cache.data.import.active-profiles=DEV, QA ---- +==== -In order for import to have an effect in this example, you must specifically set the `spring.profiles.active` -property to 1 of the valid, "_active-profiles_" listed in the import property (e.g. `QA`). Only 1 needs to match. +For import to have an effect in this example, you must specifically set the `spring.profiles.active` property to one of +the valid, `active-profiles` listed in the import property (such as `QA`). Only one needs to match. -NOTE: There are many ways to conditionally build application artifacts. Some users might prefer to handle this concern -in their Gradle or Maven builds. +NOTE: There are many ways to conditionally build application artifacts. You might prefer to handle this concern in your +Gradle or Maven build. [[geode-data-using-export]] === Exporting Data -Certain data stored in your application's `Regions` may be sensitive or confidential and keeping the data secure is of -the utmost concern and priority. Therefore, exporting data is **disabled** by default. +Certain data stored in your application's `Regions` may be sensitive or confidential, and keeping the data secure is of +the utmost concern and priority. Therefore, exporting data is *disabled* by default. -However, if you are using this feature for development and testing purposes then enabling the _export_ capability may be -useful to move data from 1 environment to another. For example, if your QA team finds a bug in the application using a -particular data set, then they can _export_ the data and pass it back to the development team to _import_ in their local +However, if you use this feature for development and testing purposes, enabling the export capability may be useful to +move data from one environment to another. For example, if your QA team finds a bug in the application that uses a +particular data set, they can export the data and pass it back to the development team to import in their local development environment to help debug the issue. -To enable _export_, set the `spring.boot.data.gemfire.cache.data.export.enabled` property to `true`: +To enable export, set the `spring.boot.data.gemfire.cache.data.export.enabled` property to `true`: .Enable Export +==== [source,properties] ---- # Spring Boot application.properties spring.boot.data.gemfire.cache.data.export.enabled=true ---- +==== -SBDG is careful to _export_ data to JSON in a format that {geode-name} expects on _import_ and includes things such as +SBDG is careful to export data to JSON in a format that {geode-name} expects on import and includes things such as `@type` metadata fields. WARNING: The `@identifier` metadata field is not generated automatically. While it is possible for POJOs stored in a -`Region` to include an `@identifier` metadata field when exported to JSON it is not possible when the `Region` value -is a `PdxInstance` that did not originate from JSON. In this case, you must manually ensure the `PdxInstance` includes -an `@identifier` metadata field before it is exported to JSON if necessary (e.g. `Book.isbn`). This is only necessary -if your entity classes do not declare an explicit identifier field, such as with the `@Id` mapping annotation, or do -not have an "id" field. This scenario can also occur when inter-operating with native clients that model the application -domain objects differently, then serialize the objects using PDX storing them in Regions on the server that are then -later consumed by your Spring Boot application. +`Region` to include an `@identifier` metadata field when exported to JSON, it is not possible when the `Region` value +is a `PdxInstance` that did not originate from JSON. In this case, you must manually ensure that the `PdxInstance` +includes an `@identifier` metadata field before it is exported to JSON if necessary (for example, `Book.isbn`). This is +only necessary if your entity classes do not declare an explicit identifier field, such as with the `@Id` mapping +annotation, or do not have an `id` field. This scenario can also occur when inter-operating with native clients +that model the application domain objects differently and then serialize the objects by using PDX, storing them in +Regions on the server that are then later consumed by your Java-based, Spring Boot application. -WARNING: It may be necessary to set the `-Dgemfire.disableShutdownHook` JVM System property to `true` before your Spring -Boot application starts up when using Export. Unfortunately, this Java Runtime shutdown hook is registered and enabled -in {geode-name} by default, which results in the cache and _Regions_ being closed before the SBDG Export functionality -can "export the data", thereby resulting in a `CacheClosedException`. SBDG +WARNING: You may need to set the `-Dgemfire.disableShutdownHook` JVM System property to `true` before your Spring +Boot application starts up when using export. Unfortunately, this Java runtime shutdown hook is registered and enabled +in {geode-name} by default, which results in the cache and the Regions being closed before the SBDG Export +functionality can export the data, thereby resulting in a `CacheClosedException`. SBDG {github-url}/spring-geode-autoconfigure/src/main/java/org/springframework/geode/boot/autoconfigure/DataImportExportAutoConfiguration.java#L173-L183[makes a best effort] -to disable the {geode-name} shutdown hook when export is enabled, but it is at the mercy of the JVM `ClassLoader` since -{geode-name}'s JVM shutdown hook +to disable the {geode-name} JVM shutdown hook when export is enabled, but it is at the mercy of the JVM `ClassLoader`, +since {geode-name}'s JVM shutdown hook {apache-geode-src}/geode-core/src/main/java/org/apache/geode/distributed/internal/InternalDistributedSystem.java#L2185-L2223[registration] is declared in a `static` initializer. [[geode-data-using-import-export-api-extensions]] === Import/Export API Extensions -The API in SBDG for Import/Export functionality is separated into the following concerns: +The API in SBDG for import and export functionality is separated into the following concerns: * Data Format * Resource Resolving * Resource Reading * Resource Writing -By breaking each of these functions apart into separate concerns, it affords a developer the ability to customize each -aspect of the Import/Export functions. +By breaking each of these functions apart into separate concerns, a developer can customize each aspect of the import +and export functions. For example, you could import XML from the filesystem and then export JSON to a REST-based Web Service. By default, SBDG imports JSON from the classpath and exports JSON to the filesystem. -However, not all environments expose the filesystem, such as cloud environments like PCF. Therefore, giving users -control over each aspect of import/export process is essential for performing the functions in any environment. +However, not all environments expose a filesystem, such as cloud environments like PCF. Therefore, giving users control +over each aspect of the import and export processes is essential for performing the functions in any environment. [[geode-data-using-import-export-api-extensions-data-format]] ==== Data Format -The primary interface to import data into a `Region` is the `CacheDataImporter`. +The primary interface to import data into a `Region` is `CacheDataImporter`. -`CacheDataImporter` is a `@FunctionalInterface` extending Spring's +`CacheDataImporter` is a `@FunctionalInterface` that extends Spring's {spring-framework-javadoc}/org/springframework/beans/factory/config/BeanPostProcessor.html[`BeanPostProcessor`] interface to trigger the import of data after the `Region` has been initialized. -The interface is defined as: +The interface is defined as follows: .`CacheDataImporter` +==== [source,java] ---- interface CacheDataImporter extends BeanPostProcessor { @@ -395,65 +420,71 @@ interface CacheDataImporter extends BeanPostProcessor { } ---- +==== -The `importInto(..)` method can be coded to handle any data format (JSON, XML, etc) you prefer. Simply register a bean -implementing the `CacheDataImporter` interface in the Spring container and the importer will do its job. +You can code the `importInto(:Region)` method to handle any data format (JSON, XML, and others) you prefer. Register a +bean that implements the `CacheDataImporter` interface in the Spring container, and the importer does its job. -On the flip-side, the primary interface to export data from a `Region` is the `CacheDataExporter`. +On the flip side, the primary interface to export data from a `Region` is the `CacheDataExporter`. -`CacheDataExporter` is a `@FunctionalInterface` extending Spring's +`CacheDataExporter` is a `@FunctionalInterface` that extends Spring's {spring-framework-javadoc}/org/springframework/beans/factory/config/DestructionAwareBeanPostProcessor.html[`DestructionAwareBeanPostProcessor`] interface to trigger the export of data before the `Region` is destroyed. -The interface is defined as: +The interface is defined as follows: .`CacheDataExporter` +==== [source,java] ---- interface CacheDataExporter extends DestructionAwareBeanPostProcessor { Region exportFrom(Region region); - } ---- +==== -The `exportFrom(..)` method can be coded to handle any data format (JSON, XML, etc) you prefer. Simply register a bean -implementing the `CacheDataExporter` interface in the Spring container and the exporter will do its job. +You can code the `exportFrom(:Region)` method to handle any data format (JSON, XML, and others) you prefer. Register a +bean implementing the `CacheDataExporter` interface in the Spring container, and the exporter does its job. -For convenience when you want to implement both import and export functionality, SBDG provides the -`CacheDataImporterExporter` interface, which extends both `CacheDataImporter` and `CacheDataExporter`. +For convenience, when you want to implement both import and export functionality, SBDG provides the +`CacheDataImporterExporter` interface, which extends both `CacheDataImporter` and `CacheDataExporter`: .`CacheDataImporterExporter` +==== [source,java] ---- interface CacheDataImporterExporter extends CacheDataExporter, CacheDataImporter { } ---- +==== -For support, SBDG also provides the `AbstractCacheDataImporterExporter` abstract base class to simplify +For added support, SBDG also provides the `AbstractCacheDataImporterExporter` abstract base class to simplify the implementation of your importer/exporter. [[geode-data-using-import-export-api-extensions-data-format-lifecycle-management]] ===== Lifecycle Management -Sometimes it is necessary to control precisely when data is imported or exported. +Sometimes, it is necessary to precisely control when data is imported or exported. -This is especially true on import since different `Regions` maybe collocated or tied together via a cache callback like -a `CacheListener`. In these cases, the other `Region` may need to exist before the import on the dependent `Region` -proceeds, particularly if the dependencies were loosely defined. +This is especially true on import, since different `Region` instances may be collocated or tied together through a +cache callback, such as a `CacheListener`. In these cases, the other `Region` may need to exist before the import +on the dependent `Region` proceeds, particularly if the dependencies were loosely defined. -Another case when controlling the import is important is when you are using SBDG's `@EnableClusterAware` annotation to -push configuration metadata from the client to the cluster in order to define server-side `Regions` matching the -client-side `Regions`, especially client `Regions` targeted for import. The matching `Regions` on the server-side must -exist before data is imported into client (`PROXY`) `Regions`. +Controlling the import is also important when you use SBDG's `@EnableClusterAware` annotation to push configuration +metadata from the client to the cluster in order to define server-side `Region` instances that match the client-side +`Region` instances, especially client `Region` instances targeted for import. The matching `Region` instances on the +server side must exist before data is imported into client (`PROXY`) `Region` instances. In all cases, SBDG provides the `LifecycleAwareCacheDataImporterExporter` class to wrap your `CacheDataImporterExporter` -implementation. This class implements Spring's {spring-framework-javadoc}/https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/SmartLifecycle.html[`SmartLifecycle`] +implementation. This class implements Spring's +{spring-framework-javadoc}/https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/context/SmartLifecycle.html[`SmartLifecycle`] interface. -By implementing the `SmartLifecycle` interface, it allows you to control which `phase` of the Spring container -the import occurs. As such SBDG exposes two more properties to control the lifecycle: +By implementing the `SmartLifecycle` interface, you can control in which `phase` of the Spring container the import +occurs. SBDG also exposes two more properties to control the lifecycle: .Lifecycle Management Properties +==== [source,properties] ---- # Spring Boot application.properties @@ -461,13 +492,15 @@ the import occurs. As such SBDG exposes two more properties to control the lifec spring.boot.data.gemfire.cache.data.import.lifecycle=[EAGER|LAZY] spring.boot.data.gemfire.cache.data.import.phase=1000000 ---- +==== -`EAGER` acts immediately, after the Region is initialized (the default behavior). `LAZY` delays the import until the -`start()` method is called, which is invoked according to the `phase`, thereby ordering the import relative to other -"lifecycle-aware" components registered in the Spring container. +`EAGER` acts immediately, after the `Region` is initialized (the default behavior). `LAZY` delays the import until the +`start()` method is called, which is invoked according to the `phase`, thereby ordering the import relative to the other +lifecycle-aware components that are registered in the Spring container. -To make your `CacheDataImporterExporter` "lifecycle-aware" simply do: +The following example shows how to make your `CacheDataImporterExporter` lifecycle-aware: +==== [source,java] ---- @Configuration @@ -479,6 +512,7 @@ class MyApplicationConfiguration { } } ---- +==== [[geode-data-using-import-export-api-extensions-resource-resolution]] ==== Resource Resolution @@ -487,14 +521,15 @@ Resolving resources used for import and export results in the creation of a Spri {spring-framework-javadoc}/https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/core/io/Resource.html[`Resource`] handle. -Resource resolution is a vital step to qualify a resource, especially if the resource requires special logic -or permissions to access it. In this case, specific `Resource` handles can be returned and used by the _reader_ -and _writer_ of the `Resource` as is appropriate for import or export operation. +Resource resolution is a vital step to qualifying a resource, especially if the resource requires special logic +or permissions to access it. In this case, specific `Resource` handles can be returned and used by the reader +and writer of the `Resource` as appropriate for import or export operation. SBDG encapsulates the algorithm for resolving `Resources` in the `ResourceResolver` (https://en.wikipedia.org/wiki/Strategy_pattern[Strategy]) interface: .ResourceResolver +==== [source,java] ---- @FunctionalInterface @@ -507,21 +542,23 @@ interface ResourceResolver { } } ---- +==== -Additionally, SBDG provides the `ImportResourceResolver` and `ExportResourceResolver` marker interfaces along with -the `AbstractImportResourceResolver` and `AbstractExportResourceResolver` abstract base classes for implementing -resource resolution logic used by both import and export operations, for your convenience. +Additionally, SBDG provides the `ImportResourceResolver` and `ExportResourceResolver` marker interfaces and the +`AbstractImportResourceResolver` and `AbstractExportResourceResolver` abstract base classes for implementing the +resource resolution logic used by both import and export operations. -If you wish to customize the resolution of `Resources` used for import and/or export, your `CacheDataImporterExporter` +If you wish to customize the resolution of `Resources` used for import or export, your `CacheDataImporterExporter` implementation can extend the `ResourceCapableCacheDataImporterExporter` abstract base class, which provides the aforementioned interfaces and base classes. -As stated above, SBDG resolves resources on import from the classpath and resources on export to the filesystem. +As stated earlier, SBDG resolves resources on import from the classpath and resources on export to the filesystem. -It is easy to customize this behavior simply by providing an implementation of either or both the -`ImportResourceResolver` and `ExportResourceResolver` interfaces and declare instances as beans in the Spring context: +You can customize this behavior by providing an implementation of `ImportResourceResolver`, `ExportResourceResolver`, +or both interfaces and declare instances as beans in the Spring context: .Import & Export ResourceResolver beans +==== [source,java] ---- @Configuration @@ -538,17 +575,19 @@ class MyApplicationConfiguration { } } ---- +==== -TIP: If you need to customize the resource resolution process per location (or `Region`) on import or export, then you -could use the https://en.wikipedia.org/wiki/Composite_pattern[Composite Software Design Pattern]. +TIP: If you need to customize the resource resolution process for each location (or `Region`) on import or export, +you can use the https://en.wikipedia.org/wiki/Composite_pattern[Composite software design pattern]. [[geode-data-using-import-export-api-extensions-resource-resolution-default-customization]] ===== Customize Default Resource Resolution -If you are content with the provided defaults, but want to target specific locations on the classpath or filesystem -used by the import or export, then SBDG additionally provides the following properties: +If you are content with the provided defaults but want to target specific locations on the classpath or filesystem +used by the import or export, SBDG additionally provides the following properties: .Import/Export Resource Location Properties +==== [source,properties] ---- # Spring Boot application.properties @@ -556,19 +595,21 @@ used by the import or export, then SBDG additionally provides the following prop spring.boot.data.gemfire.cache.data.import.resource.location=... spring.boot.data.gemfire.cache.data.export.resource.location=... ---- +==== -The properties accept any valid resource string as specified in the Spring -{spring-framework-docs}/core.html#resources-resourceloader[documentation] (See *Table 10. Resource strings*). +The properties accept any valid resource string, as specified in the Spring +{spring-framework-docs}/core.html#resources-resourceloader[documentation] (see *Table 10. Resource strings*). -This means even though the import defaults from the classpath, it is simple to change the location from classpath -to filesystem, or even network (e.g. https://) simply by changing the _prefix_ (or _protocol_). +This means that, even though import defaults from the classpath, you can change the location from classpath +to filesystem, or even network (for example, https://) by changing the prefix (or protocol). -Of course, import/export resource location properties can refer to other properties via property placeholders, but SBDG -further allows users to use SpEL inside the property values. +Import/export resource location properties can refer to other properties through property placeholders, but SBDG +further lets you use SpEL inside the property values. -For example: +Consider the following example: .Using SpEL +==== [source,properties] ---- # Spring Boot application.properties @@ -576,49 +617,56 @@ For example: spring.boot.data.gemfire.cache.data.import.resource.location=\ https://#{#env['user.name']}:#{someBean.lookupPassword(#env['user.name'])}@#{host}:#{port}/cache/#{#regionName}/data/import ---- +==== -The import resource location in this case refers to a rather sophisticated resource string using a complex SpEL +In this case, the import resource location refers to a rather sophisticated resource string by using a complex SpEL expression. -Out-of-the-box, SBDG populates the SpEL `EvaluationContext` with 3 sources of information: +SBDG populates the SpEL `EvaluationContext` with three sources of information: * Access to the Spring `BeanFactory` * Access to the Spring `Environment` * Access to the current `Region` -Simple Java System properties or environment variables can be accessed with the expression: +Simple Java System properties or environment variables can be accessed with the following expression: +==== [source,text] ---- #{propertyName} ---- +==== -For more complex property names (e.g. properties using dot notation, such as the `user.home` Java System property), -users can access these properties directly from the `Environment` using map style syntax as follows: +You can access more complex property names (including properties that use dot notation, such as the `user.home` +Java System property), directly from the `Environment` by using map style syntax as follows: +==== [source,text] ---- #{#env['property.name']} ---- +==== The `#env` variable is set in the SpEL `EvaluationContext` to the Spring `Environment`. Because the SpEL `EvaluationContext` is evaluated with the Spring `ApplicationContext` as the root object, you also have -access to the beans declared and registered in the Spring context and can invoke methods on them, as shown above with -`someBean.lookupPassword(..)`. "_someBean_" must be the name of the bean as declared/registered in the Spring context. +access to the beans declared and registered in the Spring container and can invoke methods on them, as shown earlier +with `someBean.lookupPassword(..)`. `someBean` must be the name of the bean as declared and registered in the Spring +container. -WARNING: Be careful when accessing beans declared in the Spring context with SpEL, particularly when using `EAGER` -import as it may force those beans to be eagerly (or even, prematurely) initialized. +CAUTION: Be careful when accessing beans declared in the Spring container with SpEL, particularly when using `EAGER` +import, as it may force those beans to be eagerly (or even prematurely) initialized. -SBDG also sets the `#regionName` variable in the `EvaluationContext` to the name of the `Region`, -as determined by {apache-geode-javadoc}/https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/Region.html#getName--[Region.getName()], -targeted for import/export. +SBDG also sets the `#regionName` variable in the `EvaluationContext` to the name of the `Region`, as determined by +{apache-geode-javadoc}/https://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/Region.html#getName--[`Region.getName()`], +targeted for import and export. -This allows you to not only change the location of the resource but also change the resource name (e.g. filename). +This lets you not only change the location of the resource but also change the resource name (such as a filename). -For example: +Consider the following example: .Using `#regionName` +==== [source,properties] ---- # Spring Boot application.properties @@ -626,27 +674,29 @@ For example: spring.boot.data.gemfire.cache.data.export.resource.location=\ file://#{#env['user.home']}/gemfire/cache/data/custom-filename-for-#{#regionName}.json ---- +==== -NOTE: By default, the exported file is stored in the working directory (i.e. `System.getProperty("user.dir")`) of the -Spring Boot application process. +NOTE: By default, the exported file is stored in the working directory (`System.getProperty("user.dir")`) +of the Spring Boot application process. -TIP: See the Spring {spring-framework-docs}/core.html#expressions[documentation] for more information on SpEL. +TIP: See the Spring Framework {spring-framework-docs}/core.html#expressions[documentation] for more information on SpEL. [[geode-data-using-import-export-api-extensions-resource-reading-writing]] ==== Reading & Writing Resources -The Spring {spring-framework-javadoc}/org/springframework/core/io/Resource.html[`Resource`] handle specifies -the location of a resource, not how to read or write it. Even the Spring -{spring-framework-javadoc}/org/springframework/core/io/ResourceLoader.html[`ResourceLoader`], which is an interface for -"loading" `Resources`, does not specifically read or write any content to the `Resource`. +The Spring {spring-framework-javadoc}/org/springframework/core/io/Resource.html[`Resource`] handle +specifies tion of a resource, not how the resource is read or written. Even the Spring +{spring-framework-javadoc}/org/springframework/core/io/ResourceLoader.html[`ResourceLoader`], +which is an interface for loading `Resources`, does not specifically read or write any content to the `Resource`. -As such, SBDG separates these concerns into two interfaces: `ResourceReader` and `ResourceWriter`, respectively. -The design follows the same pattern used by Java's `InputStream/OutputStream` and `Reader/Writer` classes in -the `java.io` package. +SBDG separates these concerns into two interfaces: `ResourceReader` and `ResourceWriter`, respectively. +The design follows the same pattern used by Java's `InputStream/OutputStream` and `Reader/Writer` classes +in the `java.io` package. -The interfaces are basically defined as: +The `ResourceReader` interfaces is defined as: .ResourceReader +==== [source,java] ---- @FunctionalInterface @@ -656,10 +706,12 @@ interface ResourceReader { } ---- +==== -And... +The `ResourceWriter` interfaces is defined as: .ResourceWriter +==== [source,java] ---- @FunctionalInterface @@ -669,20 +721,21 @@ interface ResourceWriter { } ---- +==== -Both of interfaces provide additional methods to _compose_ readers and writers, much like Java's own `Consumer` -and `Function` interfaces in the `java.util.function` package. If a particular reader or writer is used in a composition -and is unable to handle the given `Resource`, then it should throw a `UnhandledResourceException` to allow the next -reader or writer in the composition to try and read from or write to the `Resource`. +Both interfaces provide additional methods to compose readers and writers, much like Java's `Consumer` and `Function` +interfaces in the `java.util.function` package. If a particular reader or writer is used in a composition and is unable +to handle the given `Resource`, it should throw a `UnhandledResourceException` to let the next reader or writer in the +composition try to read from or write to the `Resource`. -Of course, the reader or writer are free to throw a `ResourceReadException` or `ResourceWriteException` to break the -chain of reader and writer invocations in the composition. +The reader or writer are free to throw a `ResourceReadException` or `ResourceWriteException` to break the chain of +reader and writer invocations in the composition. -To override the default export/import reader and writer used by SBDG out-of-the-box, simply implement -the `ResourceReader` and/or `ResourceWriter` interfaces as appropriate and declare instances of these classes as beans -in the Spring context: +To override the default export/import reader and writer used by SBDG, you can implement the `ResourceReader` +or `ResourceWriter` interfaces as appropriate and declare instances of these classes as beans in the Spring container: .Custom `ResourceReader` & `ResourceWriter` beans +==== [source,java] ---- @Configuration @@ -700,3 +753,4 @@ class MyApplicationConfiguration { } } ---- +==== diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/docker.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/docker.adoc index 94289ee0..304ca81f 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/docker.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/docker.adoc @@ -6,50 +6,54 @@ :testcontainers-url: https://www.testcontainers.org -The state of modern software application development is moving towards https://www.docker.com/resources/what-container[_containerization_]. -Containers offer a controlled environment to predictably build (configure & package), run and manage your applications -in a reliable and repeatable manner regardless of context. The intrinsic benefit of using Containers is a no brainer. +The state of modern software application development is moving towards https://www.docker.com/resources/what-container[containerization]. +Containers offer a controlled environment to predictably build (compile, configure and package), run, and manage your +applications in a reliable and repeatable manner, regardless of context. In many situations, the intrinsic benefit of +using containers is obvious. -Understandably, {docker-site-url}[Docker's] popularity took off like wildfire given its highly powerful and simplified -model for creating, using and managing Containers to run packaged applications. +Understandably, {docker-site-url}[Docker's] popularity took off like wildfire, given its highly powerful and simplified +model for creating, using and managing containers to run packaged applications. -Docker's ecosystem is also quite impressive, with the event of {testcontainers-url}[Testcontainers] -along with Spring Boot's now {spring-boot-docs-html}/spring-boot-features.html#building-docker-images[dedicated support] -to create packaged Spring Boot apps in {docker-docs-url}/get-started/overview/#docker-objects[Docker Images] -that are then later run in a Docker Container. +Docker's ecosystem is also quite impressive, with the advent of {testcontainers-url}[Testcontainers] and Spring Boot's +now {spring-boot-docs-html}/spring-boot-features.html#building-docker-images[dedicated support] to create packaged +Spring Boot applications in {docker-docs-url}/get-started/overview/#docker-objects[Docker images] that are then later +run in a Docker container. -TIP: Also see {spring-boot-docs-html}/deployment.html#containers-deployment[Deploying to Containers] to learn more. +TIP: See also {spring-boot-docs-html}/deployment.html#containers-deployment["`Deploying to Containers`"] to learn more. -{geode-name} is no exception to being able to run in a controlled, containerized environment. The goal of this chapter -is to get you started running {geode-name} in a Container and interfacing to a containerized {geode-name} cluster from -your Spring Boot, {geode-name} client applications. +{geode-name} can also run in a controlled, containerized environment. The goal of this chapter is to get you started +running {geode-name} in a container and interfacing to a containerized {geode-name} cluster from your Spring Boot, +{geode-name} client applications. -This chapter does not cover how to run your Spring Boot, {geode-name} client applications in a Container since that is -already covered by Spring Boot (again, see {spring-boot-docs-html}/spring-boot-features.html#building-docker-images[here] -and {spring-boot-docs-html}/deployment.html#containers-deployment[here], along with Docker's {docker-docs-url}/get-started/overview/[docs]). -Instead, our focus is on how to run an {geode-name} cluster in a Container and connect to it from a Spring Boot, -{geode-name} client application, regardless of whether the app is running in a Container or not. - -Let's get started. +This chapter does not cover how to run your Spring Boot, {geode-name} client applications in a container, since that is +already covered by Spring Boot (again, see the Spring Boot documentation for +{spring-boot-docs-html}/spring-boot-features.html#building-docker-images[Docker images] +and {spring-boot-docs-html}/deployment.html#containers-deployment[container deployment], +along with Docker's {docker-docs-url}/get-started/overview/[documentation]). +Instead, our focus is on how to run an {geode-name} cluster in a container and connect to it from a Spring Boot, +{geode-name} client application, regardless of whether the application runs in a container or not. [[geode-docker-image]] === Acquiring the {geode-name} Docker Image -To run an {geode-name} cluster inside a Docker Container you must first acquire the Docker Image. The {geode-name} -Docker Image can be acquired from https://hub.docker.com/r/apachegeode/geode/[Docker Hub]. +To run an {geode-name} cluster inside a Docker container, you must first acquire the Docker image. You can get +the {geode-name} Docker image from https://hub.docker.com/r/apachegeode/geode/[Docker Hub]. -While {geode-name}'s official {apache-geode-docs}[documentation] is less than clear on how to use {geode-name} in Docker, -we find a bit of relief in the {apache-geode-wiki}/How+to+use+Geode+on+Docker[Wiki]. However, for a complete and -comprehensive write up, please refer to the instructions in the https://github.com/markito/geode-docker#building-the-container-image[README] +While {geode-name}'s {apache-geode-docs}[official documentation] is less than clear on how to use {geode-name} in Docker, +we find a bit of relief in the {apache-geode-wiki}/How+to+use+Geode+on+Docker[Wiki]. However, for a complete +and comprehensive write up, see the instructions in +the https://github.com/markito/geode-docker#building-the-container-image[README] from this https://github.com/markito/geode-docker[GitHub Repo]. -NOTE: You must have {docker-docs-url}/get-docker[Docker] installed on your local system to complete the following steps. +NOTE: You must have {docker-docs-url}/get-docker[Docker] installed on your computer to complete the following steps. Effectively, the high-level steps are as follows: -1) Acquire the {geode-name} Docker Image from Docker Hub using the `docker pull` command from the command-line: +1) Acquire the {geode-name} Docker image from Docker Hub by using the `docker pull` command (shown with typical output) +from the command-line: .Download/Install the {geode-name} Docker Image +==== [source,text] ---- $ docker pull apachegeode/geode @@ -59,13 +63,15 @@ Digest: sha256:6a6218f22a2895bb706175727c7d76f654f9162acac22b2d950d09a2649f9cf4 Status: Image is up to date for apachegeode/geode:latest docker.io/apachegeode/geode:latest ---- +==== -Instead of pulling from the `nightly` TAG as suggested, the Spring team highly recommends that you pull from the -`latest` TAG, which pulls a stable, production-ready {geode-name} Docker Image based on the latest {geode-name} +Instead of pulling from the `nightly` tag as suggested, the Spring team highly recommends that you pull from +the `latest` tag, which pulls a stable, production-ready {geode-name} Docker image based on the latest {geode-name} GA version. -2) Verify the {geode-name} Docker Image was downloaded and installed successfully: +2) Verify that the {geode-name} Docker image was downloaded and installed successfully: +==== [source,text] ---- $ docker image ls @@ -76,16 +82,18 @@ open-liberty 19.0.0.9-webProfile8 dece75feff1a tomee 11-jre-8.0.0-M3-webprofile 0d03e4d395e6 3 months ago 678MB ... ---- +==== -Now, you are ready to run {geode-name} in a Docker Container. +Now you are ready to run {geode-name} in a Docker container. [[geode-docker-container]] === Running {geode-name} in a Docker Container -Now that we have acquired the {geode-name} Docker Image, we can run {geode-name} in a Docker Container. Use the -following `docker run` command to start {geode-name} in a Docker Container: +Now that you have acquired the {geode-name} Docker image, you can run {geode-name} in a Docker container. +Use the following `docker run` command to start {geode-name} in a Docker container: .Start the {geode-name} Docker Container +==== [source,text] ---- $ docker run -it -p 10334:10334 -p 40404:40404 -p 1099:1099 -p 7070:7070 -p 7575:7575 apachegeode/geode @@ -98,24 +106,26 @@ $ docker run -it -p 10334:10334 -p 40404:40404 -p 1099:1099 -p 7070:7070 -p 7575 Monitor and Manage Apache Geode gfsh> ---- +==== -Since the {geode-name} Docker Container was started in interactive mode, you must open a separate command-line shell -to verify the {geode-name} Docker Container is in fact running: +Since the {geode-name} Docker container was started in interactive mode, you must open a separate command-line shell +to verify that the {geode-name} Docker container is in fact running: .Verify the {geode-name} Docker Container is Running +==== [source,text] ---- $ docker container ls CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3b30b9ffc5dc apachegeode/geode "gfsh" 44 seconds ago Up 43 seconds 0.0.0.0:1099->1099/tcp, 0.0.0.0:7070->7070/tcp, 0.0.0.0:7575->7575/tcp, 0.0.0.0:10334->10334/tcp, 0.0.0.0:40404->40404/tcp, 8080/tcp awesome_khorana - ---- +==== -Of course, we know that the {geode-name} Docker Container is running since we ended up at a _Gfsh_ command prompt in the -interactive shell. +You know that the {geode-name} Docker container is running since we ended up at a Gfsh command prompt in +the interactive shell. -We also mapped ports between the Docker Container and the host system, exposing well-known ports used by {geode-name} -server-side, cluster processes, such as Locators and Cache Servers. +We also mapped ports between the Docker container and the host system, exposing well-known ports used by {geode-name} +server-side cluster processes, such as Locators and CacheServers: .{geode-name} Ports [width=30%, options="header", cols="2,1"] @@ -132,17 +142,18 @@ server-side, cluster processes, such as Locators and Cache Servers. |=== -It is unfortunate that the {geode-name} Docker Image only gives you a _Gfsh_ command prompt, leaving you with the task -of provisioning a cluster. It would have been more useful to provide preconfigured Docker Images with different -{geode-name} cluster configurations, such as 1 Locator + 1 Server, or 2 Locators + 4 Servers, etc. But, no matter, we -can start the cluster ourselves. +It is unfortunate that the {geode-name} Docker image gives you only a Gfsh command prompt, leaving you with the task of +provisioning a cluster. It would have been more useful to provide preconfigured Docker images with different {geode-name} +cluster configurations, such as one Locator and one server or two Locators and four servers, and so on. However, we can +start the cluster ourselves. [[geode-docker-cluster]] === Start an {geode-name} Cluster in Docker -From inside the {geode-name} Docker Container we can start a Locator and a Server. +From inside the {geode-name} Docker container, we can start a Locator and a server: .Start {geode-name} Locator & Server +==== [source, text] ---- gfsh>start locator --name=LocatorOne --log-level=config --hostname-for-clients=localhost @@ -219,37 +230,42 @@ Running : true Client Connections : 0 ---- +==== -We now have an {geode-name} cluster running with 1 Locator and 1 Server inside a Docker Container. We deliberately +We now have an {geode-name} cluster running with one Locator and one server inside a Docker container. We deliberately started the cluster with a minimal configuration. For example, we have no Regions in which to store data: +==== [source,text] ---- gfsh>list regions No Regions Found - ---- +==== -But, that is OK. Once more, we want to showcase the full power of SBDG and let the Spring Boot application drive -the configuration of the {geode-name} cluster running in the Docker Container as required by the application. +However, that is OK. Once more, we want to show the full power of SBDG and let the Spring Boot application drive +the configuration of the {geode-name} cluster that runs in the Docker container, as required by the application. Let's have a quick look at our Spring Boot application. [[geode-docker-application]] -=== Spring Boot, {geode-name} client application explained +=== Spring Boot, {geode-name} Client Application Explained -The Spring Boot, {geode-name} `ClientCache` application we will use to connect to our {geode-name} cluster running in -the Docker Container appears as follows: +The Spring Boot, {geode-name} `ClientCache` application we use to connect to our {geode-name} cluster that runs in +the Docker container appears as follows: .Spring Boot, {geode-name} Docker client application +==== [source,java] ---- include::{docs-src-dir}/org/springframework/geode/docs/example/app/docker/SpringBootApacheGeodeDockerClientCacheApplication.java[tags=class] ---- +==== Our `Customer` application domain model object type is defined as: .`Customer` class +==== [source,java] ---- @Region("Customers") @@ -262,10 +278,12 @@ class Customer { } ---- +==== -And, we define a Spring Data CRUD _Repository_ to persist and access `Customers` stored in the "/Customers" Region: +Also, we define a Spring Data CRUD Repository to persist and access `Customers` stored in the `/Customers` Region: .`CustomerRepository` interface +==== [source,java] ---- interface CustomerRepository extends CrudRepository { @@ -274,33 +292,35 @@ interface CustomerRepository extends CrudRepository { } ---- +==== -Our main class is annotated with `@SpringBootApplication` making it a proper Spring Boot application. +Our main class is annotated with `@SpringBootApplication`, making it be a proper Spring Boot application. -We additionally annotate the main class with SBDG's `@EnableClusterAware` to automatically detect the {geode-name} -cluster running in the Docker Container as well as to push cluster configuration metadata from the application to -the cluster as required by the application. +We additionally annotate the main class with SBDG's `@EnableClusterAware` annotation to automatically detect +the {geode-name} cluster that runs in the Docker container and to push cluster configuration metadata from +the application to the cluster as required by the application. Specifically, the application requires that a Region called "Customers", as defined by the `@Region` mapping annotation -on the `Customer` application domain model class, exists on the server(s) in the cluster to persist `Customer` data. +on the `Customer` application domain model class, exists on the servers in the cluster, to store `Customer` data. -We use the SDG `@EnableEntityDefinedRegions` annotation to define the matching, client `PROXY` "Customers" Region. +We use the SDG `@EnableEntityDefinedRegions` annotation to define the matching client `PROXY` "Customers" Region. Optionally, we have also annotated our main class with SBDG's `@UseMemberName` annotation to give the `ClientCache` a name, which we assert in the `assertClientCacheAndConfigureMappingPdxSerializer(:ClientCache)` method. -The primary work performed by this application is done in the Spring Boot `ApplicationRunner` bean definition. We -essentially create a `Customer` instance, "Jon Doe", save "Jon Doe" to the "Customers" Region managed by the server(s) -in the cluster, and then query for "Jon Doe" using OQL, asserting that the result is equal to the expected. +The primary work performed by this application is done in the Spring Boot `ApplicationRunner` bean definition. We create +a `Customer` instance (`Jon Doe`), save it to the "Customers" Region that is managed by the server in the cluster, +and then query for `Jon Doe` using OQL, asserting that the result is equal to what we expect. We log the output from the application's operations to see the application in action. [[geode-docker-application-run]] === Running the Spring Boot, {geode-name} client application -When you run the Spring Boot, {geode-name} client application, you should see output similar to: +When you run the Spring Boot, {geode-name} client application, you should see output similar to the following: .Application log output +==== [source,text] ---- /Library/Java/JavaVirtualMachines/jdk1.8.0_241.jdk/Contents/Home/bin/java ... @@ -320,11 +340,13 @@ Customer was [Customer(name=Jon Doe)] Process finished with exit code 0 ---- +==== -Now when we review the configuration of the cluster, we see that the "/Customers" Region was created -once the application has run: +When we review the configuration of the cluster, we see that the `/Customers` Region was created when the application +ran: ./Customers Region Configuration +==== [source,text] ---- gfsh>list regions @@ -344,13 +366,14 @@ Non-Default Attributes Shared By Hosting Members ------ | ----------- | --------- Region | size | 1 | data-policy | PARTITION - ---- +==== -Our "/Customers" Region contains a value, "Jon Doe", and we can verify this by running the following OQL Query -with _Gfsh_: +Our `/Customers` Region contains a value (`Jon Doe`), and we can verify this by running the following OQL Query +with Gfsh: .Query the "/Customers" Region +==== [source,text] ---- gfsh>query --query="SELECT customer.name FROM /Customers customer" @@ -361,17 +384,17 @@ Rows : 1 Result ------- Jon Doe - ---- +==== -Indeed, our application ran successfully! +Our application ran successfully. [[geode-docker-application-conclusion]] === Conclusion In this chapter, we saw how to connect a Spring Boot, {geode-name} `ClientCache` application to an {geode-name} cluster -running in a Docker Container. +that runs in a Docker container. -Later, we will provide more information on how to scale up, or rather scale out, our {geode-name} cluster running in -Docker. Additionally, we will provide details on how you can use {geode-name}'s Docker Image with **Testcontainers** -when writing _Integration Tests_, which will formally become part of the Spring Test for {geode-name} (STDG) project. +Later, we provide more information on how to scale up, or rather scale out, our {geode-name} cluster that runs in Docker. +Additionally, we provide details on how you can use {geode-name}'s Docker image with Testcontainers when you write +integration tests, which formally became part of the Spring Test for {geode-name} (STDG) project. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/functions.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/functions.adoc index 4f0e40dc..cd0d30be 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/functions.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/functions.adoc @@ -3,57 +3,57 @@ :geode-name: {apache-geode-name} -This chapter is about using {geode-name} in a Spring context for distributed compute use cases. +This chapter is about using {geode-name} in a Spring context for distributed computing use cases. === Background -Distributed processing, particularly in conjunction with data access and mutation operations, is a very effective -and efficient use of clustered computing resources. This is along the same lines as {wikipedia-docs}/MapReduce[MapReduce]. +Distributed computing, particularly in conjunction with data access and mutation operations, is a very effective +and efficient use of clustered computing resources. This is similar to {wikipedia-docs}/MapReduce[MapReduce]. -A naively conceived query returning potentially hundreds of thousands, or even millions of rows of data in a result set -back to the application that queried and requested the data can be very costly, especially under load. Therefore, it is +A naively conceived query returning potentially hundreds of thousands (or even millions) of rows of data in a result set +to the application that queried and requested the data can be very costly, especially under load. Therefore, it is typically more efficient to move the processing and computations on the predicated data set to where the data resides, -perform the required computations, summarize the results and then send the reduced data set back to the client. +perform the required computations, summarize the results, and then send the reduced data set back to the client. Additionally, when the computations are handled in parallel, across the cluster of computing resources, the operation -can be performed much faster. This typically involves intelligently organizing the data using various partitioning +can be performed much more quickly. This typically involves intelligently organizing the data using various partitioning (a.k.a. sharding) strategies to uniformly balance the data set across the cluster. -Well, {geode-name} addresses this very important application concern in its -{apache-geode-docs}/developing/function_exec/chapter_overview.html[Function Execution] framework. +{geode-name} addresses this very important application concern in its +{apache-geode-docs}/developing/function_exec/chapter_overview.html[Function execution] framework. -Spring Data for {geode-name} {spring-data-geode-docs-html}/#function-annotations[builds] on this Function Execution -framework by enabling developers to {spring-data-geode-docs-html}/#function-implementation[implement] -and {spring-data-geode-docs-html}/#function-execution[execute] {geode-name} Functions using a very simple POJO-based, +Spring Data for {geode-name} {spring-data-geode-docs-html}/#function-annotations[builds] on this Function execution +framework by letting developers {spring-data-geode-docs-html}/#function-implementation[implement] +and {spring-data-geode-docs-html}/#function-execution[execute] {geode-name} functions with a simple POJO-based annotation configuration model. -TIP: See {spring-data-geode-docs-html}/#_implementation_vs_execution[here] for the difference between -Function implementation & executions. +TIP: See {spring-data-geode-docs-html}/#_implementation_vs_execution[the section about implementation versus execution] +for the difference between Function implementation and execution. -Taking this 1 step further, Spring Boot for {geode-name} _auto-configures_ and enables both Function implementation -and execution out-of-the-box. Therefore, you can immediately begin writing Functions and invoking them without having -to worry about all the necessary plumbing to begin with. You can rest assured that it will just work as expected. +Taking this a step further, Spring Boot for {geode-name} auto-configures and enables both Function implementation +and execution out-of-the-box. Therefore, you can immediately begin writing Functions and invoking them without having to +worry about all the necessary plumbing to begin with. You can rest assured that it works as expected. === Applying Functions -Earlier, when we talked about <>, we described a `FinancialLoanApplicationService` class -that could process eligibility when a `Person` applied for a financial loan. +Earlier, when we talked about <>, we described a `FinancialLoanApplicationService` class +that could process eligibility when someone (represented by a `Person` object) applied for a financial loan. -This can be a very resource intensive & expensive operation since it might involve collecting credit and employment -history, gathering information on existing, outstanding/unpaid loans, and so on and so forth. We applied caching -in order to not have to recompute, or redetermine eligibility every time a loan office may want to review the decision -with the customer. +This can be a very resource intensive and expensive operation, since it might involve collecting credit and employment +history, gathering information on outstanding loans, and so on. We applied caching in order to not have to recompute +or redetermine eligibility every time a loan office may want to review the decision with the customer. -But what about the process of computing eligibility in the first place? +But, what about the process of computing eligibility in the first place? -Currently the application's `FinancialLoanApplicationService` class seems to be designed to fetch the data and perform -the eligibility determination in place. However, it might be far better to distribute the processing and even -determine eligibility for a larger group of people all at once, especially when multiple, related people are involved -in a single decision, as is typically the case. +Currently, the application's `FinancialLoanApplicationService` class seems to be designed to fetch the data and perform +the eligibility determination in place. However, it might be far better to distribute the processing and even determine +eligibility for a larger group of people all at once, especially when multiple, related people are involved in a single +decision, as is typically the case. -We implement an `EligibilityDeterminationFunction` class using SDG very simply as: +We can implement an `EligibilityDeterminationFunction` class by using SDG: .Function implementation +==== [source,java] ---- @Component @@ -65,16 +65,18 @@ class EligibilityDeterminationFunction { } } ---- +==== -Using the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/function/annotation/GemfireFunction.html[`@GemfireFunction`] -annotation, it is easy to implement our Function as a POJO method. SDG handles registering this POJO method -as a proper Function with {geode-name} appropriately. +By using the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/function/annotation/GemfireFunction.html[`@GemfireFunction`] +annotation, we can implement our Function as a POJO method. SDG appropriately handles registering this POJO method +as a proper Function with {geode-name}. -If we now want to call this Function from our Spring Boot, `ClientCache` application, then we simply define -a Function Execution interface with a method name matching the Function name, and targeting the execution -on the "_EligibilityDecisions_" Region: +If we now want to call this function from our Spring Boot `ClientCache` application, we can define +a function execution interface with a method name that matches the function name and that targets the execution +on the `EligibilityDecisions` Region: .Function execution +==== [source,java] ---- @OnRegion("EligibilityDecisions") @@ -84,11 +86,13 @@ interface EligibilityDeterminationExecution { } ---- +==== -We can then inject the `EligibilityDeterminationExecution` into our `FinancialLoanApplicationService` like any other -object/Spring bean: +We can then inject an instance of the `EligibilityDeterminationExecution` interface into our +`FinancialLoanApplicationService`, as we would any other object or Spring bean: .Function use +==== [source,java] ---- @Service @@ -106,8 +110,10 @@ class FinancialLoanApplicationService { } } ---- +==== -Just like caching, no addition configuration is required to enable and find your application Function implementations -and executions. Simply build and run. Spring Boot for {geode-name} handles the rest. +As with caching, no additional configuration is required to enable and find your application Function implementations +and executions. You can simply build and run. Spring Boot for {geode-name} handles the rest. -TIP: It is common to implement and register your application Functions on the server and execute them from the client. +TIP: It is common to "implement" and register your application Functions on the server and "execute" them from +the client. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/gemfire-properties.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/gemfire-properties.adoc index 62fa0f2d..bd1a6eb9 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/gemfire-properties.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/gemfire-properties.adoc @@ -3,18 +3,19 @@ :geode-name: Apache Geode -As of Spring Boot for {geode-name} (SBDG) 1.3, it is possible to declare {geode-name} properties from -`gemfire.properties` in a Spring Boot `application.properties` file. +As of Spring Boot for {geode-name} (SBDG) 1.3, you can declare {geode-name} properties from `gemfire.properties` +in Spring Boot `application.properties`. -TIP: A complete list of valid {geode-name} properties can be found in the -{apache-geode-docs}/reference/topics/gemfire_properties.html[User Guide]. +TIP: See the {apache-geode-docs}/reference/topics/gemfire_properties.html[User Guide] for a complete list +of valid {geode-name} properties. -It should be known that only valid Geode Properties can be declared in `gemfire.properties`, or alternatively, +Note that you can declare only valid Geode properties in `gemfire.properties` or, alternatively, `gfsecurity.properties`. -For example: +The following example shows how to declare properties in `gemfire.properties`: .Valid `gemfire.properties` +==== [source,properties] ---- # Geode Properties in gemfire.properties @@ -25,15 +26,16 @@ enable-time-statistics=true durable-client-id=123 # ... ---- +==== -All of the properties declared in the `gemfire.properties` file shown above correspond to valid Geode Properties. -It is illegal to declare properties in a `gemfire.properties` file that are not valid Geode Properties, even if those -properties are prefixed with a different qualifier (e.g. "_spring.*_"). {geode-name} is very particular about this -and will throw an `IllegalArgumentException` for invalid properties. +All of the properties declared in the preceding example correspond to valid Geode properties. It is illegal to declare +properties in `gemfire.properties` that are not valid Geode properties, even if those properties are prefixed with a +different qualifier (such as `spring.*`). {geode-name} throws an `IllegalArgumentException` for invalid properties. -For example, given the following `gemfire.properties` file with "_invalid-property_" declared: +Consider the following `gemfire.properties` file with an `invalid-property`: .Invalid `gemfire.properties` +==== [source,properties] ---- # Geode Properties in gemfire.properties @@ -41,10 +43,12 @@ For example, given the following `gemfire.properties` file with "_invalid-proper name=ExampleCacheName invalid-property=TEST ---- +==== {geode-name} throws an `IllegalArgumentException`: -.{geode-name} Exception for Invalid Property (Full Text Omitted) +.`IllegalArgumentException` thrown by {geode-name} for Invalid Property (Full Text Omitted) +==== [source,txt] ---- Exception in thread "main" java.lang.IllegalArgumentException: Unknown configuration attribute name invalid-property. @@ -66,63 +70,63 @@ Valid attribute names are: ack-severe-alert-threshold ack-wait-threshold archive at o.a.g.cache.client.ClientCacheFactory.create(ClientCacheFactory.java:216) at org.example.app.ApacheGeodeClientCacheApplication.main(...) ---- +==== It is inconvenient to have to separate {geode-name} properties from other application properties, or to have to declare only {geode-name} properties in a `gemfire.properties` file and application properties in a separate properties file, such as Spring Boot `application.properties`. -Additionally, because of {geode-name}'s constraint on properties, you are not able to leverage the full power of -Spring Boot when composing `application.properties`. +Additionally, because of {geode-name}'s constraint on properties, you cannot use the full power of Spring Boot when you +compose `application.properties`. -It is well-known that you can include certain properties based on a Spring Profile while excluding other properties. -This is essential when properties are environment or context specific. +You can include certain properties based on a Spring profile while excluding other properties. This is essential when +properties are environment- or context-specific. -Of course, users should be aware that Spring Data for {geode-name} (SDG) provide a wide range of properties mapping to -{geode-name} properties already. +Spring Data for {geode-name} already provides a wide range of properties mapping to {geode-name} properties. -For example, the SDG `spring.data.gemfire.locators` property maps to the `gemfire.locators` property (or simply, -`locators` in `gemfire.properties`) from {geode-name}. Likewise, there are a full set of SDG properties mapping to +For example, the SDG `spring.data.gemfire.locators` property maps to the `gemfire.locators` property +(`locators` in `gemfire.properties`) from {geode-name}. Likewise, there are a full set of SDG properties that map to the corresponding {geode-name} properties in the <>. -The Geode Properties shown above can be expressed as SDG Properties in Spring Boot `application.properties` as follows: +You can express the Geode properties shown earlier as SDG properties in Spring Boot `application.properties`, +as follows: -.Configurring Geode Properties using SDG Properties +.Configuring Geode Properties using SDG Properties +==== [source,properties] ---- # Spring Data for {geode-name} properties in application.properties spring.data.gemfire.name=ExampleCacheName spring.data.gemfire.cache.log-level=TRACE -spring.data.gemfire.stats.enable-time-statistics=true spring.data.gemfire.cache.client.durable-client-id=123 +spring.data.gemfire.stats.enable-time-statistics=true # ... ---- +==== -However, there are some {geode-name} properties that have no equivalent SDG property, such as `gemfire.groups` -(or simply, `groups` in `gemfire.properties`). This is partly due to the fact that many {geode-name} properties are -applicable only configured on the server (e.g. `groups` or `enforce-unique-host`). +However, some {geode-name} properties have no equivalent SDG property, such as `gemfire.groups` (`groups` in +`gemfire.properties`). This is partly due to the fact that many {geode-name} properties are applicable only when +configured on the server (such as `groups` or `enforce-unique-host`). TIP: See the `@EnableGemFireProperties` annotation ({spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableGemFireProperties.html[attributes]) -from SDG for a complete list of {geode-name} properties, which have no corresponding SDG property. +from SDG for a complete list of {geode-name} properties with no corresponding SDG property. Furthermore, many of the SDG properties also correspond to API calls. -For example, `spring.data.gemfire.cache.client.keep-alive` -(see {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#keepAlive--[here]) -actually translates to the call, `ClientCache.close(boolean keepAlive)` -(see {apache-geode-javadoc}/org/apache/geode/cache/client/ClientCache.html#close-boolean-[here]). +For example, {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/ClientCacheApplication.html#keepAlive[`spring.data.gemfire.cache.client.keep-alive`] +translates to the {apache-geode-javadoc}/org/apache/geode/cache/client/ClientCache.html#close-boolean[`ClientCache.close(boolean keepAlive)`] API call. Still, it would be convenient to be able to declare application and {geode-name} properties together, in a single -properties file, such as Spring Boot `application.properties`. After all, it is not uncommon to declare JDBC Connection +properties file, such as Spring Boot `application.properties`. After all, it is not uncommon to declare JDBC Connection properties in a Spring Boot `application.properties` file. -Therefore, as of SBDG 1.3, it is now possible to declare {geode-name} properties in Spring Boot `application.properties` -directly. - -For example: +Therefore, as of SBDG 1.3, you can now declare {geode-name} properties in Spring Boot `application.properties` directly, +as follows: .Geode Properties declared in Spring Boot `application.properties` +==== [source,properties] ---- # Spring Boot application.properties @@ -132,33 +136,32 @@ spring.application.name=ExampleApp gemfire.durable-client-id=123 gemfire.enable-time-statistics=true ---- +==== This is convenient and ideal for several reasons: -1. If you already have a large number of {geode-name} properties declared as `gemfire.` properties, either in -`gemfire.properties` or `gfsecurity.properties`, or declared on the Java command-line as JVM System Properties -(e.g. `-Dgemfire.name=ExampleCacheName`), then you can reuse these property declarations as is. +* If you already have a large number of {geode-name} properties declared as `gemfire.` properties (either in +`gemfire.properties` or `gfsecurity.properties`) or declared on the Java command-line as JVM System properties +(such as `-Dgemfire.name=ExampleCacheName`), you can reuse these property declarations. +* If you are unfamiliar with SDG's corresponding properties, you can declare Geode properties instead. +* You can take advantage of Spring features, such as Spring profiles. +* You can also use property placeholders with Geode properties (such as +`gemfire.log-level=${external.log-level.property}`). -2. If you are unfamiliar with SDG's corresponding properties, then you can simply declare Geode Properties instead. +TIP: We encourage you to use the SDG properties, which cover more than {geode-name} properties. -3. You can take advantage of Spring features, such as _Spring Profiles_. - -4. You can also use _Property Placeholders_ with Geode Properties, -e.g. `gemfire.log-level=${external.log-level.property}` - -TIP: As much as possible, we encourage users to use the SDG provided properties. - -However, 1 strict requirement imposed by SBDG is that the Geode Property must have the "_gemfire._" prefix in a -Spring Boot `application.properties` file. This qualifies that the property belongs to {geode-name}. Without, the -"_gemfire._" prefix, the property will not be appropriately applied to the {geode-name} cache instance. +However, SBDG requires that the Geode property must have the `gemfire.` prefix in Spring Boot `application.properties`. +This indicates that the property belongs to {geode-name}. Without the `gemfire.` prefix, the property is not +appropriately applied to the {geode-name} cache instance. It would be ambiguous if your Spring Boot applications integrated with several technologies, including {geode-name}, -and they too had matching properties, e.g. `bind-address` or `log-file`, perhaps. +and they too had matching properties, such as `bind-address` or `log-file`. -SBDG makes a best attempt to log warnings when the Geode Property is invalid or not set. For example, the following -Geode Property would result in a log warning: +SBDG makes a best attempt to log warnings when a Geode property is invalid or is not set. For example, the following +Geode property would result in logging a warning: .Invalid {geode-name} Property +==== [source,properties] ---- # Spring Boot application.properties @@ -166,27 +169,35 @@ Geode Property would result in a log warning: spring.application.name=ExampleApp gemfire.non-existing-property=TEST ---- +==== -The resulting warning appearing in the log would read: +The resulting warning in the log would read: +.Invalid Geode Property Warning Message +==== [source,text] ---- [gemfire.non-existing-property] is not a valid Apache Geode property ---- +==== -If a Geode Property is not properly set, then the following warning will be logged: +If a Geode Property is not properly set, the following warning is logged: +.Invalide Geode Property Value Warning Message +==== [source,text] ---- Apache Geode Property [gemfire.security-manager] was not set ---- +==== -With regards to the 3rd point, you can now compose and declare Geode Properties based on context (e.g. your application -environment) with Spring Profiles. +With regards to the third point mentioned earlier, you can now compose and declare Geode properties based on a context +(such as your application environment) using Spring profiles. For example, you might start with a base set of properties in Spring Boot `application.properties`: .Base Properties +==== [source,properties] ---- server.port=8181 @@ -194,10 +205,12 @@ spring.application.name=ExampleApp gemfire.durable-client-id=123 gemfire.enable-time-statistics=false ---- +==== -And then begin to vary the properties by environment: +Then you can vary the properties by environment, as the next two listings (for QA and production) show: .QA Properties +==== [source,properties] ---- # Spring Boot application-qa.properties @@ -209,10 +222,10 @@ gemfire.enable-network-partition-detection=true gemfire.groups=QA # ... ---- +==== -Or in production: - -.PROD Properties +.Production Properties +==== [source,properties] ---- # Spring Boot application-prod.properties @@ -225,21 +238,24 @@ gemfire.enforce-unique-host=true gemfire.groups=PROD # ... ---- +==== -It is then a simple matter to apply the appropriate set of properties by configuring the Spring Profile by using: -`-Dspring.profiles.active=prod`. It is also possible to enable more than 1 profile at a time by using: +You can then apply the appropriate set of properties by configuring the Spring profile with +`-Dspring.profiles.active=prod`. You can also enable more than one profile at a time with `-Dspring.profiles.active=profile1,profile2,...,profileN` If both `spring.data.gemfire.*` properties and the matching {geode-name} properties are declared in Spring Boot -`application.properties`, then the SDG properties take precedence. +`application.properties`, the SDG properties take precedence. -If a property is specified more than once, as would potentially be the case when composing multiple `application.properties` -files and you enable more than 1 Spring Profile at time, then the last property declaration wins. In the example shown -above, the value for `gemfire.groups` would be `PROD` when `-Dspring.profiles.active=qa,prod` is configured. +If a property is specified more than once, as would potentially be the case when composing multiple Spring Boot +`application.properties` files and you enable more than one Spring profile at time, the last property declaration wins. +In the example shown earlier, the value for `gemfire.groups` would be `PROD` when `-Dspring.profiles.active=qa,prod` +is configured. -For example, given the following Spring Boot `application.properties`: +Consider the following Spring Boot `application.properties`: .Property Precedence +==== [source,properties] ---- # Spring Boot application.properties @@ -247,26 +263,30 @@ For example, given the following Spring Boot `application.properties`: gemfire.durable-client-id=123 spring.data.gemfire.cache.client.durable-client-id=987 ---- +==== -Then the `durable-client-id` will be `987`. It does not matter which order the SDG or {geode-name} properties are -declared in `application.properties`, the matching SDG property will override the {geode-name} property when duplicates +The `durable-client-id` is `987`. It does not matter which order the SDG or {geode-name} properties are declared in +Spring Boot `application.properties`. The matching SDG property overrides the {geode-name} property when duplicates are found. -Finally, it is not possible to refer to Geode Properties declared in Spring Boot `application.properties` with the -SBDG `GemFireProperties` class (See {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/configuration/GemFireProperties.html[Javadoc]). +Finally, you cannot refer to Geode properties declared in Spring Boot `application.properties` with the SBDG +`GemFireProperties` class (see the {spring-boot-data-geode-javadoc}/org/springframework/geode/boot/autoconfigure/configuration/GemFireProperties.html[Javadoc]). -For example, given: +Consider the following example: .Geode Properties declared in Spring Boot `application.properties` +==== [source,properties] ---- # Spring Boot application.properties gemfire.name=TestCacheName ---- +==== -The following assertion holds: +Given the preceding property, the following assertion holds: +==== [source,java] ---- import org.springframework.geode.boot.autoconfigure.configuration.GemFireProperties; @@ -284,12 +304,13 @@ class GemFirePropertiesTestSuite { } } ---- +==== -TIP: `application.properties` can be declared in the `@SpringBootTest` annotation. For example, `gemfire.name` -could have been declared in the annotation using the declaration, `@SpringBootTest(properties = { "gemfire.name=TestCacheName" })`, -for testing purposes instead of declaring the property in a separate `application.properties` file. +TIP: You can declare `application.properties` in the `@SpringBootTest` annotation. For example, you could have declared +`gemfire.name` in the annotation by setting `@SpringBootTest(properties = { "gemfire.name=TestCacheName" })` +for testing purposes instead of declaring the property in a separate Spring Boot `application.properties` file. Only `spring.data.gemfire.*` prefixed properties are mapped to the SBDG `GemFireProperties` class hierarchy. -TIP: Again, prefer SDG Properties over Geode Properties. See SDG properties reference +TIP: Prefer SDG properties over Geode properties. See the SDG properties reference in the <>. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/geode-api-ext.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/geode-api-ext.adoc index e4b2ec42..178d26ca 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/geode-api-ext.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/geode-api-ext.adoc @@ -9,9 +9,8 @@ When using the Spring programming model and abstractions, it should not be neces or the Spring Data Repository abstraction for DAO development. There are many more examples. For certain use cases, users may require low level access to fine-grained functionally. Spring Boot for {geode-name}'s -`org.springframework.geode:apache-geode-extensions` module and library builds on {geode-name}'s APIs -by including several extensions with enhanced functionality to offer an experience familiar to Spring users -inside a Spring context. +`org.springframework.geode:apache-geode-extensions` module and library builds on {geode-name}'s APIs by including +several extensions with enhanced functionality to offer an experience familiar to Spring users inside a Spring context. TIP: Spring Data for {geode-name} (SDG) also {spring-data-geode-docs-html}/#apis[includes] additional extensions to {geode-name}'s APIs. @@ -20,19 +19,21 @@ TIP: Spring Data for {geode-name} (SDG) also {spring-data-geode-docs-html}/#apis === `SimpleCacheResolver` In some cases, it is necessary to acquire a reference to the cache instance in your application components at runtime. -For example, you might want to create a temporary `Region` on the fly in order to aggregate data for analysis. +For example, you might want to create a temporary `Region` on the fly to aggregate data for analysis. -Typically, you already know the type of cache your application is using since you must declare your application to be -either a client (i.e. `ClientCache`) in the {apache-geode-docs}/topologies_and_comm/cs_configuration/chapter_overview.html[client/server topology], -or a {apache-geode-docs}/topologies_and_comm/p2p_configuration/chapter_overview.html[peer member/node] in the cluster -(i.e. `Cache`) on startup. This is expressed in configuration when creating the cache instance required to interact with -the {geode-name} data management system. In most cases, your application will be a client and SBDG makes this decision -easy since it _auto-configures_ a `ClientCache` instance, <>. +Typically, you already know the type of cache your application is using, since you must declare your application to be +either a client (`ClientCache`) in the {apache-geode-docs}/topologies_and_comm/cs_configuration/chapter_overview.html[client/server topology], +or a {apache-geode-docs}/topologies_and_comm/p2p_configuration/chapter_overview.html[peer member or node] (`Cache`) in +the cluster on startup. This is expressed in configuration when creating the cache instance required to interact with +the {geode-name} data management system. In most cases, your application will be a client. SBDG makes this decision easy, +since it auto-configures a `ClientCache` instance, <>. -In a Spring context, the cache instance created by the framework is a managed bean in the Spring container. As such, -it is a simple matter to inject a reference to the _Singleton_ cache bean into any other managed application component. +In a Spring context, the cache instance created by the framework is a managed bean in the Spring container. +You can inject a reference to the https://en.wikipedia.org/wiki/Singleton_pattern[_Singleton_] cache bean +into any other managed application component: .Autowired Cache Reference using Dependency Injection (DI) +==== [source,java] ---- @Service @@ -45,12 +46,14 @@ class CacheMonitoringService { } ---- +==== However, in cases where your application component or class is not managed by Spring and you need a reference to the cache instance at runtime, SBDG provides the abstract `org.springframework.geode.cache.SimpleCacheResolver` class -(see {spring-boot-data-geode-javadoc}/org/springframework/geode/cache/SimpleCacheResolver.html[Javadoc]). +(see its {spring-boot-data-geode-javadoc}/org/springframework/geode/cache/SimpleCacheResolver.html[Javadoc]). .`SimpleCacheResolver` API +==== [source, java ] ---- package org.springframework.geode.cache; @@ -67,63 +70,64 @@ abstract class SimpleCacheResolver { } ---- +==== -`SimpleCacheResolver` adheres to https://en.wikipedia.org/wiki/SOLID[SOLID OO Principles]. This class is abstract and -extensible so users can change the algorithm used to resolve client or peer cache instances as well as mock its methods -in _Unit Tests_. +`SimpleCacheResolver` adheres to https://en.wikipedia.org/wiki/SOLID[SOLID OO Principles]. This class is abstract +and extensible so that you can change the algorithm used to resolve client or peer cache instances as well as mock +its methods in unit tests. -Additionally, each method is precise. For example, `resolveClientCache()` will only resolve a reference to a cache if -the cache instance is a "client"! If a cache exists, but is a "peer" instance, then `resolveClientCache()` returns -`Optional.EMPTY`. The behavior of `resolvePeerCache()` is similar. +Additionally, each method is precise. For example, `resolveClientCache()` resolves a reference to a cache only if +the cache instance is a "`client.`" If a cache exists but is a "`peer`" cache instance, `resolveClientCache()` +returns `Optional.EMPTY`. The behavior of `resolvePeerCache()` is similar. -`require()` returns a non-`Optional` reference to a cache instance throwing an `IllegalStateException` if a cache +`require()` returns a non-`Optional` reference to a cache instance and throws an `IllegalStateException` if a cache is not present. [[geode-api-extensions-cacheutils]] === `CacheUtils` -Under-the-hood, `SimpleCacheResolver` delegates some of its functions to the +Under the hood, `SimpleCacheResolver` delegates some of its functions to the {spring-boot-data-geode-javadoc}/org/springframework/geode/util/CacheUtils.html[`CacheUtils`] -abstract utility class, which provides additional, convenient capabilities when using a cache. +abstract utility class, which provides additional, convenient capabilities when you use a cache. -While there are utility methods to determine whether a cache instance (i.e. `GemFireCache`) or _Region_ is a client -or a peer, one of the more useful functions is to extract all the values from a _Region_. +While there are utility methods to determine whether a cache instance (that is, a `GemFireCache`) or Region is a client +or a peer, one of the more useful functions is to extract all the values from a Region. -To extract all the values stored in a _Region_ call `CacheUtils.collectValues(:Region)`. This method returns a -`Collection` containing all the values stored in the given _Region_. The method is smart, and knows how to handle -the `Region` appropriately regardless of whether the `Region` is a client or peer `Region`. This distinction is -important since client `PROXY` _Regions_ store no values. +To extract all the values stored in a Region, call `CacheUtils.collectValues(:Region)`. This method returns a +`Collection` that contains all the values stored in the given `Region`. The method is smart and knows how to handle +the `Region` appropriately regardless of whether the `Region` is a client or a peer. This distinction is important, +since client `PROXY` Regions store no values. -WARNING: Caution is advised when getting all values from a _Region_. While getting filtered reference values from a -non-transactional, reference data only [`REPLICATE`] _Region_ is quite useful, getting all values from a transactional, -[`PARTITION`] _Region_ can prove quite detrimental, especially in production. Getting all values from a _Region_ can be +WARNING: Caution is advised when you get all values from a Region. While getting filtered reference values from a +non-transactional, reference data only [`REPLICATE`] Region is quite useful, getting all values from a transactional, +[`PARTITION`] Region can prove quite detrimental, especially in production. Getting all values from a Region can be useful during testing. [[geode-api-extensions-membership]] -=== `MembershipListenerAdapter` & `MembershipEvent` +=== `MembershipListenerAdapter` and `MembershipEvent` Another useful API hidden by {geode-name} is the membership events and listener interface. This API is especially useful -on the server-side when your Spring Boot application is serving as a peer member of an {geode-name} distributed system. +on the server side when your Spring Boot application serves as a peer member of an {geode-name} distributed system. When a peer member is disconnected from the distributed system, perhaps due to a network failure, the member is forcibly removed from the cluster. This node immediately enters a reconnecting state, trying to establish a connection back to -the cluster. Once reconnected, the peer member must rebuild all cache objects (i.e. `Cache`, `Regions`, `Indexes`, -`DiskStores`, etc). All previous cache objects are now invalid and their references stale. +the cluster. Once reconnected, the peer member must rebuild all cache objects (`Cache`, `Region` instances, `Index` +instances, `DiskStore` instances, and so on). All previous cache objects are now invalid, and their references are stale. -As you can imagine, in a Spring context this is particularly problematic since most {geode-name} objects are _Singleton_ -beans declared in and managed by the Spring container. Those beans may be injected and used in other framework and -application components. For instance, `Regions` are injected into SDG's `GemfireTemplate`, Spring Data _Repositories_ -and possibly application-specific _Data Access Objects_ (https://en.wikipedia.org/wiki/Data_access_object[DAO]). +In a Spring context, this is particularly problematic since most {geode-name} objects are _Singleton_ beans declared in +and managed by the Spring container. Those beans may be injected and used in other framework and application components. +For instance, `Region` instances are injected into SDG's `GemfireTemplate`, Spring Data Repositories and possibly +application-specific data access objects (https://en.wikipedia.org/wiki/Data_access_object[DAOs]). -If references to those cache objects become stale on a forced disconnect event, then there is no way to auto-wire fresh -object references into the dependent application or framework components when the peer member is reconnected unless the -Spring `ApplicationContext` is "refreshed". In fact, there is no way to even know that this event has occurred since the -{geode-name} `MembershipListener` API and corresponding events are "internal". +If references to those cache objects become stale on a forced disconnect event, there is no way to auto-wire fresh +object references into the dependent application or framework components when the peer member is reconnected, unless the +Spring `ApplicationContext` is "`refreshed`". In fact, there is no way to even know that this event has occurred, since +the {geode-name} `MembershipListener` API and corresponding events are "`internal`". -NOTE: The Spring team have explored the idea of creating proxies for all types of cache objects (i.e. `Cache`, `Regions`, -`Indexes`, `DiskStores`, `AsyncEventQueues`, `GatewayReceivers`, `GatewaySenders`, etc) used by Spring. The proxies -would know how to obtain a "fresh" reference on a reconnect event. However, this turns out to be more problematic than -it is worth. It is simply easier to "refresh" the Spring `ApplicationContext`, although no less cheap. Neither way is +NOTE: The Spring team explored the idea of creating proxies for all types of cache objects (`Cache`, `Region`, `Index`, +`DiskStore`, `AsyncEventQueue`, `GatewayReceiver`, `GatewaySender`, and others) used by Spring. The proxies would know +how to obtain a fresh reference on a reconnect event. However, this turns out to be more problematic than it is worth. +It is easier to "`refresh`" the Spring `ApplicationContext`, although doing so is no less expensive. Neither way is ideal. See https://jira.spring.io/browse/SGF-921[SGF-921] and https://jira.spring.io/browse/SGF-227[SGF-227] for further details. @@ -133,9 +137,9 @@ In the case where membership events are useful to the Spring Boot application, S * {spring-boot-data-geode-javadoc}/org/springframework/geode/distributed/event/MembershipListenerAdapter.html[`MembershipListenerAdapter`] * {spring-boot-data-geode-javadoc}/org/springframework/geode/distributed/event/MembershipEvent.html[`MembershipEvent`] -The abstract `MembershipListenerAdapter` class implements {geode-name}'s `org.apache.geode.distributed.internal.MembershipListener` interface -to simplify the event handler method signatures by using an appropriate `MembershipEvent` type -to encapsulate the actors in the event. +The abstract `MembershipListenerAdapter` class implements {geode-name}'s `org.apache.geode.distributed.internal.MembershipListener` +interface to simplify the event handler method signatures by using an appropriate `MembershipEvent` type to encapsulate +the actors in the event. The abstract `MembershipEvent` class is further subclassed to represent specific membership event types that occur within the {geode-name} system: @@ -145,7 +149,7 @@ within the {geode-name} system: * {spring-boot-data-geode-javadoc}/org/springframework/geode/distributed/event/support/MemberSuspectEvent.html[`MemberSuspectEvent`] * {spring-boot-data-geode-javadoc}/org/springframework/geode/distributed/event/support/QuorumLostEvent.html[`QuorumLostEvent`] -The API is depicted in this UML diagram: +The API is depicted in the following UML diagram: image::{images-dir}/membership-api-uml.png[] @@ -153,12 +157,12 @@ The membership event type is further categorized with an appropriate enumerated {spring-boot-data-geode-javadoc}/org/springframework/geode/distributed/event/MembershipEvent.Type.html[`MembershipEvent.Type`], as a property of the `MembershipEvent` itself (see {spring-boot-data-geode-javadoc}/org/springframework/geode/distributed/event/MembershipEvent.html#getType--[`getType()`]). -The type hierarchy is useful in `instanceof` expressions while the `Enum` is useful in `switch` statements. +The type hierarchy is useful in `instanceof` expressions, while the `Enum` is useful in `switch` statements. -You can see 1 particular implementation of the `MembershipListenerAdapter` with the +You can see one particular implementation of the `MembershipListenerAdapter` with the {spring-boot-data-geode-javadoc}/org/springframework/geode/distributed/event/ApplicationContextMembershipListener.html[`ApplicationContextMembershipListener`] class, -which does exactly as we described above, handling forced-disconnect/auto-reconnect membership events inside a -Spring context in order to refresh the Spring `ApplicationContext`. +which does exactly as we described earlier, handling forced-disconnect/auto-reconnect membership events inside a +Spring container in order to refresh the Spring `ApplicationContext`. [[geode-api-extensions-pdx]] === PDX @@ -166,20 +170,21 @@ Spring context in order to refresh the Spring `ApplicationContext`. {geode-name}'s PDX serialization framework is yet another API that falls short of a complete stack. For instance, there is no easy or direct way to serialize an object as PDX bytes. It is also not possible to modify an -existing `PdxInstance` by adding or removing fields since it requires a new PDX type. In this case, you must create a -new `PdxInstance` and copy from the existing `PdxInstance`. Unfortunately, the {geode-name} API offers no assistance. -It is also not possible to use PDX in a client, local-only mode without a server since the PDX type registry is only -available and managed on servers in a cluster. All of this leaves much to be desired. +existing `PdxInstance` by adding or removing fields, since doing so would require a new PDX type. In this case, you must +create a new `PdxInstance` and copy from an existing `PdxInstance`. Unfortunately, the {geode-name} API offers no help +in this regard. It is also not possible to use PDX in a client, local-only mode without a server, since the PDX type +registry is only available and managed on servers in a cluster. [[geode-api-extensions-pdx-builder]] ==== `PdxInstanceBuilder` In such cases, SBDG conveniently provides the {spring-boot-data-geode-javadoc}/org/springframework/geode/pdx/PdxInstanceBuilder.html[`PdxInstanceBuilder`] class, -appropriately named after the https://en.wikipedia.org/wiki/Builder_pattern[_Builder Software Design Pattern_]. -The `PdxInstanceBuilder` also offers a fluent API for constructing `PdxInstances`. +appropriately named after the https://en.wikipedia.org/wiki/Builder_pattern[Builder software design pattern]. +The `PdxInstanceBuilder` also offers a fluent API for constructing `PdxInstances`: .`PdxInstanceBuilder` API +==== [source,java] ---- class PdxInstanceBuilder { @@ -190,10 +195,12 @@ class PdxInstanceBuilder { } ---- +==== For example, you could serialize an application domain object as PDX bytes with the following code: .Serializing an Object to PDX +==== [source,java] ---- @Component @@ -207,10 +214,12 @@ class CustomerSerializer { } } ---- +==== You could then modify the `PdxInstance` by copying from the original: .Copy `PdxInstance` +==== [source,java] ---- @Component @@ -230,66 +239,71 @@ class CustomerDecorator { } } ---- +==== [[geode-api-extensions-pdx-wrapper]] ==== `PdxInstanceWrapper` SBDG also provides the {spring-boot-data-geode-javadoc}/org/springframework/geode/pdx/PdxInstanceWrapper.html[`PdxInstanceWrapper`] class to wrap an existing `PdxInstance` in order to provide more control during the conversion from PDX to JSON and from -JSON back into a POJO. Specifically, the wrapper gives users more control over the configuration of Jackson's +JSON back into a POJO. Specifically, the wrapper gives you more control over the configuration of Jackson's `ObjectMapper`. The `ObjectMapper` constructed by {geode-name}'s own `PdxInstance` implementation (`PdxInstanceImpl`) is not -configurable nor was it configured correctly. And unfortunately, since `PdxInstance` is not extensible, the `getObject()` -method fails miserably when converting the JSON generated from PDX back into a POJO for any practical application domain -model type. +configurable, nor was it configured correctly. Unfortunately, since `PdxInstance` is not extensible, the `getObject()` +method fails when converting the JSON generated from PDX back into a POJO for any practical application domain model +type. + +The following example wraps an existing `PdxInstance`: .Wrapping an existing `PdxInstance` +==== [source,java] ---- PdxInstanceWrapper wrapper = PdxInstanceWrapper.from(pdxInstance); ---- +==== For all operations on `PdxInstance` except `getObject()`, the wrapper delegates to the underlying `PdxInstance` method implementation called by the user. In addition to the decorated `getObject()` method, the `PdxInstanceWrapper` provides a thorough implementation of the -`toString()` method. The state of the `PdxInstance` is output in a JSON-like String. +`toString()` method. The state of the `PdxInstance` is output in a JSON-like `String`. Finally, the `PdxInstanceWrapper` class adds a `getIdentifier()` method. Rather than put the burden on the user to have -to iterate the field names of the `PdxInstance` to determine whether a field is the identity field, and then call -`getField(..)` with the field name to get the ID (value), assuming an identity field was marked in the first place, -the `PdxInstanceWrapper` class provides the `getIdentifier()` method to return the ID of the `PdxInstance` directly. +to iterate the field names of the `PdxInstance` to determine whether a field is the identity field and then call +`getField(name)` with the field name to get the ID (value) -- assuming an identity field was marked in the first place +-- the `PdxInstanceWrapper` class provides the `getIdentifier()` method to return the ID of the `PdxInstance` directly. -The `getIdentifier()` method is smart in that it first iterates the fields of the `PdxInstance` asking if the field is -the identity field. If no field was marked as the "identity" field, then the algorithm searches for a field named "id". -If no field with the name "id" exists, then the algorithm searches for a metadata field called "@identifier", which -refers to the field that is the identity field of the `PdxInstance`. +The `getIdentifier()` method is smart in that it first iterates the fields of the `PdxInstance`, asking each field if it +is the identity field. If no field was marked as the identity field, the algorithm searches for a field named `id`. If +no field with the name `id` exists, the algorithm searches for a metadata field called `@identifier`, which refers to +the field that is the identity field of the `PdxInstance`. The `@identifier` metadata field is useful in cases where the `PdxInstance` originated from JSON and the application domain object uses a natural identifier, rather than a surrogate ID, such as `Book.isbn`. -NOTE: {geode-name}'s `JSONFormatter` is not capable of marking the identity field of a `PdxInstance` originating +NOTE: {geode-name}'s `JSONFormatter` class is not capable of marking the identity field of a `PdxInstance` originating from JSON. WARNING: It is not currently possible to implement the `PdxInstance` interface and store instances of this type as a -value in a _Region_. {geode-name} naively assumes that all `PdxInstance` objects are an implementation created by -{geode-name} itself (i.e. `PdxInstanceImpl`), which has a tight coupling to the PDX type registry. An Exception is -thrown if you try to store instances of your own `PdxInstance` implementation. +value in a Region. {geode-name} assumes all `PdxInstance` objects are an implementation created by {geode-name} itself +(that is, `PdxInstanceImpl`), which has a tight coupling to the PDX type registry. An `Exception` is thrown if you try +to store instances of your own `PdxInstance` implementation. [[geode-api-extensions-pdx-adapter]] ==== `ObjectPdxInstanceAdapter` -In rare cases, it might be necessary to treat an `Object` as a `PdxInstance` depending on the context without incurring +In rare cases, you may need to treat an `Object` as a `PdxInstance`, depending on the context without incurring the overhead of serializing an `Object` to PDX. For such cases, SBDG offers the `ObjectPdxInstanceAdapter` class. -This might be true when calling a method with a parameter expecting an argument, or returning an instance, of type -`PdxInstance`, particularly when {geode-name}'s `read-serialized` PDX configuration property is set to `true`, and only -an object is available in the current context. +This might be true when calling a method with a parameter expecting an argument of, or returning an instance of, +type `PdxInstance`, particularly when {geode-name}'s `read-serialized` PDX configuration property is set to `true` +and only an object is available in the current context. -Under-the-hood, SBDG's `ObjectPdxInstanceAdapter` class uses Spring's -{spring-framework-javadoc}/org/springframework/beans/BeanWrapper.html[`BeanWrapper`] class along with _Java's -Introspection & Reflection_ functionality to adapt the given `Object` in order to access it using the full +Under the hood, SBDG's `ObjectPdxInstanceAdapter` class uses Spring's +{spring-framework-javadoc}/org/springframework/beans/BeanWrapper.html[`BeanWrapper`] class along with Java's +introspection and reflection functionality to adapt the given `Object` and access it with the full {apache-geode-javadoc}/org/apache/geode/pdx/PdxInstance.html[`PdxInstance`] API. This includes the use of the {apache-geode-javadoc}/org/apache/geode/pdx/WritablePdxInstance.html[`WritablePdxInstance`] API, obtained from {apache-geode-javadoc}/org/apache/geode/pdx/PdxInstance.html#createWriter--[`PdxInstance.createWriter()`], to modify @@ -297,17 +311,18 @@ the underlying `Object` as well. Like the `PdxInstanceWrapper` class, `ObjectPdxInstanceAdapter` contains special logic to resolve the identity field and ID of the `PdxInstance`, including consideration for Spring Data's -{spring-data-commons-javadoc}/org/springframework/data/annotation/Id.html[`@Id`] mapping annotation, which can be -introspected in this case given the underlying `Object` backing the `PdxInstance` is a POJO. +{spring-data-commons-javadoc}/org/springframework/data/annotation/Id.html[`@Id`] mapping annotation, +which can be introspected in this case, given that the underlying `Object` backing the `PdxInstance` is a POJO. -Clearly, the `ObjectPdxInstanceAdapter.getObject()` method will return the given, wrapped `Object` used to construct -the `ObjectPdxInstanceAdapter`, and is therefore, automatically "_deserializable_", as determined by the +The `ObjectPdxInstanceAdapter.getObject()` method returns the wrapped `Object` used to construct +the `ObjectPdxInstanceAdapter` and is, therefore, automatically deserializable, as determined by the {apache-geode-javadoc}/org/apache/geode/pdx/PdxInstance.html#isDeserializable--[`PdxInstance.isDeseriable()`] method, -which always returns true. +which always returns `true`. -To adapt any `Object` as a `PdxInstance`, simply do: +You can adapt any `Object` as a `PdxInstance`: .Adapt an `Object` as a `PdxInstance` +==== [source,java] ---- class OfflineObjectToPdxInstanceConverter { @@ -317,12 +332,15 @@ class OfflineObjectToPdxInstanceConverter { } } ---- +==== -Once the adapter is created, you can use it to access data on the underlying `Object`. +Once the https://en.wikipedia.org/wiki/Adapter_pattern[Adapter] is created, you can use it to access data +on the underlying `Object`. -For example, given a `Customer` class: +Consider the following example of a `Customer` class: .`Customer` class +==== [source,java] ---- @Region("Customers") @@ -337,10 +355,12 @@ class Customer { } ---- +==== -Then accessing an instance of `Customer` using the `PdxInstance` API is as easy as: +Then you can access an instance of `Customer` by using the `PdxInstance` API: .Accessing an `Object` using the `PdxInstance` API +==== [source,java] ---- class ObjectPdxInstanceAdapterTest { @@ -362,15 +382,17 @@ class ObjectPdxInstanceAdapterTest { } } ---- +==== [[geode-api-extensions-security]] === Security -For testing purposes, SBDG provides a test implementation of {geode-name}'s {apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[`SecurityManager`] -interface that simply expects the password to match the username (case-sensitive) when authenticating. +For testing purposes, SBDG provides a test implementation of +{geode-name}'s {apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[`SecurityManager`] interface, +which expects the password to match the username (case-sensitive) when authenticating. By default, all operations are authorized. To match the expectations of SBDG's `TestSecurityManager`, SBDG additionally provides a test implementation of -{geode-name}'s {apache-geode-javadoc}/org/apache/geode/security/AuthInitialize.html[`AuthInitialize`] interface that -supplies matching credentials for both the username and password. +{geode-name}'s {apache-geode-javadoc}/org/apache/geode/security/AuthInitialize.html[`AuthInitialize`] interface, +which supplies matching credentials for both the username and password. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/logging.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/logging.adoc index d3892721..f570c409 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/logging.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/logging.adoc @@ -3,127 +3,127 @@ :geode-name: Apache Geode -{geode-name} `1.9.2` was modularized to separate its use of the Apache Log4j API to log output in Geode code from -the underlying implementation of logging, which uses Apache Log4j as the logging provider by default. +{geode-name} `1.9.2` was modularized to separate its use of the Apache Log4j API to log output in {geode-name} code +from the underlying implementation of logging, which uses Apache Log4j as the logging provider by default. -Prior to `1.9.2`, the Apache Log4j API (i.e. `log4j-api`) along with the Apache Log4j provider (i.e. `log4j-core`) -were automatically pulled in by {geode-name} core (i.e. `org.apache.geode:geode-core`) thereby making it problematic +Prior to `1.9.2`, the Apache Log4j API (`log4j-api`) and the Apache Log4j service provider (`log4j-core`) +were automatically pulled in by {geode-name} core (`org.apache.geode:geode-core`), thereby making it problematic to change logging providers when using {geode-name} in Spring Boot applications. -However, now, in order to get any log output from {geode-name} whatsoever, {geode-name} requires a logging provider on -your Spring Boot application classpath. Consequently, this also means the old {geode-name} `Properties`, -e.g. `log-level` no longer have any effect, regardless of whether the property (e.g. `log-level`) is specified in -`gemfire.properties`, in Spring Boot `application.properties` or even as a JVM System Property, `-Dgemfire.log-level`. +However, now, in order to get any log output from {geode-name} whatsoever, {geode-name} requires a logging provider +declared on your Spring Boot application classpath. Consequently, this also means the old {geode-name} `Properties` +(such as `log-level`) no longer have any effect, regardless of whether the property is specified in `gemfire.properties`, +in Spring Boot `application.properties`, or even as a JVM System Property (`-Dgemfire.log-level`). -TIP: Refer to {geode-name}'s {apache-geode-docs}/reference/topics/gemfire_properties.html[Documentation] -for a complete list of valid `Properties`, including the `Properties` used to configure logging. +TIP: See {geode-name}'s {apache-geode-docs}/reference/topics/gemfire_properties.html[documentation] for a complete list +of valid `Properties`, including the `Properties` used to configure logging. -Unfortunately, this also means the _Spring Data for {geode-name}_ (SDG) +Unfortunately, this also means the Spring Data for {geode-name} {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableLogging.html[`@EnableLogging`] -annotation no longer has any effect on {geode-name} logging either and is the reason it has been +annotation no longer has any effect on {geode-name} logging either. Consequently, it has been https://jira.spring.io/browse/DATAGEODE-299[deprecated]. The reason `@EnableLogging` no longer has any effect on logging -is because this annotation's attributes and associated SDG properties indirectly sets the corresponding {geode-name} -properties, which again, are useless from {geode-name} `1.9.2` onward. +is because this annotation's attributes and associated SDG properties indirectly set the corresponding {geode-name} +properties, which, again, are useless from {geode-name} `1.9.2` onward. -By way of example, and to make this concrete, **none** of the following approaches have any effect on -{geode-name} logging: +By way of example, and to make this concrete, *none* of the following approaches have any effect on {geode-name} logging: .Command-line configuration +==== [source,txt] ---- $ java -classpath ...:/path/to/MySpringBootApacheGeodeClientCacheApplication.jar -Dgemfire.log-level=DEBUG example.app.MySpringBootApacheGeodeClientCacheApplication ---- +==== .Externalized configuration using {geode-name} `gemfire.properties` +==== [source,properties] ---- # {geode-name} only/specific properties log-level=INFO ---- +==== .Externalized configuration using Spring Boot `application.properties` +==== [source,properties] ---- spring.data.gemfire.cache.log-level=DEBUG ----- - -Or: - -[source,properties] ----- spring.data.gemfire.logging.level=DEBUG ---- +==== .Java configuration using SDG's `@EnableLogging` annotation +==== [source,java] ---- @SpringBootApplication @EnableLogging(logLevel = "DEBUG") class MySpringBootApacheGeodeClientApplication { - // ... + } ---- +==== -That is to say, none of the approaches above have any effect without the **new** SBDG logging starter. +None of the preceding approaches have any effect without the *new* SBDG logging starter. [[geode-logging-configuration]] === Configure {geode-name} Logging So, how do you configure logging for {geode-name}? -Effectively, 3 things are required to get {geode-name} to log output: +Three things are required to get {geode-name} to log output: -1) First, you must declare a logging provider on your Spring Boot application classpath (e.g. _Logback_). - -2) (optional) Next, you must declare an adapter, or bridge JAR, between Log4j and your logging provider if your declared +. You must declare a logging provider (such as Logback) on your Spring Boot application classpath. +. (optional) You can declare an adapter (a bridge JAR) between Log4j and your logging provider if your declared logging provider is not Apache Log4j. - -For example, if you use the SLF4J API to log output from your Spring Boot application along with _Logback_ as your -logging provider/implementation, then you must include the `org.apache.logging.log4j.log4j-to-slf4j` adapter/bridge JAR -dependency as well. - -Internally, {geode-name} uses the Apache Log4j API to log output from Geode components. Therefore, you must bridge Log4j -to any other logging provider (e.g. _Logback_) that is not Log4j (i.e. `log4j-core`). If you are using Log4j as your -logging provider then you do not need to declare an adapter/bridge JAR on your Spring Boot application classpath. - -3) Finally, you must supply logging provider configuration to configure Loggers, Appenders, log levels, etc. - -For example, when using _Logback_, you must provide a `logback.xml` configuration file on your Spring Boot application -classpath, or in the filesystem. Alternatively, you can use other means to configure your logging provider and get ++ +For example, if you use the SLF4J API to log output from your Spring Boot application and use Logback as your +logging provider or implementation, you must include the `org.apache.logging.log4j.log4j-to-slf4j` adapter or +bridge JAR as well. ++ +Internally, {geode-name} uses the Apache Log4j API to log output from Geode components. Therefore, you must bridge Log4j +to any other logging provider (such as Logback) that is not Log4j (`log4j-core`). If you use Log4j as your +logging provider, you need not declare an adapter or bridge JAR on your Spring Boot application classpath. +. Finally, you must supply logging provider configuration to configure Loggers, Appenders, log levels, and other details. ++ +For example, when you use Logback, you must provide a `logback.xml` configuration file on your Spring Boot application +classpath or in the filesystem. Alternatively, you can use other means to configure your logging provider and get {geode-name} to log output. NOTE: {geode-name}'s `geode-log4j` module covers the required configuration for steps 1-3 above and uses Apache Log4j -(i.e. `org.apache.logging.log4j:log4j-core`) as the logging provider. The `geode-log4j` module even provides a default, -`log4j2.xml` configuration file to configure Loggers, Appenders and log levels for {geode-name}. +(`org.apache.logging.log4j:log4j-core`) as the logging provider. The `geode-log4j` module even provides a default +`log4j2.xml` configuration file to configure Loggers, Appenders, and log levels for {geode-name}. -If you declare Spring Boot's own `org.springframework.boot:spring-boot-starter-logging` on your application classpath -then this will cover Steps 1 and 2 above. +If you declare Spring Boot's own `org.springframework.boot:spring-boot-starter-logging` on your application classpath, +it covers steps 1 and 2 above. -The `spring-boot-starter-logging` dependency declares _Logback_ as the logging provider and automatically adapts, -or bridges `java.util.logging` (JUL) and Apache Log4j to SLF4J. However, you still need to supply logging provider -configuration, such as a `logback.xml` file for _Logback_, to configure logging not only for your Spring Boot -application, but also for {geode-name} as well. +The `spring-boot-starter-logging` dependency declares Logback as the logging provider and automatically adapts (bridges) +`java.util.logging` (JUL) and Apache Log4j to SLF4J. However, you still need to supply logging provider configuration +(such as a `logback.xml` file for Logback) to configure logging not only for your Spring Boot application but for +{geode-name} as well. -SBDG has simplified the setup of {geode-name} logging. Simply declare the -`org.springframework.geode:spring-geode-starter-logging` dependency on your Spring Boot application classpath! +SBDG has simplified the setup of {geode-name} logging. You need only declare the +`org.springframework.geode:spring-geode-starter-logging` dependency on your Spring Boot application classpath. -Unlike {geode-name}'s default Log4j XML configuration file (i.e. `log4j2.xml`), SBDG's provided `logback.xml` -configuration file is properly parameterized enabling you to adjust log levels as well as add Appenders. +Unlike {geode-name}'s default Log4j XML configuration file (`log4j2.xml`), SBDG's provided `logback.xml` configuration +file is properly parameterized, letting you adjust log levels as well as add Appenders. -In addition, SBDG's provided _Logback_ configuration uses templates so you can compose your own logging configuration -while still "including" snippets from SBDG's provided logging configuration metadata, such as Loggers and Appenders. +In addition, SBDG's provided Logback configuration uses templates so that you can compose your own logging configuration +while still including snippets from SBDG's provided logging configuration metadata, such as Loggers and Appenders. [[geode-logging-configuration-log-levels]] ==== Configuring Log Levels -One of the most common logging tasks is to adjust the log-level of one or more Loggers, or the ROOT Logger. However, -a user may only want to adjust the log-level for specific components of his/her Spring Boot application, such as for -{geode-name}, by setting the log-level for only the Logger that logs {geode-name} events. +One of the most common logging tasks is to adjust the log level of one or more Loggers or the ROOT Logger. However, +you may want to only adjust the log level for specific components of your Spring Boot application, such as for +{geode-name}, by setting the log level for only the Logger that logs {geode-name} events. -SBDG's _Logback_ configuration defines 3 Loggers to control the log output from {geode-name}: +SBDG's Logback configuration defines three Loggers to control the log output from {geode-name}: -.{geode-name} Loggers by name +.{geode-name} Loggers by Name +==== [source,xml] ---- @@ -132,136 +132,154 @@ SBDG's _Logback_ configuration defines 3 Loggers to control the log output from ---- +==== -The `com.gemstone.gemfire` Logger is a legacy Logger covering old GemFire bits still present in {geode-name} -for backwards compatibility reasons. This Logger's use should be largely unnecessary. +The `com.gemstone.gemfire` Logger covers old GemFire components that are still present in {geode-name} for backwards +compatibility. By default, it logs output at `INFO`. This Logger's use should be mostly unnecessary. The `org.apache.geode` Logger is the primary Logger used to control log output from all {geode-name} components -during the runtime operation of {geode-name}. Both this Logger and the legacy `com.gemstone.gemfire` Logger default -log output to `INFO`. +during the runtime operation of {geode-name}. By default, it logs output at `INFO`. The `org.jgroups` Logger is used to log output from {geode-name}'s message distribution and membership system. {geode-name} uses JGroups for membership and message distribution between peer members (nodes) in the cluster -(distributed system). By default, JGroups log messages are logged at `ERROR`. +(distributed system). By default, JGroups logs output at `ERROR`. -The log-level for the `com.gemstone.gemfire` and `org.apache.geode` Loggers are configured with the -`spring.boot.data.gemfire.log.level` property. The `org.jgroups` Logger is independently configured with the -`spring.boot.data.gemfire.jgroups.log.level` property. +You can configure the log level for the `com.gemstone.gemfire` and `org.apache.geode` Loggers by setting +the `spring.boot.data.gemfire.log.level` property. You can independently configure the `org.jgroups` Logger by setting +the `spring.boot.data.gemfire.jgroups.log.level` property. -The SBDG logging properties can be set on the command-line as JVM System Properties when running +You can set the SBDG logging properties on the command line as JVM System properties when you run your Spring Boot application: -.Setting the log-level from the command-line +.Setting the log-level from the CLI +==== [source,text] ---- $ java -classpath ...:/path/to/MySpringBootApplication.jar -Dspring.boot.data.gemfire.log.level=DEBUG package.to.MySpringBootApplicationClass ---- +==== -NOTE: Setting JVM System Properties using `$ java -jar MySpringBootApplication.jar -Dspring.boot.data.gemfire.log.level=DEBUG` +NOTE: Setting JVM System properties by using +`$ java -jar MySpringBootApplication.jar -Dspring.boot.data.gemfire.log.level=DEBUG` is not supported by the Java Runtime Environment (JRE). Alternatively, you can configure and control {geode-name} logging in Spring Boot `application.properties`: -.Setting the log-level in `application.properties` +.Setting the log-level in Spring Boot `application.properties` +==== [source,properties] ---- spring.boot.data.gemfire.log.level=DEBUG ---- +==== -For backwards compatibility, SBDG additionally supports the old _Spring Data for {geode-name}_ (SDG) logging properties -as well, using either: +For backwards compatibility, SBDG additionally supports the Spring Data for {geode-name} (SDG) logging properties +as well, by using either of the following properties: -`spring.data.gemfire.cache.log-level=DEBUG` +.Setting log-level using SDG Properties +==== +[source,properties] +---- +spring.data.gemfire.cache.log-level=DEBUG +spring.data.gemfire.logging.level=DEBUG +---- +==== -Or: - -`spring.data.gemfire.logging.level=DEBUG` - -If you previously used either of these SDG based logging properties, they will continue to work as designed in -SBDG `1.3` or later. +If you previously used either of these SDG-based logging properties, they continue to work as designed in SBDG `1.3` +or later. [[geode-logging-configuration-composition]] ==== Composing Logging Configuration -As mentioned earlier, SBDG allows you to compose your own logging configuration from SBDG's default, provided _Logback_ -configuration metadata. +As mentioned earlier, SBDG lets you compose your own logging configuration from SBDG's default Logback configuration +metadata. SBDG conveniently bundles the Loggers and Appenders from SBDG's logging starter into a template file that you can -include into your own, custom _Logback_ XML configuration file. +include into your own custom Logback XML configuration file. -The _Logback_ template file appears as follows: +The Logback template file appears as follows: .logback-include.xml +==== [source,xml] ---- include::{starter-logging-resources-dir}/logback-include.xml[] ---- +==== -Then, this Logback configuration snippet can be included in an application-specific, _Logback_ XML configuration file +Then you can include this Logback configuration snippet in an application-specific Logback XML configuration file, as follows: .logback.xml +==== [source,xml] ---- include::{starter-logging-resources-dir}/logback.xml[] ---- - +==== [[geode-logging-slf4j-logback-api-support]] -=== SLF4J & Logback API Support +=== SLF4J and Logback API Support -SBDG provides additional support when working with the SLF4J and _Logback_ APIs. This support is available when you +SBDG provides additional support when working with the SLF4J and Logback APIs. This support is available when you declare the `org.springframework.geode:spring-geode-starter-logging` dependency on your Spring Boot application classpath. One of the main supporting classes from the `spring-geode-starter-logger` -is the `org.springframework.geode.logging.slf4j.logback.LogbackSupport` class. This class provides methods to: +is the `org.springframework.geode.logging.slf4j.logback.LogbackSupport` class. This class provides methods to: -* Resolve a reference to the _Logback_ `LoggingContext` -* Resolve the SLF4J ROOT `Logger` as a _Logback_ `Logger` -* Lookup `Appenders` by name and required type -* Add/Remove `Appenders` to `Loggers` -* And even reset the state of the _Logback_ logging system, which can prove to be most useful during testing +* Resolve a reference to the Logback `LoggingContext`. +* Resolve the SLF4J ROOT `Logger` as a Logback `Logger`. +* Look up `Appenders` by name and required type. +* Add or remove `Appenders` to `Loggers`. +* Reset the state of the Logback logging system, which can prove to be most useful during testing. -`LogbackSupport` can even suppress the auto-configuration of _Logback_ performed by Spring Boot on startup, +`LogbackSupport` can even suppress the auto-configuration of Logback performed by Spring Boot on startup, which is another useful utility during automated testing. -In addition to the `LogbackSupport` class, SBDG also provides some custom _Logback_ `Appenders`. +In addition to the `LogbackSupport` class, SBDG also provides some custom Logback `Appenders`. [[geode-logging-slf4j-logback-api-support-appender-composite]] ==== CompositeAppender -The `org.springframework.geode.logging.slf4j.logback.CompositeAppender` class is an implementation of _Logback_ -`Appender` and the https://en.wikipedia.org/wiki/Composite_pattern[Composite Software Design Pattern]. +The `org.springframework.geode.logging.slf4j.logback.CompositeAppender` class is an implementation of the Logback +`Appender` interface and the https://en.wikipedia.org/wiki/Composite_pattern[Composite software design pattern]. -`CompositeAppender` enables developers to compose multiple `Appenders` and use them as if they were a single `Appender`. +`CompositeAppender` lets developers compose multiple Appenders and use them as if they were a single `Appender`. -For example, you could compose both the _Logback_ `ConsoleAppender` and `FileAppender` into one using: +For example, you could compose both the Logback `ConsoleAppender` and `FileAppender` into one `Appender`: .Composing multiple `Appenders` +==== [source,java] ---- class LoggingConfiguration { - void composeApenders() { + + Appender compositeAppender() { ConsoleAppender consoleAppender = new ConsoleAppender<>(); FileAppender fileAppender = new FileApender<>(); Appender compositeAppender = CompositeAppender.compose(consoleAppender, fileAppender); + + return compositeAppender; } } // do something with the compositeAppender ---- +==== -You could then add the `CompositeAppender` to a "named" `Logger` by doing: +You could then add the `CompositeAppender` to a named `Logger`: .Register `CompositeAppender` on "named" `Logger` +==== [source,java] ---- class LoggerConfiguration { + void registerAppenderOnLogger() { Logger namedLogger = LoggerFactory.getLogger("loggerName"); @@ -271,29 +289,32 @@ class LoggerConfiguration { } } ---- +==== -In this case, the "named" `Logger` will log events (or log messages) to both the _Console_ and _File_ `Appenders`. +In this case, the named `Logger` logs events (or log messages) to both the console and file Appenders. -It is simple to compose an array or `Iterable` of `Appenders` by using either the +You can compose an array or `Iterable` of `Appenders` by using either the `CompositeAppender.compose(:Appender[])` method or the `CompositeAppender.compose(:Iterable>)` method. [[geode-logging-slf4j-logback-api-support-appender-delegate]] ==== DelegatingAppender -The `org.springframework.geode.logging.slf4j.logback.DelegatingAppender` is a pass-through _Logback_ `Appender` -implementation wrapping another _Logback_ `Appender`, or collection of `Appenders` doing actual work, like the -`ConsoleAppender`, a `FileAppender` or a `SocketAppender`, etc. By default, the `DelegatingAppender` delegates -to the `NOPAppender` thereby doing no actual work. +The `org.springframework.geode.logging.slf4j.logback.DelegatingAppender` is a pass-through Logback `Appender` +implementation that wraps another Logback `Appender` or collection of `Appenders`, such as the `ConsoleAppender`, +a `FileAppender`, a `SocketAppender`, or others. By default, the `DelegatingAppender` delegates to the `NOPAppender`, +thereby doing no actual work. -By default, SBDG registers the `org.springframework.geode.logging.slfj4.logback.DelegatingAppender` with -the ROOT `Logger`, which can be useful for testing purposes. +By default, SBDG registers the `org.springframework.geode.logging.slfj4.logback.DelegatingAppender` with the ROOT +`Logger`, which can be useful for testing purposes. -With a reference to a `DelegatingAppender`, you can add any `Appender` as the delegate, even a `CompositeAppender`: +With a reference to a `DelegatingAppender`, you can add any `Appender` (even a `CompositeAppender`) as the delegate: .Add `ConsoleAppender` as the "delegate" for the `DelegatingAppender` +==== [source,java] ---- class LoggerConfiguration { + void setupDelegation() { ConsoleAppender consoleAppender = new ConsoleAppender(); @@ -311,20 +332,22 @@ class LoggerConfiguration { } } ---- +==== [[geode-logging-slf4j-logback-api-support-appender-string]] ==== StringAppender -The `org.springframework.geode.logging.slf4j.logback.StringAppender` stores log message in-memory, appended to +The `org.springframework.geode.logging.slf4j.logback.StringAppender` stores a log message in-memory, appended to a `String`. -The `StringAppender` is very useful for testing purposes. For instance, you can use the `StringAppender` to assert that -a `Logger` used by certain application components logged messages at the appropriately configured log level while other -log messages were not logged. +The `StringAppender` is useful for testing purposes. For instance, you can use the `StringAppender` to assert that +a `Logger` used by certain application components logged messages at the appropriately configured log level +while other log messages were not logged. -For example: +Consider the following example: .`StringAppender` in Action +==== [source,java] ---- class ApplicationComponent { @@ -379,9 +402,10 @@ class ApplicationComponentUnitTests { } } ---- +==== -There are many other uses for the `StringAppender` and it can be used safely in a multi-Threaded context by calling +There are many other uses for the `StringAppender` and you can use it safely in a multi-Threaded context by calling `StringAppender.Builder.useSynchronization()`. When combined with other SBDG provided `Appenders` in conjunction with the `LogbackSupport` class, you have a lot of -power both in application code as well as your tests. +power both in application code as well as in your tests. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/repositories.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/repositories.adoc index 2fe80c85..27a0fa1a 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/repositories.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/repositories.adoc @@ -3,27 +3,27 @@ :geode-name: {apache-geode-name} -Using Spring Data Repositories with {geode-name} makes short work of data access operations when using {geode-name} -as your System of Record (SOR) to persist your application's state. +Using Spring Data Repositories with {geode-name} makes short work of data access operations when you use {geode-name} +as your System of Record (SoR) to persist your application's state. -{spring-data-commons-docs-html}/#repositories[Spring Data Repositories] provides a convenient and highly powerful way -to define basic CRUD and simple query data access operations easily just by specifying the contract of those data access -operations in a Java interface. +{spring-data-commons-docs-html}/#repositories[Spring Data Repositories] provide a convenient and powerful way to define +basic CRUD and simple query data access operations by specifying the contract of those data access operations in a Java +interface. -Spring Boot for {geode-name} _auto-configures_ the Spring Data for {geode-name} {spring-data-geode-docs-html}/#gemfire-repositories[Repository extension] -when either is declared on your application's classpath. You do not need to do anything special to enable it. Simply -start coding your application-specific Repository interfaces and the way you go. +Spring Boot for {geode-name} auto-configures the Spring Data for {geode-name} +{spring-data-geode-docs-html}/#gemfire-repositories[Repository extension] +when either is declared on your application's classpath. You need not do anything special to enable it. You can start +coding your application-specific Repository interfaces. -For example: - -Define a `Customer` class to model customers and map it to the {geode-name} "Customers" Region using the SDG -{spring-data-geode-javadoc}/org/springframework/data/gemfire/mapping/annotation/Region.html[`@Region`] mapping -annotation: +The following example defines a `Customer` class to model customers and map it to the {geode-name} `Customers` Region +by using the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/mapping/annotation/Region.html[`@Region`] +mapping annotation: .`Customer` entity class +==== [source,java] ---- -package example.app.books.model; +package example.app.crm.model; @Region("Customers") class Customer { @@ -35,13 +35,16 @@ class Customer { } ---- +==== -Declare your _Repository_ (a.k.a. {wikipedia-docs}/Data_access_object[Data Access Object (DAO)]) for `Customers`... +The following example shows how to declare your Repository (a.k.a. {wikipedia-docs}/Data_access_object[Data Access Object (DAO)]) +for `Customers`: .`CustomerRepository` for peristing and accessing `Customers` +==== [source,java] ---- -package example.app.books.repo; +package example.app.crm.repo; interface CustomerRepository extends CrudRepository { @@ -49,10 +52,12 @@ interface CustomerRepository extends CrudRepository { } ---- +==== -Then use the `CustomerRepository` in an application service class: +Then you can use the `CustomerRepository` in an application service class: .Inject and use the `CustomerRepository` +==== [source,java] ---- package example.app; @@ -76,7 +81,8 @@ class SpringBootApacheGeodeClientCacheApplication { } } ---- +==== -Again, see Spring Data Commons' {spring-data-commons-docs-html}/#repositories[Repositories abstraction] in general, +See Spring Data Commons' {spring-data-commons-docs-html}/#repositories[Repositories abstraction] and Spring Data for {geode-name}'s {spring-data-geode-docs-html}/#gemfire-repositories[Repositories extension] -in particular, for more details. +for more detail. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/samples.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/samples.adoc index 5d3e5a6b..2f4a7c45 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/samples.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/samples.adoc @@ -3,61 +3,59 @@ :geode-name: {apache-geode-name} -This section contains working examples demonstrating how to use Spring Boot for {geode-name} (SBDG) effectively. +This section contains working examples that show how to use Spring Boot for {geode-name} (SBDG) effectively. -Some examples focus on specific Use Cases (e.g. [(HTTP) Session state] caching) while other examples demonstrate how -SBDG works under-the-hood to give users a better understanding of what is actually happening and how to debug problems -with their {geode-name}, Spring Boot applications. +Some examples focus on specific use cases (such as (HTTP) session state caching), while other examples show how SBDG +works under the hood, to give you a better understanding of what is actually happening and how to debug problems with +your Spring Boot {geode-name} applications. .Example Spring Boot applications using {geode-name} |=== | Guide | Description | Source | link:guides/getting-started.html[Getting Started with Spring Boot for {geode-name}] -| Explains how to get started quickly, easily and reliably building {geode-name} and Pivotal Cloud Cache powered -applications with Spring Boot. +| Explains how to get started quickly, easily, and reliably building {geode-name} powered applications with Spring Boot. | {github-samples-url}/intro/getting-started[Getting Started] | link:guides/boot-configuration.html[Spring Boot Auto-Configuration for {geode-name}] -| Explains what auto-configuration is provided by SBDG out-of-the-box and what the auto-configuration is doing. -| {github-samples-url}/boot/configuration[Boot Auto-Configuration] +| Explains what auto-configuration is provided by SBDG and what the auto-configuration does. +| {github-samples-url}/boot/configuration[Spring Boot Auto-Configuration] | link:guides/boot-actuator.html[Spring Boot Actuator for {geode-name}] | Explains how to use Spring Boot Actuator for {geode-name} and how it works. -| {github-samples-url}/boot/actuator[Boot Actuator] +| {github-samples-url}/boot/actuator[Spring Boot Actuator] | link:guides/boot-security.html[Spring Boot Security for {geode-name}] -| Explains how to configure Auth and TLS with SSL when using {geode-name} and Pivotal Cloud Cache -in Spring Boot applications. -| {github-samples-url}/boot/security[Boot Security] +| Explains how to configure auth and TLS with SSL when you use {geode-name} in your Spring Boot applications. +| {github-samples-url}/boot/security[Spring Boot Security] | link:guides/caching-look-aside.html[Look-Aside Caching with Spring's Cache Abstraction and {geode-name}] -| Explains how to enable and use the Spring Cache Abstraction with {geode-name} as the caching provider for Look-Aside Caching. +| Explains how to enable and use Spring's Cache Abstraction with {geode-name} as the caching provider +for look-aside caching. | {github-samples-url}/caching/look-aside[Look-Aside Caching] | link:guides/caching-inline.html[Inline Caching with Spring's Cache Abstraction and {geode-name}] -| Explains how to enable and use the Spring Cache Abstraction with {geode-name} as the caching provider for Inline Caching. -This sample builds on the *_Look-Aside Caching_* sample above. +| Explains how to enable and use Spring's Cache Abstraction with {geode-name} as the caching provider for inline caching. +This sample builds on the look-aside caching sample. | {github-samples-url}/caching/inline[Inline Caching] | link:guides/caching-inline-async.html[Asynchronous Inline Caching with Spring's Cache Abstraction and {geode-name}] -| Explains how to enable and use the Spring Cache Abstraction with {geode-name} as the caching provider for Asynchronous -Inline Caching. This sample builds on the *_Look-Aside Caching_* and *Inline Caching* samples above. +| Explains how to enable and use Spring's Cache Abstraction with {geode-name} as the caching provider for asynchronous +inline caching. This sample builds on the look-aside and inline caching samples. | {github-samples-url}/caching/inline-async[Asynchronous Inline Caching] | link:guides/caching-near.html[Near Caching with Spring's Cache Abstraction and {geode-name}] -| Explains how to enable and use the Spring Cache Abstraction with {geode-name} as the caching provider for Near Caching. -This sample builds on the *_Look-Aside Caching_* sample above +| Explains how to enable and use Spring's Cache Abstraction with {geode-name} as the caching provider for near caching. +This sample builds on the look-aside caching sample. | {github-samples-url}/caching/near[Near Caching] | link:guides/caching-multi-site.html[Multi-Site Caching with Spring's Cache Abstraction and {geode-name}] -| Explains how to enable and use the Spring Cache Abstraction with {geode-name} as the caching provider for Multi-Site Caching. -This sample builds on the *_Look-Aside Caching_* sample above and is the 4th and final leg in our study -of _caching patterns_. +| Explains how to enable and use Spring's Cache Abstraction with {geode-name} as the caching provider for multi-site +caching. This sample builds on the look-aside caching sample. | {github-samples-url}/caching/multi-site[Multi-Site Caching] | link:guides/caching-http-session.html[HTTP Session Caching with Spring Session and {geode-name}] -| Explains how to enable and use Spring Session with {geode-name} to manage HTTP Session state. +| Explains how to enable and use Spring Session with {geode-name} to manage HTTP session state. | {github-samples-url}/caching/http-session[HTTP Session Caching] |=== diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/security.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/security.adoc index 70df62ba..d7d01eaf 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/security.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/security.adoc @@ -3,42 +3,42 @@ :geode-name: {apache-geode-name} -This sections covers Security configuration for {geode-name}, which includes both Authentication & Authorization -(collectively, Auth) as well as Transport Layer Security (TLS) using SSL. +This chapter covers security configuration for {geode-name}, which includes both authentication and authorization +(collectively, auth) as well as Transport Layer Security (TLS) using SSL. -NOTE: Securing Data at Rest is not supported by {geode-name}. +NOTE: Securing data at rest is not supported by {geode-name}. -TIP: Refer to the corresponding Sample link:guides/boot-security.html[Guide] and {github-samples-url}/boot/security[Code] -to see Spring Boot Security for {geode-name} in action! +TIP: See the corresponding sample link:guides/boot-security.html[guide] and {github-samples-url}/boot/security[code] +to see Spring Boot Security for {geode-name} in action. [[geode-security-auth]] -=== Authentication & Authorization +=== Authentication and Authorization -{geode-name} employs Username and Password based {apache-geode-docs}/managing/security/authentication_overview.html[Authentication] -along with Role-based {apache-geode-docs}/managing/security/authorization_overview.html[Authorization] to secure -your client to server data exchanges and operations. +{geode-name} employs username- and password-based {apache-geode-docs}/managing/security/authentication_overview.html[authentication] +and role-based {apache-geode-docs}/managing/security/authorization_overview.html[authorization] to secure your client to +server data exchanges and operations. Spring Data for {geode-name} provides {spring-data-geode-docs-html}/#bootstrap-annotation-config-security[first-class support] for {geode-name}'s Security framework, which is based on the -{apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[SecurityManager] interface. -Additionally, {geode-name}'s Security framework is integrated with https://shiro.apache.org/[Apache Shiro], -making the security for servers an even easier and more familiar task. +{apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[`SecurityManager`] interface. +Additionally, {geode-name}'s Security framework is integrated with https://shiro.apache.org/[Apache Shiro]. -NOTE: Eventually, support and integration with https://spring.io/projects/spring-security[Spring Security] -will be provided by SBDG as well. +NOTE: SBDG will eventually provide support for and integration with +https://spring.io/projects/spring-security[Spring Security]. -When you use Spring Boot for {geode-name}, which builds on the bits provided in Spring Data for {geode-name}, -it makes short work of enabling Auth in both your clients and servers. +When you use Spring Boot for {geode-name}, which builds Spring Data for {geode-name}, it makes short work of +enabling auth in both your clients and servers. [[geode-security-auth-servers]] ==== Auth for Servers -The easiest and most standard way to enable Auth in the servers of your cluster is to simply define 1 or more +The easiest and most standard way to enable auth in the servers of your cluster is to simply define one or more Apache Shiro https://shiro.apache.org/realm.html[Realms] as beans in the Spring `ApplicationContext`. -For example: +Consider the following example: .Declaring an Apache Shiro Realm +==== [source,java] ---- @Configuration @@ -52,17 +52,18 @@ class ApacheGeodeSecurityConfiguration { // ... } ---- +==== -When an Apache Shiro Realm (e.g. `DefaultLdapRealm`) is declared and registered in the Spring `ApplicationContext` as a -Spring bean, Spring Boot will automatically detect this `Realm` bean (or `Realm` beans if more than 1 is configured) -and the {geode-name} servers in the cluster will automatically be configured with Authentication and Authorization -enabled. +When an Apache Shiro Realm (such as `DefaultLdapRealm`) is declared and registered in the Spring `ApplicationContext` +as a Spring bean, Spring Boot automatically detects this `Realm` bean (or `Realm` beans if more than one is configured), +and the servers in the {geode-name} cluster are automatically configured with authentication and authorization enabled. -Alternatively, you can provide an custom, application-specific implementation of {geode-name}'s -{apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[SecurityManager] interface, +Alternatively, you can provide a custom, application-specific implementation of {geode-name}'s +{apache-geode-javadoc}/org/apache/geode/security/SecurityManager.html[`SecurityManager`] interface, declared and registered as a bean in the Spring `ApplicationContext`: .Declaring a custom {geode-name} `SecurityManager` +==== [source,java] ---- @Configuration @@ -76,28 +77,31 @@ class ApacheGeodeSecurityConfiguration { // ... } ---- +==== -Spring Boot will discover your custom, application-specific `SecurityManager` implementation and configure -the servers in the {geode-name} cluster with Authentication and Authorization enabled. +Spring Boot discovers your custom, application-specific `SecurityManager` implementation and configures the servers +in the {geode-name} cluster with authentication and authorization enabled. -TIP: The Spring team recommends that you use Apache Shiro to manage the Authentication & Authorization of your -{geode-name} servers over implementing {geode-name}'s `SecurityManager` interface. +TIP: The Spring team recommends that you use Apache Shiro to manage the authentication and authorization of your +servers over implementing {geode-name}'s `SecurityManager` interface. [[geode-security-auth-clients]] ==== Auth for Clients -When {geode-name} servers have been configured with Authentication & Authorization enabled, then clients must -authenticate when connecting. +When servers in an {geode-name} cluster have been configured with authentication and authorization enabled, clients +must authenticate when connecting. -Spring Boot for {geode-name} makes this easy, regardless of whether you are running your Spring Boot, `ClientCache` -applications in a local, non-managed environment or even when running in a cloud managed environment. +Spring Boot for {geode-name} makes this easy, regardless of whether you run your Spring Boot `ClientCache` applications +in a local, non-managed environment or run in a cloud-managed environment. [[geode-security-auth-clients-non-managed]] ===== Non-Managed Auth for Clients -To enable Auth for clients connecting to a secure {geode-name} cluster, you simply only need to set a username -and password in your Spring Boot `application.properties` file: +To enable auth for clients that connect to a secure {geode-name} cluster, you need only set a username and password +in Spring Boot `application.properties`: +.Spring Boot `application.properties` for the client +==== [source,txt] ---- # Spring Boot client application.properties @@ -105,71 +109,72 @@ and password in your Spring Boot `application.properties` file: spring.data.gemfire.security.username = jdoe spring.data.gemfire.security.password = p@55w0rd ---- +==== -Spring Boot for {geode-name} will handle the rest. +Spring Boot for {geode-name} handles the rest. [[geode-secuirty-auth-clients-managed]] ===== Managed Auth for Clients -Enabling Auth for clients connecting to a Pivotal Cloud Cache (PCC) service instance in Pivotal CloudFoundry (PCF) -is even easier. +Enabling auth for clients that connect to a {pivotal-cloudcache-name} service instance (PCC) +in {pivotal-cloudfoundry-name} (PCF) is even easier: You need do nothing. -You do not need to do anything! +If your Spring Boot application uses SBDG and is bound to PCC, when you deploy (that is, `cf push`) your application +to PCF, Spring Boot for {geode-name} extracts the required auth credentials from the environment that you set up when +you provisioned a PCC service instance in your PCF organization and space. PCC automatically assigns two users with +roles of `cluster_operator` and `developer`, respectively, to any Spring Boot application bound to the PCC service +instance. -When your Spring Boot application uses SBDG and is bound to PCC, then when you push (i.e. deploy) your app to PCF, -Spring Boot for {geode-name} will extract the required Auth credentials from the environment that you setup when you -provisioned a PCC service instance in your PCF organization & space. PCC automatically assigns 2 users with roles -"_cluster_operator_" and "_developer_", respectively, to any Spring Boot application bound to the PCC service instance. - -By default, SBDG will auto-configure your Spring Boot app to run with the user having the "_cluster_operator" Role. -This ensures that your Spring Boot app has the necessary permissions (i.e. Authorization) to perform all data access -operations on the servers in the PCC cluster including, for example, pushing configuration metadata from the client +By default, SBDG auto-configures your Spring Boot application to run with the user that has the `cluster_operator` role. +This ensures that your Spring Boot application has the necessary permission (authorization) to perform all data access +operations on the servers in the PCC cluster, including, for example, pushing configuration metadata from the client to the servers in the PCC cluster. -See the section, <<[cloudfoundry-cloudcache-security-auth-runtime-user-configuration,Running Spring Boot applications as a specific user>>, -in the <> chapter for additional details on user authentication and authorization. +See the <> section +in the <> chapter for additional details on user authentication and authorization. -See the <> titled '_Pivotal CloudFoundry_' for more general details. +See the <> (titled "`Pivotal CloudFoundry`") for more general details. See the {pivotal-cloudcache-docs}/security.html[Pivotal Cloud Cache documentation] for security details -when using PCC and PCF. +when you use PCC and PCF. [[geode-security-ssl]] === Transport Layer Security using SSL -Securing data in motion is also essential to the integrity of your application. +Securing data in motion is also essential to the integrity of your Spring [Boot] applications. -For instance, it would not do much good to send usernames and passwords over plain text Socket connections -between your clients and servers, nor send sensitive data over those same connections. +For instance, it would not do much good to send usernames and passwords over plain text socket connections +between your clients and servers nor to send other sensitive data over those same connections. -Therefore, {geode-name} supports SSL between clients & servers, JMX clients (e.g. _Gfsh_) and the _Manager_, -HTTP clients when using the Developer REST API or _Pulse_, between peers in the cluster, and when using the WAN Gateway -to connect multiple sites (i.e. clusters). +Therefore, {geode-name} supports SSL between clients and servers, between JMX clients (such as Gfsh) and the Manager, +between HTTP clients when you use the Developer REST API or Pulse, between peers in the cluster, and when you use +the WAN Gateway to connect multiple sites (clusters). Spring Data for {geode-name} provides https://docs.spring.io/spring-data/geode/docs/current/reference/html/#bootstrap-annotation-config-ssl[first-class support] -for configuring and enabling SSL as well. Still, Spring Boot makes it even easier to configure and enable SSL, +for configuring and enabling SSL as well. Still, Spring Boot makes it even easier to configure and enable SSL, especially during development. -{geode-name} requires certain properties to be configured, which translate to the appropriate -`javax.net.ssl.*` properties required by the JRE, to create Secure Socket Connections using +{geode-name} requires certain properties to be configured. These properties translate to the appropriate +`javax.net.ssl.*` properties required by the JRE to create secure socket connections by using https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/JSSERefGuide.html[JSSE]. -But, ensuring that you have set all the required SSL properties correctly is an error prone and tedious task. -Therefore, Spring Boot for {geode-name} applies some basic conventions for you, out-of-the-box. +However, ensuring that you have set all the required SSL properties correctly is an error prone and tedious task. +Therefore, Spring Boot for {geode-name} applies some basic conventions for you. -Simply create a `trusted.keystore`, JKS-based `KeyStore` file and place it in 1 of 3 well-known locations: +You can create a `trusted.keystore` as a JKS-based `KeyStore` file and place it in one of three well-known locations: -1. In your application JAR file at the root of the classpath. -2. In your Spring Boot application's working directory. -3. In your user home directory (as defined by the `user.home` Java System property). +* In your application JAR file at the root of the classpath. +* In your Spring Boot application's working directory. +* In your user home directory (as defined by the `user.home` Java System property). -When this file is named `trusted.keystore` and is placed in 1 of these 3 well-known locations, Spring Boot -for {geode-name} will automatically configure your client to use SSL Socket connections. +When this file is named `trusted.keystore` and is placed in one of these three well-known locations, Spring Boot +for {geode-name} automatically configures your client to use SSL socket connections. -If you are using Spring Boot to configure and bootstrap an {geode-name} server: +If you use Spring Boot to configure and bootstrap an {geode-name} server: .Spring Boot configured and bootstrapped {geode-name} server +==== [source,java] ---- @SpringBootApplication @@ -178,27 +183,31 @@ class SpringBootApacheGeodeCacheServerApplication { // ... } ---- +==== -Then, Spring Boot will apply the same procedure to enable SSL on the servers, between peers, as well. +Then Spring Boot also applies the same procedure to enable SSL on the servers (between peers). -TIP: During development it is convenient *not* to set a `trusted.keystore` password when accessing the keys in the JKS +TIP: During development, it is convenient to *not* set a `trusted.keystore` password when accessing the keys in the JKS file. However, it is highly recommended that you secure the `trusted.keystore` file when deploying your application to a production environment. -If your `trusted.keystore` file is secured with a password, you will need to additionally specify the following property: +If your `trusted.keystore` file is secured with a password, you need to additionally specify the following property: .Accessing a secure `trusted.keystore` +==== [source,txt] ---- # Spring Boot application.properties -spring.data.gemfire.security.ssl.keystore.password = p@55w0rd! +spring.data.gemfire.security.ssl.keystore.password=p@55w0rd! ---- +==== -You can also configure the location of the keystore and truststore files, if they are separate, and have not been placed -in 1 of the default, well-known locations searched by Spring Boot: +You can also configure the location of the keystore and truststore files, if they are separate and have not been placed +in one of the default, well-known locations searched by Spring Boot: -.Accessing a secure `trusted.keystore` +.Accessing a secure `trusted.keystore` by location +==== [source,txt] ---- # Spring Boot application.properties @@ -208,18 +217,19 @@ spring.data.gemfire.security.ssl.keystore.password = keystorePassword spring.data.gemfire.security.ssl.truststore = /absolute/file/system/path/to/truststore.jks spring.data.gemfire.security.ssl.truststore.password = truststorePassword ---- +==== -See the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html[EnableSsl] +See the SDG {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableSsl.html[`EnableSsl`] annotation for all the configuration attributes and the corresponding properties expressed in `application.properties`. [[geode-security-encryption]] === Securing Data at Rest -Currently, neither {geode-name} nor Spring Boot or Spring Data for {geode-name} offer any support for securing your data -while at rest (e.g. when your data has been overflowed or persisted to disk). +Currently, neither {geode-name} nor Spring Boot nor Spring Data for {geode-name} offer any support for securing your +data while at rest (for example, when your data has been overflowed or persisted to disk). -To secure data at rest when using {geode-name}, with or without Spring, you must employ 3rd party solutions like disk -encryption, which is usually highly contextual and technology specific. +To secure data at rest when using {geode-name}, with or without Spring, you must employ third-party solutions, such as +disk encryption, which is usually highly contextual and technology-specific. -For example, to secure data at rest using Amazon EC2, see +For example, to secure data at rest when you use Amazon EC2, see https://aws.amazon.com/blogs/security/how-to-protect-data-at-rest-with-amazon-ec2-instance-store-encryption/[Instance Store Encryption]. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/session.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/session.adoc index d06aa2d4..de24b2e2 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/session.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/session.adoc @@ -1,41 +1,42 @@ [[geode-session]] == Spring Session :geode-name: {apache-geode-name} -:pcc-name: Pivotal Cloud Cache -:vmw-tas-name: VMware Tanzu Application Service +:pcc-name: {pivotal-cloudcache-name} +:vmw-tas-name: {pivotal-cloudfoundry-name} -This chapter covers auto-configuration of Spring Session using {geode-name} to manage (HTTP) Session state in a reliable -(consistent), highly-available (replicated) and clustered manner. +This chapter covers auto-configuration of Spring Session for {geode-name} to manage (HTTP) session state in a reliable +(consistent), highly available (replicated), and clustered manner. {spring-session-website}[Spring Session] provides an API and several implementations for managing a user's session -information. It has the ability to replace the `javax.servlet.http.HttpSession` in an application container neutral -way along with providing Session IDs in HTTP headers to work with RESTful APIs. +information. It has the ability to replace the `javax.servlet.http.HttpSession` in an application container-neutral way +and provide session IDs in HTTP headers to work with RESTful APIs. -Furthermore, Spring Session provides the ability to keep the HttpSession alive even when working with WebSockets -and reactive Spring WebFlux WebSessions. +Furthermore, Spring Session provides the ability to keep the `HttpSession` alive even when working with `WebSockets` +and reactive Spring WebFlux `WebSessions`. -A full discussion of Spring Session is beyond the scope of this document, and the reader is encouraged to learn more -by reading the {spring-session-docs}[docs] and reviewing the {spring-session-docs}/#samples[samples]. +A complete discussion of Spring Session is beyond the scope of this document. You can learn more by reading +the {spring-session-docs}[docs] and reviewing the {spring-session-docs}/#samples[samples]. -Of course, Spring Boot for {geode-name} provides auto-configuration support to configure {geode-name} -as the user's session information management provider and store when {spring-session-data-gemfire-website}[Spring Session for {geode-name}] -is on your Spring Boot application's classpath. +Spring Boot for {geode-name} provides auto-configuration support to configure {geode-name} as the session management +provider and store when {spring-session-data-gemfire-website}[Spring Session for {geode-name}] is on your Spring Boot +application's classpath. TIP: You can learn more about Spring Session for {geode-name} in the {spring-session-data-gemfire-docs}[docs]. -TIP: Refer to the corresponding Sample link:guides/caching-http-session.html.html[Guide] and {github-samples-url}/caching/http-session[Code] -to see Spring Session for {geode-name} in action! +TIP: See the corresponding sample link:guides/caching-http-session.html.html[guide] +and {github-samples-url}/caching/http-session[code] to see Spring Session for {geode-name} in action. [[geode-session-configuration]] === Configuration -There is nothing special that you need to do in order to use {geode-name} as a Spring Session provider, -managing the (HTTP) Session state of your Spring Boot application. +You need do nothing special to use {geode-name} as a Spring Session provider implementation, managing the (HTTP) session +state of your Spring Boot application. -Simply include the appropriate Spring Session dependency on your Spring Boot application's classpath, for example: +To do so, include the appropriate Spring Session dependency on your Spring Boot application's classpath: .Maven dependency declaration +==== [source,xml] [subs="verbatim,attributes"] ---- @@ -45,11 +46,13 @@ Simply include the appropriate Spring Session dependency on your Spring Boot app {spring-session-data-gemfire-version} ---- +==== Alternatively, you may declare the provided `spring-geode-starter-session` dependency in your Spring Boot application -Maven POM or Gradle build file: +Maven POM (shown here) or Gradle build file: .Maven dependency declaration +==== [source,xml] [subs="verbatim,attributes"] ---- @@ -59,10 +62,12 @@ Maven POM or Gradle build file: {version} ---- +==== -After declaring the required Spring Session dependency, then begin your Spring Boot application as you normally would: +After declaring the required Spring Session dependency, you can begin your Spring Boot application as you normally would: .Spring Boot Application +==== [source,java] ---- @SpringBootApplication @@ -75,13 +80,13 @@ public class MySpringBootApplication { // ... } ---- +==== -That is it! +You can then create application-specific Spring Web MVC `Controllers` to interact with the `HttpSession` as needed +by your application: -Of course, you are free to create application-specific, Spring Web MVC `Controllers` to interact with the `HttpSession` -as needed by your application: - -.Application Controller using HttpSession +.Spring Boot Application `Controller` using `HttpSession` +==== [source,java] ---- @Controller @@ -93,52 +98,54 @@ class MyApplicationController { } } ---- +==== -The `HttpSession` is replaced by a Spring managed `Session` that will be stored in {geode-name}. +The `HttpSession` is replaced by a Spring managed `Session` that is stored in {geode-name}. [[geode-session-configuration-custom]] === Custom Configuration -By default, Spring Boot for {geode-name} (SBDG) applies reasonable and sensible defaults when configuring -{geode-name} as the provider in Spring Session. +By default, Spring Boot for {geode-name} (SBDG) applies reasonable and sensible defaults when configuring {geode-name} +as the provider in Spring Session. -So, for instance, by default, SBDG set the session expiration timeout to 30 minutes. It also uses a -`ClientRegionShortcut.PROXY` as the client Region data management policy for the {geode-name} -Region managing the (HTTP) Session state when the Spring Boot application is using a `ClientCache`, which it does -by <>. +For instance, by default, SBDG sets the session expiration timeout to 30 minutes. It also uses a +`ClientRegionShortcut.PROXY` as the data management policy for the {geode-name} client Region that managing the (HTTP) +session state when the Spring Boot application is using a `ClientCache`, which it does +by <>. However, what if the defaults are not sufficient for your application requirements? +In that case, see the next section. + [[geode-session-configuration-custom-properties]] ==== Custom Configuration using Properties Spring Session for {geode-name} publishes {spring-session-data-gemfire-docs}/#httpsession-gemfire-configuration-properties[well-known configuration properties] -for each of the various Spring Session configuration options when using {geode-name} as the (HTTP) Session state +for each of the various Spring Session configuration options when you use {geode-name} as the (HTTP) session state management provider. -You may specify any of these properties in a Spring Boot `application.properties` file to adjust Spring Session's -configuration when using {geode-name}. +You can specify any of these properties in Spring Boot `application.properties` to adjust Spring Session's configuration +when using {geode-name}. -In addition to the properties provided in and by Spring Session for {geode-name}, Spring Boot for {geode-name} -also recognizes and respects the `spring.session.timeout` property as well as the `server.servlet.session.timeout` -property as discussed {spring-boot-docs-html}/boot-features-session.html[here]. +In addition to the properties provided in and by Spring Session for {geode-name}, Spring Boot for {geode-name} also +recognizes and respects the `spring.session.timeout` property and the `server.servlet.session.timeout` property, as +discussed {spring-boot-docs-html}/boot-features-session.html[the Spring Boot documentation]. TIP: `spring.session.data.gemfire.session.expiration.max-inactive-interval-seconds` takes precedence over -`spring.session.timeout`, which takes precedence over `server.servlet.session.timeout`, when any combination -of these properties have been simultaneously configured in the Spring `Environment` of your application. +`spring.session.timeout`, which takes precedence over `server.servlet.session.timeout` when any combination of +these properties have been simultaneously configured in the Spring `Environment` of your application. [[geode-session-configuration-custom-configurer]] ==== Custom Configuration using a Configurer Spring Session for {geode-name} also provides the {spring-session-data-gemfire-javadoc}/org/springframework/session/data/gemfire/config/annotation/web/http/support/SpringSessionGemFireConfigurer.html[`SpringSessionGemFireConfigurer`] -callback interface, which can be declared in your Spring `ApplicationContext` to programmatically control -the configuration of Spring Session when using {geode-name}. +callback interface, which you can declare in your Spring `ApplicationContext` to programmatically control +the configuration of Spring Session when you use {geode-name}. -The `SpringSessionGemFireConfigurer`, when declared in the Spring `ApplicationContext`, takes precedence over any of the -Spring Session (for {geode-name}) configuration properties, and will effectively override them when both -are present. +The `SpringSessionGemFireConfigurer`, when declared in the Spring `ApplicationContext`, takes precedence over any of +the Spring Session (for {geode-name}) configuration properties and effectively overrides them when both are present. More information on using the `SpringSessionGemFireConfigurer` can be found in the {spring-session-data-gemfire-docs}/#httpsession-gemfire-configuration-configurer[docs]. @@ -146,15 +153,19 @@ More information on using the `SpringSessionGemFireConfigurer` can be found in t [[geode-session-disable]] === Disabling Session State Caching -There may be cases where you do not want your Spring Boot application to manage (HTTP) Session state using {geode-name}. -In certain cases, you may be using another Spring Session provider, such as Redis, to cache and manage your Spring Boot -application's (HTTP) Session state, while, even in other cases, you do not want to use Spring Session to manage your -(HTTP) Session state at all. Rather, you prefer to use your Web Server's (e.g. Tomcat) `HttpSession` state management. +There may be cases where you do not want your Spring Boot application to manage (HTTP) session state by using +{geode-name}. -Either way, you can specifically call out your Spring Session provider using the `spring.session.store-type` property -in `application.properties`, as follows: +In certain cases, you may be using another Spring Session provider implementation, such as Redis, to cache and manage +your Spring Boot application's (HTTP) session state. In other cases, you do not want to use Spring Session to manage +your (HTTP) session state at all. Rather, you prefer to use your Web Server's (such as Tomcat's) built-in `HttpSession` +state management capabilities. -.Use Redis as the Spring Session Provider +Either way, you can specifically call out your Spring Session provider implementation by using +the `spring.session.store-type` property in Spring Boot `application.properties`: + +.Use Redis as the Spring Session Provider Implementation +==== [source,txt] ---- #application.properties @@ -162,11 +173,13 @@ in `application.properties`, as follows: spring.session.store-type=redis ... ---- +==== -If you prefer not to use Spring Session to manage your Spring Boot application's (HTTP) Session state at all, then -do the following: +If you prefer not to use Spring Session to manage your Spring Boot application's (HTTP) session state at all, you can do +the following: .Use Web Server Session State Management +==== [source,txt] ---- #application.properties @@ -174,33 +187,46 @@ do the following: spring.session.store-type=none ... ---- +==== -Again, see Spring Boot {spring-boot-docs-html}/boot-features-session.html[docs] for more details. +Again, see the Spring Boot {spring-boot-docs-html}/boot-features-session.html[documentation] for more detail. -TIP: It is possible to include multiple providers on the classpath of your Spring Boot application. For instance, -you might be using Redis to cache your application's (HTTP) Session state while using {geode-name} as your -application's persistent store (_System of Record_). +TIP: You can include multiple provider implementations on the classpath of your Spring Boot application. For instance, +you might use Redis to cache your application's (HTTP) session state while using {geode-name} as your application's +transactional persistent store (System of Record). NOTE: Spring Boot does not properly recognize `spring.session.store-type=[gemfire|geode]` even though -Spring Boot for {geode-name} is setup to handle either of these property values -(i.e. either "`gemfire`" or "`geode`"). +Spring Boot for {geode-name} is set up to handle either of these property values +(that is, either `gemfire` or `geode`). [[geode-session-pcc]] === Using Spring Session with {pcc-name} (PCC) -Whether you are using Spring Session in a Spring Boot `ClientCache` application connecting to an externally managed -cluster of {geode-name} servers, or connecting to a cluster of servers in a {pcc-name} service instance managed by -a {vmw-tas-name} (TAS) environment, the setup is the same. +Whether you use Spring Session in a Spring Boot, {geode-name} `ClientCache` application to connect to an standalone, +externally managed cluster of {geode-name} servers or to connect to a cluster of servers in a {pcc-name} service +instance managed by a {vmw-tas-name} environment, the setup is the same. -Spring Session for {geode-name} expects there to exist a cache Region in the cluster that will store and manage (HTTP) -Session state when your Spring Boot application is a `ClientCache` application in a client/server topology. +Spring Session for {geode-name} expects there to be a cache Region in the cluster that can store and manage (HTTP) +session state when your Spring Boot application is a `ClientCache` application in the client/server topology. -By default, the cache Region used to store and manage (HTTP) Session state is called "_ClusteredSpringSessions_". +By default, the cache Region used to store and manage (HTTP) session state is called `ClusteredSpringSessions`. -You can set the name of the cache Region used to store and manage (HTTP) Session state either by explicitly declaring -the `@EnableGemFireHttpSession` annotation on your main `@SpringBootApplication` class, like so: +We recommend that you configure the cache Region name by using the well-known and documented property +in Spring Boot `application.properties`: + +.Using properties +==== +[source,properties] +---- +spring.session.data.gemfire.session.region.name=MySessions +---- +==== + +Alternatively, you can set the name of the cache Region used to store and manage (HTTP) session state by explicitly +declaring the `@EnableGemFireHttpSession` annotation on your main `@SpringBootApplication` class: .Using `@EnableGemfireHttpSession +==== [source,java] ---- @SpringBootApplication @@ -209,75 +235,71 @@ class MySpringBootSpringSessionApplication { // ... } ---- +==== -Or alternatively, we recommend users to configure the cache Region name using the well-known and documented property -in Spring Boot `application.properties`: +Once you decide on the cache Region name used to store and manage (HTTP) sessions, you must create the cache Region +in the cluster somehow. -.Using properties -[source,properties] ----- -spring.session.data.gemfire.session.region.name=MySessions ----- - -Once you decide on the cache Region name used to store and manage (HTTP) Sessions, you must create the Region in the -cluster somehow. - -On the client, this is simple since SBDG's auto-configuration will automatically create the client `PROXY` Region -used to send/receive (HTTP) Session state between the client and server for you, when either Spring Session is on -the application classpath (e.g. `spring-geode-starter-session`), or you explicitly declare +On the client, doing so is simple, since SBDG's auto-configuration automatically creates the client `PROXY` Region +that is used to send and receive (HTTP) session state between the client and server for you when either Spring Session +is on the application classpath (for example, `spring-geode-starter-session`) or you explicitly declare the `@EnableGemFireHttpSession` annotation on your main `@SpringBootApplication` class. -However, on the server-side, you currently have a couple of options. +However, on the server side, you currently have a couple of options. -First, you can create the cache Region manually using _Gfsh_, like so: +First, you can manually create the cache Region by using Gfsh: .Create the Sessions Region using Gfsh +==== [source,txt] ---- gfsh> create region --name=MySessions --type=PARTITION --entry-idle-time-expiration=1800 --entry-idle-time-expiration-action=INVALIDATE ---- +==== You must create the cache Region with the appropriate name and an expiration policy. -In this case, we created an Idle Expiration Policy with a timeout of `1800 seconds` (`30 minutes`), after which, -the entry (i.e. Session object) will be "_invalidated_". +In this case, we created an idle expiration policy with a timeout of `1800` seconds (30 minutes), after which the entry +(session object) is `invalidated`. -NOTE: Session expiration is managed by the Expiration Policy set on the cache Region used to store Session state. -The Servlet Container's (HTTP) Session expiration configuration is not used since Spring Session is replacing -the Servlet Container's Session management capabilities with its own and Spring Session delegates this behavior -to the individual providers, like {geode-name}. +NOTE: Session expiration is managed by the Expiration Policy set on the cache Region that is used to store session state. +The Servlet container's (HTTP) session expiration configuration is not used, since Spring Session replaces the Servlet +container's session management capabilities with its own, and Spring Session delegates this behavior to the individual +providers, such as {geode-name}. Alternatively, you could send the definition for the cache Region from your Spring Boot `ClientCache` application -to the cluster using the SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/config/annotation/EnableClusterAware.html[`@EnableClusterAware`] annotation, -which is meta-annotated with SDG's `@EnableClusterConfiguration` annotation. - -TIP: See the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html[Javadoc] -on the `@EnableClusterConfiguration` annotation as well as the {spring-data-geode-docs-html}/#bootstrap-annotation-config-cluster[documentation] -for more details. +to the cluster by using the SBDG {spring-boot-data-geode-javadoc}/org/springframework/geode/config/annotation/EnableClusterAware.html[`@EnableClusterAware`] annotation, +which is meta-annotated with SDG's `@EnableClusterConfiguration` annotation: .Using `@EnableClusterAware` +==== [source,java] ---- @SpringBootApplication @EnableClusterAware -class MySpringBootSpringSessionApplication { +class MySpringBootSpringSessionApacheGeodeApplication { // ... } ---- +==== -However, it is not currently possible to send Expiration Policy configuration metadata to the cluster yet. Therefore, -you must manually alter the cache Region to set the Expiration Policy, like so: +TIP: See the {spring-data-geode-javadoc}/org/springframework/data/gemfire/config/annotation/EnableClusterConfiguration.html[Javadoc] +on the `@EnableClusterConfiguration` annotation and the {spring-data-geode-docs-html}/#bootstrap-annotation-config-cluster[documentation] +for more detail. + +However, you cannot currently send expiration policy configuration metadata to the cluster. Therefore, you must manually +alter the cache Region to set the expiration policy: .Using Gfsh to Alter Region +==== [source,txt] ---- gfsh> alter region --name=MySessions --entry-idle-time-expiration=1800 --entry-idle-time-expiration-action=INVALIDATE ---- +==== -That is it! - -Now your Spring Boot `ClientCache` application using Spring Session in a client/server topology is configured to store -and manage user (HTTP) Session state in the cluster. This works for either standalone, externally managed {geode-name} -clusters, or when using PCC running in a {vmw-tas-name} environment. +Now your Spring Boot `ClientCache` application that uses Spring Session in a client/server topology is configured to +store and manage user (HTTP) session state in the cluster. This works for either standalone, externally managed +{geode-name} clusters or when you use PCC running in a {vmw-tas-name} environment. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/templates.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/templates.adoc index 41650e20..5d584d3a 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/templates.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/templates.adoc @@ -5,190 +5,210 @@ There are several ways to access data stored in {geode-name}. -For instance, developers may choose to use the {apache-geode-javadoc}/org/apache/geode/cache/Region.html[Region API] -directly. If developers are driven by the application's domain context, they might choose to leverage the power of +For instance, you can use the {apache-geode-javadoc}/org/apache/geode/cache/Region.html[Region API] directly. If you +are driven by the application's domain context, you can use the power of {spring-data-commons-docs-html}/#repositories[Spring Data Repositories] instead. -While using the _Region_ API directly offers flexibility, it couples your application to {geode-name}, which is usually -undesirable and unnecessary. While using Spring Data _Repositories_ provides a very powerful and convenient abstraction, -you give up flexibility provided by a lower level API. +While the Region API offers flexibility, it couples your application to {geode-name}, which is usually undesirable +and unnecessary. While using Spring Data Repositories provides a very powerful and convenient abstraction, you give up +the flexibility provided by a lower-level Region API. -A good comprise is to use the _Template_ pattern. Indeed, this pattern is consistently and widely used throughout -the entire Spring portfolio. +A good compromise is to use the https://en.wikipedia.org/wiki/Template_method_pattern[Template software design pattern]. +This pattern is consistently and widely used throughout the entire Spring portfolio. -For example, there is the {spring-framework-javadoc}/org/springframework/jdbc/core/JdbcTemplate.html[JdbcTemplate] -and {spring-framework-javadoc}/org/springframework/jms/core/JmsTemplate.html[JmsTemplate], which are provided by -the core Spring Framework. +For example, the Spring Framework provides {spring-framework-javadoc}/org/springframework/jdbc/core/JdbcTemplate.html[`JdbcTemplate`] +and {spring-framework-javadoc}/org/springframework/jms/core/JmsTemplate.html[`JmsTemplate`]. Other Spring Data modules, such as Spring Data Redis, offer the -https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/core/RedisTemplate.html[RedisTemplate], -and Spring Data for {geode-name} (SDG) offers the -{spring-data-gemfire-javadoc}/org/springframework/data/gemfire/GemfireTemplate.html[GemfireTemplate]. +https://docs.spring.io/spring-data/redis/docs/current/api/org/springframework/data/redis/core/RedisTemplate.html[`RedisTemplate`], +and Spring Data for {geode-name} (SDG) itself offers the +{spring-data-gemfire-javadoc}/org/springframework/data/gemfire/GemfireTemplate.html[`GemfireTemplate`]. The `GemfireTemplate` provides a highly consistent and familiar API to perform data access operations on {geode-name} cache `Regions`. `GemfireTemplate` offers: -1. Simple, consistent and convenient data access API to perform CRUD and basic query operations on cache Regions. -2. Use of Spring Framework's consistent, data access {spring-framework-docs}/data-access.html#dao-exceptions[Exception Hierarchy]. -3. Automatic enlistment in the presence of local, cache transactions. -4. Protection from {apache-geode-javadoc}/org/apache/geode/cache/Region.html[Region API] breaking changes. +* A simple and convenient data access API to perform basic CRUD and simple query operations on cache Regions. +* Use of Spring Framework's consistent data access {spring-framework-docs}/data-access.html#dao-exceptions[Exception hierarchy]. +* Automatic enlistment in the presence of local cache transactions. +* Consistency and protection from {apache-geode-javadoc}/org/apache/geode/cache/Region.html[Region API] breaking changes. -Given these conveniences, Spring Boot for {geode-name} (SBDG) will auto-configure `GemfireTemplate` beans for each -Region present in the {geode-name} cache. +Given these advantages, Spring Boot for {geode-name} (SBDG) auto-configures `GemfireTemplate` beans for each Region +present in the {geode-name} cache. -Additionally, SBDG is careful not to create a `GemfireTemplate` if the user has already declared a `GemfireTemplate` -bean in the Spring `ApplicationContext` for a given Region. +Additionally, SBDG is careful not to create a `GemfireTemplate` if you have already declared a `GemfireTemplate` bean +in the Spring `ApplicationContext` for a given Region. [[geode-data-access-region-templates-explicit-declaration]] === Explicitly Declared Regions -Given an explicitly declared Region bean definition: +Consider an explicitly declared Region bean definition: +. Explicitly Declared Region Bean Definition +==== [source,java] ---- @Configuration -class GemFireConfiguration { +class GeodeConfiguration { - @Bean("Example") - ClientRegionFactoryBean exampleRegion (GemFireCache gemfireCache) { - // ... - } + @Bean("Example") + ClientRegionFactoryBean exampleRegion(GemFireCache gemfireCache) { + // ... + } } ---- +==== -SBDG will automatically create a `GemfireTemplate` bean for the "Example" Region using a bean name "exampleTemplate". -SBDG will name the `GemfireTemplate` bean after the Region by converting the first letter in the Region's name -to lowercase and appending the word "Template" to the bean name. +SBDG automatically creates a `GemfireTemplate` bean for the `Example` Region by using the bean name `exampleTemplate`. +SBDG names the `GemfireTemplate` bean after the Region by converting the first letter in the Region's name to lower case +and appending `Template` to the bean name. -In a managed Data Access Object (DAO), I can inject the Template, like so: +In a managed Data Access Object (DAO), you can inject the Template: +==== [source,java] ---- @Repository class ExampleDataAccessObject { - @Autowired - @Qualifier("exampleTemplate") - private GemfireTemplate exampleTemplate; + @Autowired + @Qualifier("exampleTemplate") + private GemfireTemplate exampleTemplate; } ---- +==== -It's advisable, especially if you have more than 1 Region, to use the `@Qualifier` annotation to qualify which -`GemfireTemplate` bean you are specifically referring as demonstrated above. +You should use the `@Qualifier` annotation to qualify which `GemfireTemplate` bean you are specifically referring, +especially if you have more than one Region bean definition. [[geode-data-access-region-templates-entity-defined]] === Entity-defined Regions -SBDG auto-configures `GemfireTemplate` beans for Entity-defined Regions. +SBDG auto-configures `GemfireTemplate` beans for entity-defined Regions. -Given the following entity class: +Consider the following entity class: +.Customer class +==== [source,java] ---- @Region("Customers") class Customer { - // ... + // ... } ---- +==== -And configuration: +Further consider the following configuration: +.Apache Geode Configuration +==== [source,java] ---- @Configuration @EnableEntityDefinedRegions(basePackageClasses = Customer.class) class GeodeConfiguration { - // ... + // ... } ---- +==== -SBDG auto-configures a `GemfireTemplate` bean for the "Customers" Region named "customersTemplate", which you can then +SBDG auto-configures a `GemfireTemplate` bean for the `Customers` Region named `customersTemplate`, which you can then inject into an application component: +.CustomerService application component +==== [source,java] ---- @Service class CustomerService { - @Bean - @Qualifier("customersTemplate") - private GemfireTemplate customersTemplate; + @Bean + @Qualifier("customersTemplate") + private GemfireTemplate customersTemplate; } ---- +==== Again, be careful to qualify the `GemfireTemplate` bean injection if you have multiple Regions, whether declared -explicitly or implicitly, such as when using the `@EnableEntityDefineRegions` annotation. +explicitly or implicitly, such as when you use the `@EnableEntityDefineRegions` annotation. [[geode-data-access-region-templates-caching-defined]] === Caching-defined Regions -SBDG auto-configures `GemfireTemplate` beans for Caching-defined Regions. +SBDG auto-configures `GemfireTemplate` beans for caching-defined Regions. -When you are using Spring Framework's {spring-framework-docs}/integration.html#cache[Cache Abstraction] backed by -{geode-name}, 1 of the requirements is to configure Regions for each of the caches specified in the -{spring-framework-docs}integration.html#cache-annotations[Caching Annotations] of your application service components. +When you use Spring Framework's {spring-framework-docs}/integration.html#cache[Cache Abstraction] backed by {geode-name}, +one requirement is to configure Regions for each of the caches specified in the +{spring-framework-docs}integration.html#cache-annotations[caching annotations] of your application service components. -Fortunately, SBDG makes enabling and configuring caching easy and <> out-of-the-box. +Fortunately, SBDG makes enabling and configuring caching easy and <>. -Given a cacheable application service component: +Consider the following cacheable application service component: +.Cacheable `CustomerService` class +==== [source,java] ---- @Service class CacheableCustomerService { - @Bean - @Qualifier("customersByNameTemplate") - private GemfireTemplate customersByNameTemplate; + @Bean + @Qualifier("customersByNameTemplate") + private GemfireTemplate customersByNameTemplate; - @Cacheable("CustomersByName") - public Customer findBy(String name) { - return toCustomer(customersByNameTemplate.query("name = " + name)); - } + @Cacheable("CustomersByName") + public Customer findBy(String name) { + return toCustomer(customersByNameTemplate.query("name = " + name)); + } } ---- +==== -And configuration: +Further consider the following configuration: +.Apache Geode Configuration +==== [source,java] ---- @Configuration @EnableCachingDefinedRegions -class GemFireConfiguration { +class GeodeConfiguration { - @Bean - public CustomerService customerService() { - return new CustomerService(); - } + @Bean + public CustomerService customerService() { + return new CustomerService(); + } } ---- +==== - -SBDG auto-configures a `GemfireTemplate` bean named "customersByNameTemplate" used to perform data access operations -on the "CustomersByName" (`@Cacheable`) Region, which you can inject into any managed application component, -as shown above. +SBDG auto-configures a `GemfireTemplate` bean named `customersByNameTemplate` to perform data access operations on +the `CustomersByName` (`@Cacheable`) Region. You can then inject the bean into any managed application component, +as shown in the preceding application service component example. Again, be careful to qualify the `GemfireTemplate` bean injection if you have multiple Regions, whether declared -explicitly or implicitly, such as when using the `@EnableCachingDefineRegions` annotation. +explicitly or implicitly, such as when you use the `@EnableCachingDefineRegions` annotation. -WARNING: There are certain cases where autowiring (i.e. injecting) `GemfireTemplate` beans auto-configured by SBDG -for Caching-defined Regions into your application components will not always work! This has to do with the Spring -Container bean creation process. In those case you may need to lazily lookup the `GemfireTemplate` as needed, using -`applicationContext.getBean("customersByNameTemplate", GemfireTemplate.class)`. This is certainly not ideal but works -when autowiring does not. +WARNING: Autowiring (that is, injecting) `GemfireTemplate` beans auto-configured by SBDG for caching-defined Regions +into your application components does not always work. This has to do with the Spring container bean creation process. +In those cases, you may need to lazily lookup the `GemfireTemplate` by using +`applicationContext.getBean("customersByNameTemplate", GemfireTemplate.class)`. This is not ideal, but it works when +autowiring does not. [[geode-data-access-region-templates-native-defined]] === Native-defined Regions -SBDG will even auto-configure `GemfireTemplate` beans for Regions defined using {geode-name} native configuration -metadata, such as `cache.xml`. +SBDG even auto-configures `GemfireTemplate` beans for Regions that have been defined with {geode-name} native +configuration metadata, such as `cache.xml`. -Given the following {geode-name} native `cache.xml`: +Consider the following {geode-name} native `cache.xml`: +.Client `cache.xml` +==== [source,xml] ---- @@ -201,91 +221,110 @@ Given the following {geode-name} native `cache.xml`: ---- +==== -And Spring configuration: +Further consider the following Spring configuration: +.Apache Geode Configuration +==== [source,java] ---- @Configuration @EnableGemFireProperties(cacheXmlFile = "cache.xml") -class GemFireConfiguration { - // ... +class GeodeConfiguration { + // ... } ---- +==== -SBDG will auto-configure a `GemfireTemplate` bean named "exampleTemplate" after the "Example" Region defined in -`cache.xml`. This Template can be injected like any other Spring managed bean: +SBDG auto-configures a `GemfireTemplate` bean named `exampleTemplate` after the `Example` Region defined in `cache.xml`. +You can inject this template as you would any other Spring-managed bean: +.Injecting the `GemfireTemplate` +==== [source,java] ---- @Service class ExampleService { - @Autowired - @Qualifier("exampleTemplate") - private GemfireTemplate exampleTemplate; + @Autowired + @Qualifier("exampleTemplate") + private GemfireTemplate exampleTemplate; } ---- +==== -The same rules as above apply when multiple Regions are present. +The rules described earlier apply when multiple Regions are present. [[geode-data-access-region-templates-rules]] === Template Creation Rules -Fortunately, SBDG is careful not to create a `GemfireTemplate` bean for a Region if a Template by the same name -already exists. For example, if you defined and declared the following configuration: +Fortunately, SBDG is careful not to create a `GemfireTemplate` bean for a Region if a template by the same name already +exists. -[source,java] ----- -@Configuration -@EnableEntityDefinedRegions(basePackageClasses = Customer.class) -class GemFireConfiguration { - - @Bean - public GemfireTemplate customersTemplate(GemFireCache cache) { - return new GemfireTemplate(cache.getRegion("/Customers")); - } -} ----- - -Using our same Customers class, as above: - -[source,java] ----- -@Region("Customers") -class Customer { - // ... -} ----- - -Because you explicitly defined the "customersTemplate" bean, SBDG will not create a Template for the "Customers" Region -automatically. This applies regardless of how the Region was created, whether using `@EnableEntityDefinedRegions`, -`@EnableCachingDefinedRegions`, declaring Regions explicitly or defining Regions natively. - -Even if you name the Template differently from the Region for which the Template was configured, SBDG will conserve -resources and not create the Template. - -For example, suppose you named the `GemfireTemplate` bean, "vipCustomersTemplate", even though the Region name -is "Customers", based on the `@Region` annotated `Customer` class, which specified Region "Customers". - -With the following configuration, SBDG is still careful not to create the Template: +For example, consider the following configuration: +.Apache Geode Configuration +==== [source,java] ---- @Configuration @EnableEntityDefinedRegions(basePackageClasses = Customer.class) class GeodeConfiguration { - @Bean - public GemfireTemplate vipCustomersTemplate(GemFireCache cache) { - return new GemfireTemplate(cache.getRegion("/Customers")); - } + @Bean + public GemfireTemplate customersTemplate(GemFireCache cache) { + return new GemfireTemplate(cache.getRegion("/Customers")); + } } ---- +==== -SBDG identifies that your "vipCustomersTemplate" is the Template used with the "Customers" Region and SBDG will not -create the "customersTemplate" bean, which would result in 2 `GemfireTemplate` beans for the same Region. +Further consider the following example: -NOTE: The name of your Spring bean defined in JavaConfig is the name of the method if the Spring bean is not explicitly -named using the `name` (or `value`) attribute of the `@Bean` annotation. +.Customer class +==== +[source,java] +---- +@Region("Customers") +class Customer { + // ... +} +---- +==== + +Because you explicitly defined and declared the `customersTemplate` bean, SBDG does not automatically create a template +for the `Customers` Region. This applies regardless of how the Region was created, whether by using +`@EnableEntityDefinedRegions`, `@EnableCachingDefinedRegions`, explicitly declaring Regions, +or natively defining Regions. + +Even if you name the template differently from the Region for which the template was configured, SBDG conserves +resources and does not create the template. + +For example, suppose you named the `GemfireTemplate` bean `vipCustomersTemplate`, even though the Region name +is `Customers`, based on the `@Region` annotated `Customer` class, which specified the `Customers` Region. + +With the following configuration, SBDG is still careful not to create the template: + +.Apache Geode Configuration +==== +[source,java] +---- +@Configuration +@EnableEntityDefinedRegions(basePackageClasses = Customer.class) +class GeodeConfiguration { + + @Bean + public GemfireTemplate vipCustomersTemplate(GemFireCache cache) { + return new GemfireTemplate(cache.getRegion("/Customers")); + } +} +---- +==== + +SBDG identifies that your `vipCustomersTemplate` is the template used with the `Customers` Region, and SBDG does not +create the `customersTemplate` bean, which would result in two `GemfireTemplate` beans for the same Region. + +NOTE: The name of your Spring bean defined in Java configuration is the name of the method if the Spring bean is not +explicitly named by using the `name` attribute or the `value` attribute of the `@Bean` annotation. diff --git a/spring-geode-docs/src/docs/asciidoc/_includes/testing.adoc b/spring-geode-docs/src/docs/asciidoc/_includes/testing.adoc index e3f9bd9a..13142622 100644 --- a/spring-geode-docs/src/docs/asciidoc/_includes/testing.adoc +++ b/spring-geode-docs/src/docs/asciidoc/_includes/testing.adoc @@ -4,18 +4,20 @@ :geode-name: {apache-geode-name} :stdg-website: https://github.com/spring-projects/spring-test-data-geode + Spring Boot for {geode-name} (SBDG), with help from {stdg-website}[Spring Test for {geode-name} (STDG)], offers -first-class support for both _Unit_ & _Integration Testing_ of {geode-name} in your Spring Boot applications. +first-class support for both unit and integration testing with {geode-name} in your Spring Boot applications. TIP: See the Spring Test for Apache Geode (STDG) {stdg-website}/#stdg-in-a-nutshell[documentation] for more details. [[geode-testing-unit]] === Unit Testing -_Unit Testing_ with {geode-name} using _mock objects_ in a Spring Boot Test is as simple as declaring the STDG +Unit testing with {geode-name} using mock objects in a Spring Boot Test requires only that you declare the STDG `@EnableGemFireMockObjects` annotation in your test configuration: .Unit Test with {geode-name} using Spring Boot +==== [source,java] ---- @SpringBootTest @@ -59,50 +61,52 @@ class User { interface UserRepository extends CrudRepository { } ---- +==== -While this test class is not a "pure" _Unit Test_, particularly since it bootstraps an actual Spring `ApplicationContext` -using Spring Boot, it does, however, "_mock_" all {geode-name} objects, such as the "_Users_" `Region` declared by the -`User` application entity class, which was annotated with SDG's `@Region` mapping annotation. +This test class is not a "`pure`" unit test, particularly since it bootstraps an actual Spring `ApplicationContext` +using Spring Boot. However, it does mock all {geode-name} objects, such as the `Users` `Region` declared by the `User` +application entity class, which was annotated with SDG's `@Region` mapping annotation. -This test class conveniently uses Spring Boot's _auto-configuration_ to auto-configure an {geode-name} `ClientCache` +This test class conveniently uses Spring Boot's auto-configuration to auto-configure an {geode-name} `ClientCache` instance. In addition, SDG's `@EnableEntityDefinedRegions` annotation was used to conveniently create the {geode-name} -"_Users_" `Region` to store instances of `User`. +"Users` `Region` to store instances of `User`. -Finally, Spring Data's _Repository_ abstraction was used to conveniently perform basic CRUD (e.g. `save`) and simple -(OQL) query (e.g. `findById`) data access operations on the "_Users_" `Region`. +Finally, Spring Data's Repository abstraction was used to conveniently perform basic CRUD (such as `save`) and simple +(OQL) query (such as `findById`) data access operations on the `Users` `Region`. -Even though the {geode-name} objects (e.g. "_Users_" `Region`) are "_mock objects_", you can still perform many of -the data access operations required by your Spring Boot application's business logic in a {geode-name} API agnostic way, -that is, using Spring's powerful programming model and constructs! +Even though the {geode-name} objects (such as the `Users` `Region`) are "`mock objects`", you can still perform many of +the data access operations required by your Spring Boot application's components in an {geode-name} API-agnostic way +-- that is, by using Spring's powerful programming model and constructs. -TIP: By extending STDG's `org.springframework.data.gemfire.tests.integration.IntegrationTestSupport` class, -you ensure that all {geode-name} mock objects and resources are properly released after the test class runs, -thereby preventing any interference with downstream tests. +TIP: By extending STDG's `org.springframework.data.gemfire.tests.integration.IntegrationTestSupport` class, you ensure +that all {geode-name} mock objects and resources are properly released after the test class runs, thereby preventing +any interference with downstream tests. While STDG tries to {stdg-website}/#mock-regions-with-data[mock the functionality and behavior] for many `Region` -operations, it is simply not pragmatic to mock them all. For example, it would not be practical to mock `Region` -query operations involving complex OQL statements having sophisticated predicates. +operations, it is not pragmatic to mock them all. For example, it would not be practical to mock `Region` query +operations involving complex OQL statements that have sophisticated predicates. -If such functional testing is required, then the test might be better suited as an _Integration Test_. Alternatively, -you can follow the advice in this {stdg-website}/#mocking-unsupported-region-operations[section]. +If such functional testing is required, the test might be better suited as an integration test. Alternatively, you can +follow the advice in this section about {stdg-website}/#mocking-unsupported-region-operations[unsupported Region operations]. -In general, STDG provides the following capabilities when mocking {geode-name} objects out-of-the-box: +In general, STDG provides the following capabilities when mocking {geode-name} objects: * {stdg-website}#mock-object-scope--lifecycle-management[Mock Object Scope & Lifecycle Management] * {stdg-website}#mock-regions-with-data[Support for Mock Regions with Data] * {stdg-website}#mock-region-callbacks[Support for Mocking Region Callbacks] * {stdg-website}#mocking-unsupported-region-operations[Support for Mocking Unsupported Region Operations] -TIP: See documentation on {stdg-website}/#unit-testing-with-stdg[Unit Testing with STDG] for more details. +TIP: See the documentation on {stdg-website}/#unit-testing-with-stdg[Unit Testing with STDG] for more details. [[geode-testing-integration]] === Integration Testing -_Integration Testing_ with {geode-name} in a Spring Boot Test is as simple as **not** declaring STDG's -`@EnableGemFireMockObjects` annotation in your test configuration. Of course, you may then want to additionally use -SBDG's `@EnableClusterAware` annotation to conditionally detect the presence of a {geode-name} cluster: +Integration testing with {geode-name} in a Spring Boot Test is as simple as *not* declaring STDG's +`@EnableGemFireMockObjects` annotation in your test configuration. You may then want to use SBDG's `@EnableClusterAware` +annotation to conditionally detect the presence of a {geode-name} cluster: .Using `@EnableClusterAware` in test configuration +==== [source,java] ---- @SpringBootApplication @@ -110,19 +114,21 @@ SBDG's `@EnableClusterAware` annotation to conditionally detect the presence of @EnableEntityDefinedRegions(basePackageClasses = User.class) static class TestConfiguration { } ---- +==== -The SBDG `@EnableClusterAware` annotation will conveniently toggle your auto-configured `ClientCache` instance -between local-only mode and client/server. Additionally, it will even push configuration metadata -(e.g. `Region` definitions) up to the server(s) in the cluster required by the application to persist data. +The SBDG `@EnableClusterAware` annotation conveniently toggles your auto-configured `ClientCache` instance between +local-only mode and client/server. It even pushes configuration metadata (such as `Region` definitions) up to +the servers in the cluster that are required by the application to store data. -In most cases, in addition to testing with "_live_" {geode-name} objects (e.g. _Regions_), we also want to test -in a client/server capacity. This unlocks the full capabilities of the {geode-name} data management system -in a Spring context, and gets you as close as possible to production from the comfort of your IDE. +In most cases, in addition to testing with "`live`" {geode-name} objects (such as Regions), we also want to test in +a client/server capacity. This unlocks the full capabilities of the {geode-name} data management system in a Spring +context and gets you as close as possible to production from the comfort of your IDE. -Building on our example from the section on <>, you can modify the test to use "_live_" -{geode-name} objects in a client/server topology as follows: +Building on our example from the section on <>, you can modify the test to use "`live`" {geode-name} +objects in a client/server topology as follows: .Integration Test with {geode-name} using Spring Boot +==== [source,java] ---- @ActiveProfiles("client") @@ -187,13 +193,15 @@ class User { interface UserRepository extends CrudRepository { } ---- +==== -The application client/server-based _Integration Test_ class extend STDG's +The application client/server-based integration test class extend STDG's `org.springframework.data.gemfire.tests.integration.ForkingClientServerIntegrationTestsSupport` class. This ensures that all {geode-name} objects and resources are properly cleaned up after the test class runs. In addition, -it coordinates the client & server components of the test (e.g. connecting the client to the server using a random port). +it coordinates the client and server components of the test (for example connecting the client to the server using a +random port). -The server is started in a `@BeforeClass` setup method: +The {geode-name} server is started in a `@BeforeClass` setup method: .Start the {geode-name} server [source,java] @@ -207,11 +215,12 @@ class SpringBootApacheGeodeIntegrationTest extends ForkingClientServerIntegratio } ---- -STDG allows you to configure the server with Spring config, specified in the `TestGeodeServerConfiguration` class. -The Java class needs to provide a `main` method. It uses the `SpringApplicationBuilder` to bootstrap the {geode-name} -`CacheServer` application. +STDG lets you configure the {geode-name} server with Spring configuration, specified in +the `TestGeodeServerConfiguration` class. The Java class needs to provide a `main` method. It uses +the `SpringApplicationBuilder` to bootstrap the {geode-name} `CacheServer` application: .{geode-name} server configuration +==== [source,java] ---- @CacheServerApplication @@ -228,24 +237,25 @@ static class TestGeodeServerConfiguration { } } ---- +==== -In this case, we provide very minimal configuration since the configuration is determined and pushed up to the server -by the client. For example, we do not need to explicitly create the "_Users_" `Region` on the server-side since it is +In this case, we provide minimal configuration, since the configuration is determined and pushed up to the server +by the client. For example, we do not need to explicitly create the `Users` `Region` on the server since it is implicitly handled for you by the SBDG/STDG frameworks from the client. -We take advantage of Spring _Profiles_ in the test setup to distinguish between the client & server configuration. Keep -in mind that the test is the "client" in this arrangement. +We take advantage of Spring profiles in the test setup to distinguish between the client and server configuration. +Keep in mind that the test is the "`client`" in this arrangement. -The STDG framework is doing as the supporting class states, "forking" the Spring Boot-based, {geode-name} `CacheServer` -application in a separate JVM process. Subsequently, the STDG framework will stop the server upon completion of -the tests in the test class. +The STDG framework does what the supporting class demands: "`forking`" the Spring Boot-based, {geode-name} `CacheServer` +application in a separate JVM process. Subsequently, the STDG framework stops the server upon completion of the tests +in the test class. -Of course, you are free to start your server(s) or cluster however you choose. STDG simply and conveniently provides -this capability for you since it is a common concern. +You are free to start your servers or cluster however you choose. STDG provides this capability as a convenience for you, +since it is a common concern. -This test class is very simple and much more complex test scenarios can be easily handled by STDG. +This test class is simple. STDG can handle much more complex test scenarios. TIP: Review SBDG's test suite to witness the full power and functionality of the STDG framework for yourself. -NOTE: See documentation on {stdg-website}/#integration-testing-with-stdg[Integration Testing with STDG] +NOTE: See the documentation on {stdg-website}/#integration-testing-with-stdg[Integration Testing with STDG] for more details.