[[bootstrap:cache]]
= Configuring a Cache

To use Apache Geode, a developer needs to either create a new `Cache` or connect to an existing one.
With the current version of Geode, there can be only one open Cache per VM (technically, per `ClassLoader`).
In most cases, the `Cache` should only be created once.

NOTE: This section describes the creation and configuration of a peer cache member, appropriate in
peer-to-peer (P2P) topologies and cache servers. A cache member can also be used in standalone applications
and integration tests. However, in most typical production systems, most application processes will act as
cache clients, creating a `ClientCache` instance instead. This is described in the sections <<bootstrap:cache:client>>
and <<bootstrap:region:client>>.

A peer cache with default configuration can be created with a very simple declaration:

[source,xml]
----
<gfe:cache/>
----

During Spring container initialization, any application context containing this cache definition will register
a `CacheFactoryBean` that creates a Spring bean named `gemfireCache` referencing a Geode `Cache` instance.
This bean will refer to either an existing cache, or if one does not already exist, a newly created one.  Since no
additional properties were specified, a newly created cache will apply the default cache configuration.

All _Spring Data Geode_ components that depend on the cache respect this naming convention, so there is no need
to explicitly declare the cache dependency.  If you prefer, you can make the dependency explicit via the `cache-ref`
attribute provided by various SDG XML namespace elements.  Also, you can easily override the cache's bean name using
the `id` attribute:

[source,xml]
----
<gfe:cache id="myCache"/>
----

A Geode `Cache` can be fully configured using Spring, however, Geode's native XML configuration file, `cache.xml`,
is also supported.  For situations where the Geode cache needs to be configured natively, simply provide a reference
to the Geode XML configuration file using the `cache-xml-location` attribute:

[source,xml]
----
<gfe:cache id="cacheConfiguredWithNativeXml" cache-xml-location="classpath:cache.xml"/>
----

In this example, if a cache needs to be created, it will use a file named `cache.xml` located in the classpath root
to configure it.

NOTE: The configuration makes use of Spring's http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#resources[`Resource`]
abstraction to locate the file.  This allows various search patterns to be used, depending on the runtime environment
or the prefix specified (if any) in the resource location.

In addition to referencing an external XML configuration file, a developer may also specify Geode System
http://geode.apache.org/docs/guide/11/reference/topics/gemfire_properties.html[properties]
using any of Spring's `Properties` support features.

For example, the developer may use the `properties` element defined in the `util` namespace to define `Properties`
directly or load properties from a properties file:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:gfe="http://www.springframework.org/schema/geode"
  xmlns:util="http://www.springframework.org/schema/util"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/geode http://www.springframework.org/schema/gemfire/spring-geode.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

  <util:properties id="gemfireProperties" location="file:/path/to/gemfire.properties"/>

  <gfe:cache properties-ref="gemfireProperties"/>

</beans>
----

Using a properties file is recommended for externalizing environment specific settings outside
the application configuration.

NOTE: Cache settings apply only if a new cache needs to be created.  If an open cache already exists in the VM,
these settings are ignored.

[[bootstrap:cache:advanced]]
== Advanced Cache Configuration

For advanced cache configuration, the `cache` element provides a number of configuration options exposed as attributes
or child elements:

[source,xml]
----
<!--1-->
<gfe:cache
    cache-xml-location=".."
    properties-ref=".."
    close="false"
    copy-on-read="true"
    critical-heap-percentage="90"
    eviction-heap-percentage="70"
    enable-auto-reconnect="false" <!--2-->
    lock-lease="120"
    lock-timeout="60"
    message-sync-interval="1"
    pdx-serializer-ref="myPdxSerializer"
    pdx-persistent="true"
    pdx-disk-store="diskStore"
    pdx-read-serialized="false"
    pdx-ignore-unread-fields="true"
    search-timeout="300"
    use-bean-factory-locator="true" <!--3-->
    use-cluster-configuration="false" <!--4-->
>

  <gfe:transaction-listener ref="myTransactionListener"/> <!--5-->

  <gfe:transaction-writer> <!--6-->
    <bean class="org.example.app.geode.transaction.TransactionWriter"/>
  </gfe:transaction-writer>

  <gfe:gateway-conflict-resolver ref="myGatewayConflictResolver"/> <!--7-->

  <gfe:dynamic-region-factory/> <!--8-->

  <gfe:jndi-binding jndi-name="myDataSource" type="ManagedDataSource"/> <!--9-->

</gfe:cache>
----

<1> Various cache options are supported by attributes. For further information regarding anything shown in this example,
please consult the Geode http://geode.apache.org/docs/[product documentation].
The `close` attribute determines whether the cache should be closed when the Spring application context is closed.
The default is `true`, however, for use cases in which multiple application contexts use the cache
(common in web applications), set this value to `false`.
<2> Setting the `enable-auto-reconnect` attribute to true (default is false), allows a disconnected Geode member to
automatically reconnect and rejoin the Geode cluster.
See the Geode http://geode.apache.org/docs/guide/11/managing/autoreconnect/member-reconnect.html[product documentation]
for more details.
<3> Setting the `use-bean-factory-locator` attribute to `true` (defaults to `false`) is only applicable when both
Spring (XML) configuration meta-data and Geode `cache.xml` is used to configure the Geode cache node
(whether client or peer).  This option allows Geode components (e.g. `CacheLoader`) expressed in `cache.xml`
to be auto-wired with beans (e.g. `DataSource`) defined in the Spring application context.  This option is typically
used in conjunction with `cache-xml-location`.
<4> Setting the `use-cluster-configuration` attribute to `true` (default is `false`) enables a Geode member to
retrieve the common, shared Cluster-based configuration from a Locator.
See the Geode http://geode.apache.org/docs/guide/11/configuring/cluster_config/gfsh_persist.html[product documentation]
for more details.
<5> Example of a `TransactionListener` callback declaration using a bean reference. The referenced bean must implement
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/TransactionListener.html[TransactionListener].
A `TransactionListener` can be implemented to handle transaction related events (e.g. afterCommit, afterRollback).
<6> Example of a `TransactionWriter` callback declaration using an inner bean declaration. The bean must implement
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/TransactionWriter.html[TransactionWriter].
The `TransactionWriter` is a callback that is allowed to veto a transaction.
<7> Example of a `GatewayConflictResolver` callback declaration using a bean reference. The referenced bean
must implement http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/util/GatewayConflictResolver.html
[GatewayConflictResolver].
A `GatewayConflictResolver` is a Cache-level plugin that is called upon to decide what to do with events that originate
in other systems and arrive through the WAN Gateway.
<8> Enable Geode's http://geode.apache.org/docs/guide/11/developing/region_options/dynamic_region_creation.html[DynamicRegionFactory],
which provides a distributed Region creation service.
<9> Declares a JNDI binding to enlist an external DataSource in a Geode transaction.

[[bootstrap:cache:pdx-serialization]]
=== Enabling PDX Serialization

The example above includes a number of attributes related to Geode's enhanced serialization framework, PDX.
While a complete discussion of PDX is beyond the scope of this reference guide, it is important to note that PDX
is enabled by registering a `PdxSerializer` which is specified via the `pdx-serializer` attribute. Geode provides
an implementing class `org.apache.geode.pdx.ReflectionBasedAutoSerializer` that uses Java Reflection, however, it is
common for developers to provide their own implementation. The value of the attribute is simply a reference to
a Spring bean that implements the `PdxSerializer` interface.

More information on serialization support can be found in <<serialization>>

[[boostrap:cache:auto-reconnect]]
=== Enabling auto-reconnect

Setting the `<gfe:cache enable-auto-reconnect="[true|false*]>` attribute to `true` should be done with care.

Generally, 'auto-reconnect' should only be enabled in cases where _Spring Data Geode's_ XML namespace is used to
configure and bootstrap a new, non-application Geode Server to add to a cluster.  In other words, 'auto-reconnect'
should not be enabled when _Spring Data Geode_ is used to develop and build an Geode application that also happens
to be a peer cache member of the Geode cluster.

The main reason for this is that most Geode applications use references to the Geode cache or Regions in order to
perform data access operations.  These references are "injected" by the Spring container into application components
(e.g. DAOs or Repositories) for use by the application.  When a peer member is forcefully disconnected from the rest
of the cluster, presumably because the peer member has become unresponsive or a network partition separates one or more
peer members into a group too small to function as an independent distributed system, the peer member will shutdown
and all Geode component references (e.g. Cache, Regions, etc) become invalid.

Essentially, the current forced-disconnect processing logic in each peer member dismantles the system from the ground up.
The JGroups stack shuts down, the Distributed System is put in a shutdown state and finally, the Cache is closed.
Effectively, all memory references become stale and are lost.

After being disconnected from the Distributed System a peer member enters a "reconnecting" state and periodically
attempts to rejoin the Distributed System.  If the peer member succeeds in reconnecting, the member rebuilds
its "view" of the Distributed System from existing members and receives a new Distributed System ID.  Additionally, all
Cache, Regions and other Geode components are reconstructed.  Therefore, all old references, which may have been
injected into application by the Spring container are now stale and no longer valid.

Geode makes no guarantee, even when using the Geode public Java API, that application Cache, Region or other
component references will be automatically refreshed by the reconnect operation. As such, Geode applications
must take care to refresh their own references.

Unfortunately, there is no way to be notified of a disconnect event, and subsequently, a reconnect event.
If that were the case, the application developer would have a clean way to know when to call
`ConfigurableApplicationContext.refresh()`, if even applicable for an application to do so, which is why
this "feature" of Apache Geode is not recommended for peer cache Geode applications.

For more information about 'auto-reconnect', see Geode's
http://geode.apache.org/docs/guide/11/managing/autoreconnect/member-reconnect.html[product documentation].

[[bootstrap:cache:cluster-configuration]]
=== Using Cluster-based Configuration

Apache Geode's Cluster Configuration Service is a convenient way for any peer member joining the cluster to get
a "consistent view" of the cluster by using the shared, persistent configuration maintained by a Locator.
Using the Cluster-based Configuration ensures the peer member's configuration will be compatible with
the Geode Distributed System when the member joins.

This feature of _Spring Data Geode_ (setting the `use-cluster-configuration` attribute to `true`) works in the same way
as the `cache-xml-location` attribute, except the source of the Geode configuration meta-data comes from the network
via a Locator as opposed to a native `cache.xml` file residing in the local file system.

All Geode native configuration meta-data, whether from `cache.xml` or from the Cluster Configuration Service,
gets applied before any _Spring_ (XML) configuration meta-data.  As such, _Spring's_ config serves to "augment" the
native Geode configuration meta-data and would most likely be specific to the application.

Again, to enable this feature, just specify the following in the _Spring_ XML config:

[source,xml]
----
  <gfe:cache use-cluster-configuration="true"/>
----

NOTE: While certain Geode tools, like _Gfsh_, have their actions "recorded" when schema-like changes are made
(e.g. `gfsh>create region --name=Example --type=PARTITION`), _Spring Data Geode's_ configuration meta-data
is not recorded.  The same is true when using Geode's public Java API directly; it too is not recorded.

For more information on Geode's Cluster Configuration Service, see the
http://geode.apache.org/docs/guide/11/configuring/cluster_config/gfsh_persist.html[product documentation].

[[bootstrap:cache:server]]
== Configuring a Geode CacheServer

_Spring Data Geode_ includes dedicated support for configuring a
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/server/CacheServer.html[CacheServer],
allowing complete configuration through the Spring container:

[source,xml]
----
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:context="http://www.springframework.org/schema/context"
  xmlns:gfe="http://www.springframework.org/schema/geode"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
    http://www.springframework.org/schema/geode http://www.springframework.org/schema/geode/spring-geode.xsd
">

  <gfe:cache/>

  <!-- Example depicting serveral Geode CacheServer configuration options -->
  <gfe:cache-server id="advanced-config" auto-startup="true"
       bind-address="localhost" host-name-for-clients="localhost" port="${geode.cache.server.port}"
       load-poll-interval="2000" max-connections="22" max-message-count="1000" max-threads="16"
       max-time-between-pings="30000" groups="test-server">

    <gfe:subscription-config eviction-type="ENTRY" capacity="1000" disk-store="file://${java.io.tmpdir}"/>

  </gfe:cache-server>

  <context:property-placeholder location="classpath:cache-server.properties"/>

</beans>
----

The configuration above illustrates the `cache-server` element and the many options available.

NOTE: Rather than hard-coding the port, this configuration uses _Spring's_
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#xsd-config-body-schemas-context[context]
namespace to declare a `property-placeholder`.
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-factory-placeholderconfigurer[property placeholder]
reads one or more properties files and then replaces property placeholders with values at runtime. This allows administrators
to change values without having to touch the main application configuration.  _Spring_ also provides the
http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#expressions[SpEL]
and the http://docs.spring.io/spring/docs/current/spring-framework-reference/htmlsingle/#beans-environment[environment abstraction]
to support externalization of environment-specific properties from the main codebase, easing deployment
across multiple machines.

NOTE: To avoid initialization problems, the `CacheServer` started by _Spring Data Geode_ will start *after*
the _Spring_ container has been fully initialized.  This allows potential Regions, Listeners, Writers or Instantiators
defined declaratively to be fully initialized and registered before the server starts accepting connections.
Keep this in mind when programmatically configuring these elements as the server might start after your components
and thus not be seen by the clients connecting right away.

[[bootstrap:cache:client]]
== Configuring a Geode ClientCache

In addition to defining a Geode peer http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/Cache.html[Cache],
_Spring Data Geode_ also supports the definition of a Geode http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/client/ClientCache.html[ClientCache]
in a _Spring_ context.  A `ClientCache` definition is very similar in configuration and use to
the Geode peer <<bootstrap:cache,Cache>> and is supported by the `org.springframework.data.gemfire.client.ClientCacheFactoryBean`.

The simplest definition of a Geode cache client using default configuration can be accomplished with the following
declaration:

[source,xml]
----
<beans>
  <gfe:client-cache/>
</beans>
----

`client-cache` supports many of the same options as the <<bootstrap:cache:advanced,cache>> element.  However, as opposed
to a *full-fledged* peer cache member, a cache client connects to a remote cache server through a Pool.  By default,
a Pool is created to connect to a server running on `localhost`, listening to port `40404`. The default Pool is used
by all client Regions unless the Region is configured to use a specific Pool.

Pools can be defined with the `pool` element.  This client-side Pool can be used to configure connectivity directly to
a server for individual entities or the entire cache through one or more Locators.

For example, to customize the default Pool used by the `client-cache`, the developer needs to define a Pool and wire it
to the cache definition:

[source,xml]
----
<beans>
  <gfe:client-cache id="my-cache" pool-name="myPool"/>

  <gfe:pool id="myPool" subscription-enabled="true">
    <gfe:locator host="${geode.locator.host}" port="${geode.locator.port}"/>
  </gfe:pool>
</beans>
----

The `<client-cache>` element also has a `ready-for-events` attribute.  If set to `true`, the client cache
initialization will include a call to http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/client/ClientCache.html#readyForEvents--[ClientCache.readyForEvents()].

Client-side configuration is covered in more detail in <<bootstrap:region:client>>.

[[bootstrap:cache:client:pool]]
=== Geode's DEFAULT Pool and Spring Data Geode Pool Definitions

If a Geode `ClientCache` is local-only, then no Pool definition is required.  For instance, a developer may define:

[source,xml]
----
<gfe:client-cache/>

<gfe:client-region id="Example" shortcut="LOCAL"/>
----

In this case, the "Example" Region is `LOCAL` and no data is distributed between the client and a server, therefore,
no Pool is necessary.  This is true for any client-side, local-only Region, as defined by the Geode's
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/client/ClientRegionShortcut.html[ClientRegionShortcut]
(all `LOCAL_*` shortcuts).

However, if a client Region is a (caching) proxy to a server-side Region, then a Pool is required.  There are several
ways to define and use a Pool in this case.

When a client cache, Pool and proxy-based Region are all defined, but not explicitly identified, _Spring Data Geode_
will resolve the references automatically for you.

For example:

[source,xml]
----
<gfe:client-cache/>

<gfe:pool>
  <gfe:locator host="${geode.locator.host}" port="${geode.locator.port}"/>
</gfe:pool>

<gfe:client-region id="Example" shortcut="PROXY"/>
----

In the example above, the client cache is identified as `gemfireCache`, the Pool as `gemfirePool` and the client Region
as "Example".  However, the client cache will initialize Geode's DEFAULT Pool from `gemfirePool` and the client Region
will use the `gemfirePool` when distributing data between the client and the server.

Basically, _Spring Data Geode_ resolves the above configuration to the following:

[source,xml]
----
<gfe:client-cache id="gemfireCache" pool-name="gemfirePool"/>

<gfe:pool id="gemfirePool">
  <gfe:locator host="${geode.locator.host}" port="${geode.locator.port}"/>
</gfe:pool>

<gfe:client-region id="Example" cache-ref="gemfireCache" pool-name="gemfirePool" shortcut="PROXY"/>
----

Geode still creates a Pool called "DEFAULT".  _Spring Data Geode_ will just cause the "DEFAULT" Pool to be
initialized from the `gemfirePool`.  This is useful in situations where multiple Pools are defined and client Regions
are using separate Pools.

Consider the following:

[source,xml]
----
<gfe:client-cache pool-name="locatorPool"/>

<gfe:pool id="locatorPool">
  <gfe:locator host="${geode.locator.host}" port="${geode.locator.port}"/>
</gfe:pool>

<gfe:pool id="serverPool">
  <gfe:server host="${geode.server.host}" port="${geode.server.port}"/>
</gfe:pool>

<gfe:client-region id="Example" pool-name="serverPool" shortcut="PROXY"/>

<gfe:client-region id="AnotherExample" shortcut="CACHING_PROXY"/>

<gfe:client-region id="YetAnotherExample" shortcut="LOCAL"/>
----

In this setup, the Geode client cache's "DEFAULT" Pool is initialized from "locatorPool" as specified with the
`pool-name` attribute.  There is no _Spring Data Geode_-defined `gemfirePool` since both Pools were explicitly
identified (named) "locatorPool" and "serverPool", respectively.

The "Example" Region explicitly refers to and uses the "serverPool" exclusively.  The "AnotherExample" Region uses
Geode's "DEFAULT" Pool, which was configured from the "locatorPool" based on the client cache bean definition's
`pool-name` attribute.

Finally, the "YetAnotherExample" Region will not use a Pool since it is `LOCAL`.

NOTE: The "AnotherExample" Region would first look for a Pool bean named `gemfirePool`, but that would require
the definition of an anonymous Pool bean (i.e. `<gfe:pool/>`) or a Pool bean explicitly named `gemfirePool`
(e.g. `<gfe:pool id="gemfirePool"/>`).

NOTE: We could have either named "locatorPool", "gemfirePool", or made the Pool bean definition anonymous
and it would have the same effect as the above configuration.
