SGF-305: Move to Asciidoctor for reference documentation

First cut at migrating reference docs to asciidoctor.
This commit is contained in:
Greg Turnquist
2014-08-11 23:07:50 -05:00
committed by Oliver Gierke
parent eb9ebec574
commit d11bf5ce0e
48 changed files with 2538 additions and 3896 deletions

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<appendix xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="appendix-schema" xmlns:xi="http://www.w3.org/2001/XInclude">
<title>Spring Data GemFire Schema</title>
<para>Spring Data GemFire Core Schema (gfe)</para>
<programlisting language="xml"><xi:include href="../../../src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.3.xsd" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:fallback>
<para><emphasis>FIXME: SGF SCHEMA LOCATION/NAME CHANGED</emphasis></para>
</xi:fallback>
</xi:include>
</programlisting>
<para>Spring Data GemFire Data Access Schema (gfe-data)</para>
<programlisting language="xml"><xi:include href="../../../src/main/resources/org/springframework/data/gemfire/config/spring-data-gemfire-1.3.xsd" parse="text" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:fallback>
<para><emphasis>FIXME: SGF SCHEMA LOCATION/NAME CHANGED</emphasis></para>
</xi:fallback>
</xi:include>
</programlisting>
</appendix>

View File

@@ -1,90 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<book xmlns="http://docbook.org/ns/docbook" version="5.0"
xml:id="spring-gemfire-reference"
xmlns:xi="http://www.w3.org/2001/XInclude">
<bookinfo>
<title>Spring Data GemFire Reference Guide</title>
<releaseinfo>${version}</releaseinfo>
<titleabbrev>Spring Data GemFire ${version}</titleabbrev>
<productname>Spring Data GemFire</productname>
<authorgroup>
<author>
<firstname>Costin</firstname>
<surname>Leau</surname>
<affiliation>SpringSource, a division of Pivotal</affiliation>
</author>
<author>
<firstname>David</firstname>
<surname>Turanski</surname>
<affiliation>SpringSource, a division of Pivotal</affiliation>
</author>
<author>
<firstname>John</firstname>
<surname>Blum</surname>
<affiliation>SpringSource, a division of Pivotal</affiliation>
</author>
<author>
<firstname>Oliver</firstname>
<surname>Gierke</surname>
<affiliation>SpringSource, a division of Pivotal</affiliation>
</author>
</authorgroup>
<legalnotice>
<para>Copies of this document may be made for your own use and for
distribution to others, provided that you do not charge any fee for such
copies and further provided that each copy contains this Copyright
Notice, whether distributed in print or electronically.</para>
</legalnotice>
<releaseinfo>
<note>
As of the 1.2.0 release, this project, formerly known as Spring GemFire, has been renamed to Spring Data GemFire to reflect that
it is now a component of the <ulink url="http://www.springsource.org/spring-data">Spring Data</ulink> project.
</note>
</releaseinfo>
</bookinfo>
<toc />
<xi:include href="preface.xml"/>
<part id="introduction">
<title>Introduction</title>
<xi:include href="introduction/introduction.xml"/>
<xi:include href="introduction/requirements.xml"/>
<xi:include href="introduction/new-features.xml"/>
</part>
<part id="reference">
<title>Reference Guide</title>
<xi:include href="reference/introduction.xml"/>
<xi:include href="reference/bootstrap.xml"/>
<xi:include href="reference/data.xml"/>
<xi:include href="reference/serialization.xml"/>
<xi:include href="reference/mapping.xml"/>
<xi:include href="reference/repositories.xml"/>
<xi:include href="reference/function-annotations.xml"/>
<xi:include href="reference/gemfire-bootstrap.xml"/>
<xi:include href="reference/samples.xml"/>
</part>
<part id="resources">
<title>Other Resources</title>
<partintro>
<para>
In addition to this reference documentation, there are a number of
other resources that may help you learn how to use GemFire and Spring framework.
These additional, third-party resources are enumerated in this section.
</para>
</partintro>
<xi:include href="links.xml"/>
</part>
<part id="appendices">
<title>Appendices</title>
<xi:include href="appendix/appendix-schema.xml"/>
</part>
</book>

View File

@@ -1,16 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="intro-introduction" xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>Introduction</title>
<para>
This reference guide for Spring Data GemFire explains how to use the Spring Framework to configure
and develop applications with Pivotal GemFire. It presents the basic concepts, semantics and provides
numerous examples to help you get started.
</para>
<note>
Spring Data GemFire started as a top-level Spring project called Spring GemFire (SGF) and since then
has been moved under the Spring Data umbrella project and renamed accordingly.
</note>
</chapter>

View File

@@ -1,258 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="new-features" version="5.0" xmlns="http://docbook.org/ns/docbook">
<title>New Features</title>
<note>
As of the 1.2.0 release, this project, formerly known as Spring GemFire, has been renamed to Spring Data GemFire
to reflect that it is now a component of the
<ulink url="http://www.springsource.org/spring-data">Spring Data</ulink> project.
</note>
<section id="new-in-1-2-0">
<title>New in the 1.2.0 Release</title>
<itemizedlist>
<listitem>
<para>
Full support for GemFire configuration via the SDG <emphasis>gfe</emphasis> namespace. Now GemFire
components may be configured completely without requiring a native <emphasis>cache.xml</emphasis>
file.
</para>
</listitem>
<listitem>
<para>WAN Gateway support for GemFire 6.6.x. See <xref linkend="bootstrap:gateway"/>.</para>
</listitem>
<listitem>
<para>
Spring Data Repository support using a dedicated SDG namespace, <emphasis>gfe-data</emphasis>.
See <xref linkend="gemfire-repositories"/>
</para>
</listitem>
<listitem>
<para>Namespace support for registering GemFire Functions. See <xref linkend="bootstrap:function"/></para>
</listitem>
<listitem>
<para>
A top-level <literal>&lt;disk-store&gt;</literal> element has been added to the SDG
<emphasis>gfe</emphasis> namespace to allow sharing of persist stores among Regions,
and other components that support persistent backup or overflow.
See <xref linkend="bootstrap-diskstore"/>
<caution>
The <literal>&lt;*-region&gt;</literal> elements no longer allow a nested
<literal>&lt;disk-store&gt;</literal>
</caution>
</para>
</listitem>
<listitem>
<para>GemFire Sub-Regions are supported via nested <literal>&lt;*-region&gt;</literal> elements.</para>
</listitem>
<listitem>
<para>A <literal>&lt;local-region&gt;</literal> element has been added to configure a Local Region.</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-1-2-1">
<title>New in the 1.2.1 Release</title>
<itemizedlist>
<listitem>
<para>Support for the re-designed WAN Gateway in GemFire 7.0.</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-1-3-0">
<title>New in the 1.3.0 Release</title>
<itemizedlist>
<listitem>
<para>
Annotation support for GemFire Functions. It is now possible to declare and register Functions
written as POJOs using annotations. In addition, Function executions are defined as
annotated interfaces, similar to the way Spring Data Repositories work.
See <xref linkend="function-annotations"/>.
</para>
</listitem>
<listitem>
<para>
Added a <tag>&lt;datasource&gt;</tag> element to the SDG <emphasis>gfe-data</emphasis> namespace to
simplify establishing a basic <link linkend="data-access:datasource">client connection</link>
to a GemFire data grid.
</para>
</listitem>
<listitem>
<para>
Added a <tag>&lt;json-region-autoproxy&gt;</tag> element to the SDG <emphasis>gfe-data</emphasis>
namespace to <link linkend="bootstrap:region:json">support JSON</link> features introduced
in GemFire 7.0, enabling Spring AOP to perform the necessary conversions automatically
on Region operations.
</para>
</listitem>
<listitem>
<para>Upgraded to GemFire 7.0.1 and added namespace support for new AsyncEventQueue attributes.</para>
</listitem>
<listitem>
<para>Added support for setting subscription interest policy on Regions.</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-1-3-1">
<title>New in the 1.3.1 Release</title>
<itemizedlist>
<listitem>
<para>
Support for void returns on Function executions. See <xref linkend="function-annotations"/>
for complete details.
</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-1-3-2">
<title>New in the 1.3.2 Release</title>
<itemizedlist>
<listitem>
<para>
Support for persisting Local Regions. See <xref linkend="bootstrap:region:local"/> and
<xref linkend="bootstrap:region:common:attributes"/>.
</para>
</listitem>
<listitem>
<para>
Support for entry time-to-live and entry idle-time on a GemFire Client Cache.
See <xref linkend="bootstrap:cache:client"/>
</para>
</listitem>
<listitem>
<para>
Support for multiple Spring Data GemFire web-based applications using a single GemFire cluster,
operating concurrently inside tc Server.
</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-1-3-3">
<title>New in the 1.3.3 Release</title>
<itemizedlist>
<listitem>
<para>
Support for concurrency-checks-enabled on all GemFire Cache Region definitions using the SDG
<emphasis>gfe</emphasis> namespace. See <xref linkend="bootstrap:region:common:attributes"/>.
</para>
</listitem>
<listitem>
<para>
Support for Cache Loaders and Cache Writers on Client, Local Regions.
See <xref linkend="bootstrap:region:common:loaders-writers"/>.
</para>
</listitem>
<listitem>
<para>
Support for registering CacheListeners, AsyncEventQueues and Gateway Senders
on GemFire Cache Sub-Regions.
</para>
</listitem>
<listitem>
<para>
Support for PDX persistent keys in GemFire Regions.
</para>
</listitem>
<listitem>
<para>
Support for correct Partition Region bean creation in a Spring context when collocation
is specified with the <emphasis>colocated-with</emphasis> attribute.
</para>
</listitem>
<listitem>
<para>
Full support for GemFire Cache Sub-Regions using proper, nested <literal>&lt;*-region&gt;</literal>
element syntax in the SDG <emphasis>gfe</emphasis> namespace.
</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-1-3-4">
<title>New in the 1.3.4 Release</title>
<itemizedlist>
<listitem>
<para>Upgraded Spring Data GemFire to Spring Framework 3.2.8.</para>
</listitem>
<listitem>
<para>Upgraded Spring Data GemFire to Spring Data Commons 1.7.1.</para>
</listitem>
</itemizedlist>
</section>
<section id="new-in-1-4-0">
<title>New in the 1.4.0 Release</title>
<itemizedlist>
<listitem>
<para>Upgrades Spring Data GemFire to GemFire 7.0.2.</para>
</listitem>
<listitem>
<para>Upgrades Spring Data GemFire to Spring Data Commons 1.8.0.</para>
</listitem>
<listitem>
<para>
Integrates Spring Data GemFire with Spring Boot, which includes both a
<emphasis>spring-boot-starter-data-gemfire </emphasis> POM along with a Spring Boot Sample
application demonstrating GemFire Cache Transactions configured with SDG bootstrapped
with Spring Boot.
</para>
</listitem>
<listitem>
<para>
Support for bootstrapping a Spring Context in a GemFire Server when started from Gfsh.
See <xref linkend="gemfire-bootstrap"/>.
</para>
</listitem>
<listitem>
<para>
Support for persisting application domain object/entities to multiple GemFire Cache Regions.
See <xref linkend="mapping.entities"/> for more details.
</para>
</listitem>
<listitem>
<para>
Support for persisting application domain object/entities to GemFire Cache Sub-Regions, avoiding
collisions when Sub-Regions are uniquely identifiable, but identically named.
See <xref linkend="mapping.entities"/> for more details.
</para>
</listitem>
<listitem>
<para>
Adds strict XSD type rules to, and full support for, Data Policies and Region Shortcuts on all
GemFire Cache Region types.
</para>
</listitem>
<listitem>
<para>
Changed the default behavior of SDG <literal>&lt;*-region&gt;</literal> elements from lookup
to always create a new Region along with an option to restore old behavior using the
<emphasis>ignore-if-exists</emphasis> attribute.
See <link linkend="bootstrap:region:common:attributes">Common Region Attributes</link>
and <xref linkend="bootstrap:region:common:regions-subregions-lookups-caution"/>
for more details.
</para>
</listitem>
<listitem>
<para>
Enables Spring Data GemFire to be fully built and ran on JDK 7 and JDK 8 (Note, however, GemFire
has not yet been fully tested and supported on JDK 8;
See <ulink url="http://pubs.vmware.com/vfabric53/topic/com.vmware.vfabric.gemfire.7.0/getting_started/system_requirements/supported_configurations.html">GemFire User Guide</ulink>
for additional details.
</para>
</listitem>
</itemizedlist>
</section>
</chapter>

View File

@@ -1,11 +0,0 @@
<chapter xml:id="requirements" xmlns="http://docbook.org/ns/docbook" version="5.0">
<title>Requirements</title>
<para>
Spring Data GemFire requires JDK 6.0 or above,
<ulink url="http://www.springsource.org/about">Spring Framework</ulink> 3 and
<ulink url="http://www.vmware.com/support/pubs/vfabric-gemfire.html">Pivotal GemFire</ulink>
6.6 or above (version 7 or above is recommended).
</para>
</chapter>

View File

@@ -1,23 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xml:id="sgf-links" xmlns="http://docbook.org/ns/docbook">
<title>Useful Links</title>
<itemizedlist>
<listitem>
<ulink url="http://projects.spring.io/spring-data-gemfire/">Spring Data GemFire Home Page</ulink>
</listitem>
<listitem>
<ulink url="http://www.vmware.com/products/application-platform/vfabric-gemfire/overview.html">Pivotal GemFire Home Page</ulink>
</listitem>
<listitem>
<ulink url="https://www.vmware.com/support/pubs/vfabric-gemfire.html">Pivotal GemFire Documentation</ulink>
</listitem>
<listitem>
<ulink url="http://communities.vmware.com/community/vmtn/appplatform/vfabric_gemfire">Pivotal GemFire Community Home Page</ulink>
</listitem>
<listitem>
<ulink url="http://forum.spring.io/forum/spring-projects/data/gemfire">Spring Data GemFire Forum</ulink>
</listitem>
</itemizedlist>
</chapter>

View File

@@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<preface xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="preface">
<title>Preface</title>
<para>
Spring Data GemFire focuses on integrating the Spring Framework's powerful, non-invasive programming model
and concepts with Pivotal GemFire, simplifying configuration, development and providing high-level abstractions.
This document assumes the reader already has a basic familiarity with the Spring Framework and Pivotal GemFire
concepts and APIs.
</para>
<para>
While every effort has been made to ensure this documentation is comprehensive and there are no errors,
some topics might require more explanation and some typos might have crept in. If you do spot any mistakes
or even more serious errors and you can spare a few cycles, please do bring the errors to the attention
of the Spring Data GemFire team by raising an <ulink url="https://jira.spring.io/browse/SGF">issue</ulink>.
Thank you.
</para>
</preface>

View File

@@ -1,210 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="bootstrap" version="5.0"
xmlns="http://docbook.org/ns/docbook"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:xlink="http://www.w3.org/1999/xlink">
<title>Bootstrapping GemFire through the Spring Container</title>
<para>
Spring Data GemFire provides full configuration and initialization of the GemFire data grid through
Spring's IoC container and provides several classes that simplify the configuration of GemFire components
including Caches, Regions, WAN Gateways, Persistence Backup, and other Distributed System components
to support a variety of scenarios with minimal effort.
</para>
<note>
<para>
This section assumes basic familiarity with GemFire. For more information see the
<link xlink:href="http://www.vmware.com/products/application-platform/vfabric-gemfire">product</link>
documentation.
</para>
</note>
<section id="bootstrap:region:spring:config">
<title>Advantages of using Spring over GemFire <literal>cache.xml</literal></title>
<para xmlns="">As of release 1.2.0, Spring Data GemFire's XML namespace
supports full configuration of the data grid. In fact, the Spring Data
GemFire namespace is considered the preferred way to configure GemFire.
GemFire will continue to support native <filename>
<literal xmlns="http://docbook.org/ns/docbook">cache.xml</literal>
</filename> for legacy reasons, but you can now do everything in Spring
XML and take advantage of the many wonderful things Spring has to offer
such as modular XML configuration, property placeholders, SpEL, and
environment profiles. Behind the namespace, Spring Data GemFire makes
extensive use of Spring's <interfacename>FactoryBean</interfacename>
pattern to simplify the creation and initialization of GemFire
components.</para>
<para xmlns=""> For example, GemFire provides several callback interfaces
such as <interfacename>
<literal xmlns="http://docbook.org/ns/docbook">CacheListener, </literal>
</interfacename><interfacename>
<literal xmlns="http://docbook.org/ns/docbook">CacheWriter, </literal>
</interfacename>and<interfacename>
<literal xmlns="http://docbook.org/ns/docbook">CacheLoader</literal>
</interfacename> to allow developers to add custom event handlers. Using
the Spring IoC container, these may configured as normal Spring beans and
injected into GemFire components. This is a significant improvement over
native <literal xmlns="http://docbook.org/ns/docbook">cache.xml</literal>
which provides relatively limited configuration options and requires
callbacks to implement GemFire's <literal>
<literal xmlns="http://docbook.org/ns/docbook">Declarable</literal>
</literal> interface (see <xref linkend="apis:declarable"
xmlns="http://docbook.org/ns/docbook"/> to see how you can still use
<literal xmlns="http://docbook.org/ns/docbook">Declarables</literal>
within Spring's DI container).</para>
<para xmlns=""> In addition, IDEs such as the Spring Tool Suite (STS)
provide excellent support for Spring XML namespaces, such as code
completion, pop-up annotations, and real time validation, making them easy
to use.</para>
</section>
<section id="bootstrap:namespace">
<title>Using the Core Spring Data GemFire Namespace</title>
<para>To simplify configuration, Spring Data GemFire provides a dedicated
XML namespace for configuring core GemFire components. It is also possible
to configure the beans directly through Spring's standard &lt;bean&gt;
definition. However, as of Spring Data GemFire 1.2.0, all bean properties
are exposed via the namespace so there is little benefit to using raw bean
definitions. For more information about XML Schema-based configuration in
Spring, see <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/xsd-config.html">this</ulink>
appendix in the Spring Framework reference documentation.</para>
<note>
<para>Spring Data Repository support uses a separate XML namespace. See
<xref linkend="gemfire-repositories"/> for more information on how to
configure GemFire Repositories.</para>
</note>
<para>To use the Spring Data GemFire namespace, simply declare it in your
Spring XML configuration meta-data:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlxsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:<co id="gfe#ns#prefix"/>gfe="http://www.springframework.org/schema/gemfire"<co
id="gfe#ns#uri"/>
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
<co id="gfe#ns#uri#loc"/>http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd"&gt;
&lt;bean id ... &gt;
<co id="gfe#ns#example"/>&lt;gfe:cache ...&gt;
&lt;/beans&gt;</programlisting>
<calloutlist>
<callout arearefs="gfe#ns#prefix">
<para>Spring GemFire namespace prefix. Any name will do but through
out the reference documentation, <literal>gfe</literal> will be
used.</para>
</callout>
<callout arearefs="gfe#ns#uri">
<para>The namespace URI.</para>
</callout>
<callout arearefs="gfe#ns#uri#loc">
<para>The namespace URI location. Note that even though the location
points to an external address (which exists and is valid), Spring will
resolve the schema locally as it is included in the Spring Data
GemFire library.</para>
</callout>
<callout arearefs="gfe#ns#example">
<para>Declaration example for the GemFire namespace. Notice the prefix
usage.</para>
</callout>
</calloutlist>
<para>Once declared, the namespace elements can be declared simply by
appending the aforementioned prefix.</para>
<note>
<para>It is possible to change the default namespace, for example from
<literal>beans</literal> to <literal>gfe</literal>. This is useful for
configuration composed mainly of GemFire components as it avoids
declaring the prefix. To achieve this, simply swap the namespace prefix
declaration above:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="<co id="gfe#default-ns#prefix"/>http://www.springframework.org/schema/gemfire"
xmlxsi="http://www.w3.org/2001/XMLSchema-instance"
<co id="gfe#default-ns#beans-prefix"/>
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd"&gt;
<co id="gfe#default-ns#beans-example"/>&lt;beans:bean id ... &gt;
<co id="gfe#default-ns#gfe-example"/>&lt;cache ...&gt;
&lt;/beans&gt;</programlisting>
<calloutlist>
<callout arearefs="gfe#default-ns#prefix">
<para>The default namespace declaration for this XML file points to
the Spring Data GemFire namespace.</para>
</callout>
<callout arearefs="gfe#default-ns#beans-prefix">
<para>The beans namespace prefix declaration.</para>
</callout>
<callout arearefs="gfe#default-ns#beans-example">
<para>Bean declaration using the <literal>beans</literal> namespace.
Notice the prefix.</para>
</callout>
<callout arearefs="gfe#default-ns#gfe-example">
<para>Bean declaration using the <literal>gfe</literal> namespace.
Notice the lack of prefix (as the default namespace is used).</para>
</callout>
</calloutlist>
</note>
</section>
<xi:include href="cache.xml"/>
<xi:include href="data-access.xml"/>
<xi:include href="region.xml"/>
<section id="bootstrap:indicies">
<title>Creating an Index</title>
<para>GemFire allows creation on indexes (or indices) to improve the
performance of (common) queries. Spring Data GemFire allows indecies to be
declared through the <literal>index</literal> element:</para>
<programlisting language="xml">&lt;gfe:index id="myIndex" expression="someField" from="/someRegion"/&gt;</programlisting>
<para>Before creating an index, Spring Data GemFire will verify whether
one with the same name already exists. If it does, it will compare the
properties and if they don't match, will remove the old one to create a
new one. If the properties match, Spring Data GemFire will simply return
the index (in case it does not exist it will simply create one). To
prevent the update of the index, even if the properties do not match, set
the property <literal>override</literal> to false.</para>
<para>Note that index declaration are not bound to a region but rather are
top-level elements (just like <literal>gfe:cache</literal>). This allows
one to declare any number of indecies on any region whether they are just
created or already exist - an improvement versus the GemFire
<literal>cache.xml</literal>. By default the index relies on the default
cache declaration but one can customize it accordingly or use a pool (if
need be) - see the namespace schema for the full set of options.</para>
</section>
<xi:include href="diskstore.xml"/>
<xi:include href="function.xml"/>
<xi:include href="gateway.xml"/>
</chapter>

View File

@@ -1,324 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<section id="bootstrap:cache" version="5.0"
xmlns="http://docbook.org/ns/docbook"
xmlns:ns52="http://www.w3.org/1998/Math/MathML"
xmlns:ns5="http://www.w3.org/1999/xlink"
xmlns:ns4="http://www.w3.org/2000/svg"
xmlns:ns3="http://www.w3.org/1999/xhtml"
xmlns:ns="http://docbook.org/ns/docbook">
<title>Configuring the GemFire Cache</title>
<para>In order to use GemFire, one needs to either create a new
<interfacename>Cache</interfacename> or connect to an existing one. In the
current version of GemFire, there can be only one opened cache per VM (or
per classloader to be technically correct). In most cases the cache is
created once.</para>
<note>This section describes the creation and configuration of a full cache
member, appropriate for peer to peer cache topologies and cache servers. A
full cache is also commonly used for standalone applications, integration
tests and proofs of concept. In a typical production system, most
application processes will act as cache clients and will create a
ClientCache instance instead. This is described in the sections <xref
linkend="bootstrap:cache:client"/> and <xref
linkend="bootstrap:region:client"/></note>
<para>A cache with default configuration can be created with a very simple
declaration:</para>
<programlisting language="xml">&lt;gfe:cache/&gt;</programlisting>
<para>A Spring application context containing this definition will, upon
initialization, will register a <literal>CacheFactoryBean</literal> to
create a Spring bean named <literal>gemfireCache</literal> referencing a
GemFire <interfacename>Cache</interfacename> instance. This will be either
an existing cache, or if one does not exist, a newly created one. Since no
additional properties were specified, a newly created cache will apply the
default cache configuration.</para>
<para>All Spring Data GemFire components which depend on the Cache respect
this naming convention so that there is no need to explicitly declare the
Cache dependency. If you prefer, you can make the dependence explicit via
the <literal>cache-ref</literal> attribute provided by various namespace
elements. Also you can easily override the Cache's bean name:</para>
<programlisting language="xml">&lt;gfe:cache id="my-cache"/&gt;</programlisting>
<para>Starting with Spring Data GemFire 1.2.0, The GemFire Cache may be
fully configured using Spring. However, GemFire's native XML configuration
file (e.g., cache.xml) is also supported. For scenarios in which the GemFire
cache needs to be configured natively, simply provide a reference the
GemFire configuration file using the <literal>cache-xml-location</literal>
attribute:</para>
<programlisting language="xml">&lt;gfe:cache id="cache-with-xml" cache-xml-location="classpath:cache.xml"/&gt;</programlisting>
<para>In this example, if the cache needs to be created, it will use the
file named <literal>cache.xml</literal> located in the classpath
root.</para>
<note>
<para>Note that the configuration makes use of Spring's <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/resources.html">
<interfacename>Resource</interfacename>
</ulink> 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.</para>
</note>
<para>In addition to referencing an external configuration file one can
specify GemFire <ulink
url="http://pubs.vmware.com/vfabricNoSuite/topic/com.vmware.vfabric.gemfire.7.0/reference/topics/gemfire_properties.html">properties</ulink>
using any of Spring's common properties support features. For example, one
can use the <literal>properties</literal> element defined in the
<literal>util</literal> namespace to define properties directly or load
properties from properties files. The latter is recommended for
externalizing environment specific settings outside the application
configuration:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"&gt;
&lt;gfe:cache properties-ref="props"/&gt;
&lt;util:properties id="props" location="file:/vfabric/gemfire/gemfire.properties"/&gt;
&lt;/beans&gt;</programlisting>
<note>
<para>The cache settings apply only if a new cache needs to be created. If
an open cache already exists in the JVM, these settings will be
ignored.</para>
</note>
<section id="bootstrap:cache:advanced">
<title>Advanced Cache Configuration</title>
<para>For advanced cache configuration, the <literal>cache</literal>
element provides a number of configuration options exposed as attributes
or child elements</para>
<programlisting language="xml"><co id="gfe#cache-element#attributes"/>
&lt;gfe:cache
copy-on-read="true"
critical-heap-percentage="70"
eviction-heap-percentage="60"
lock-lease="120"
lock-timeout="60"
pdx-serializer="myPdxSerializer"
pdx-disk-store="diskStore"
pdx-ignore-unread-fields="true"
pdx-persistent="true"
pdx-read-serialized="false"
message-sync-interval="1"
search-timeout="300"
close="false"
lazy-init="true"
&gt;
<co id="gfe#transaction#listener"/>&lt;gfe:transaction-listener ref="myTransactionListener"/&gt;
<co id="gfe#transaction#writer"/>&lt;gfe:transaction-writer&gt;
&lt;bean class="org.springframework.data.gemfire.example.TransactionListener"/&gt;
&lt;/gfe:transaction-writer&gt;
<co id="gfe#dynamic#region"/>&lt;gfe:dynamic-region-factory/&gt;
<co id="gfe#jndi#binding"/>&lt;gfe:jndi-binding jndi-name="myDataSource" type="ManagedDataSource"/&gt;
&lt;/gfe:cache&gt;
</programlisting>
<calloutlist>
<callout arearefs="gfe#cache-element#attributes">
<para>Various cache options are supported by attributes. For further
information regarding anything shown in this example, please consult
the GemFire product <ulink
url="http://www.vmware.com/support/pubs/vfabric-gemfire.html">documentation</ulink></para>
<para>The <literal>close</literal> attribute determines if the cache should be closed when the Spring application context is closed.
The default is <literal>true</literal> however for cases in which multiple application contexts use the cache (common in web applications), set this value to <literal>false</literal>.</para>
<para>The <literal>lazy-init</literal> attribute determines if the cache should be initialized before another bean references it.
The default is <literal>true</literal> however in some cases it may be convenient to set this value to <literal>false</literal>.</para>
</callout>
<callout arearefs="gfe#transaction#listener">
<para>An example of a
<interfacename>TransactionListener</interfacename> callback
declaration using a bean reference. The referenced bean must implement
<ulink
url="http://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/TransactionListener.html">TransactionListener</ulink></para>
</callout>
<callout arearefs="gfe#transaction#writer">
<para>An example of a <interfacename>TransactionWriter</interfacename>
callback declaration using an inner bean declaration this time. The
bean must implement <ulink
url="http://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/TransactionWriter.html">TransactionWriter</ulink></para>
</callout>
<callout arearefs="gfe#dynamic#region">
<para>Enable GemFire's <ulink
url="http://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/DynamicRegionFactory.html">DynamicRegionFactory</ulink></para>
</callout>
<callout arearefs="gfe#jndi#binding">
<para>Declares a JNDI binding to enlist an external datasource in a
GemFire transaction</para>
</callout>
</calloutlist>
<note>The <literal xmlns="">use-bean-factory-locator</literal> attribute
(not shown) deserves a mention. The factory bean responsible for creating
the cache uses an internal Spring type called a <interfacename
xmlns="">BeanFactoryLocator</interfacename> to enable user classes
declared in GemFire's native <literal xmlns="">cache.xml</literal> to be
registered as Spring beans. The <interfacename
xmlns="">BeanFactoryLocator</interfacename> implementation also permits
only one bean definition for a cache with a given id. In certain
situations, such as running JUnit integration tests from within Eclipse,
it is necessary to disable the <interfacename
xmlns="">BeanFactoryLocator</interfacename> by setting this value to
<literal xmlns="">false</literal> to prevent an exception. This exception
may also arise during JUnit tests running from a build script. In this
case the test runner should be configured to fork a new JVM for each test
(in maven, set <literal
xmlns="">&lt;forkmode&gt;always&lt;/forkmode&gt;</literal>) . Generally
there is no harm in setting this value to false.</note>
<section>
<title>Enabling PDX Serialization</title>
<para>The example above includes a number of attributes related to
GemGire'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 PDX serializer
which is done via the <literal>pdx-serializer</literal> attribute.
GemFire provides an implementation class <classname>
com.gemstone.gemfire.pdx.ReflectionBasedAutoSerializer</classname>,
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 required interface. More information on serialization
support can be found in <xref linkend="serialization"/></para>
<para/>
</section>
</section>
<section id="bootstrap:cache:server">
<title>Configuring a GemFire Cache Server</title>
<para>In Spring Data GemFire 1.1 dedicated support for configuring a
<ulink
url="http://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/server/CacheServer.html">CacheServer</ulink>
was added, allowing complete configuration through the Spring
container:</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
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"&gt;
&lt;gfe:cache /&gt;
&lt;!-- Advanced example depicting various cache server configuration options --&gt;
&lt;gfe:cache-server id="advanced-config" auto-startup="true"
bind-address="localhost" port="${gfe.port.6}" host-name-for-clients="localhost"
load-poll-interval="2000" max-connections="22" max-threads="16"
max-message-count="1000" max-time-between-pings="30000"
groups="test-server"&gt;
&lt;gfe:subscription-config eviction-type="ENTRY" capacity="1000" disk-store="file://${java.io.tmpdir}"/&gt;
&lt;/gfe:cache-server&gt;
&lt;context:property-placeholder location="classpath:cache-server.properties"/&gt;
&lt;/beans&gt;</programlisting>
<para>The configuration above illustrates the
<literal>cache-server</literal> element and the many options
available.</para>
<note>
<para>Rather than hard-coding the port, this configuration uses Spring's
<literal>
<ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/xsd-config.html#xsd-config-body-schemas-context">context</ulink>
</literal> namespace to declare a
<literal>property-placeholder</literal>. The <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-placeholderconfigurer">property
placeholder</ulink> reads one or more properties file and then replaces
property placeholders with values at runtime. This allows administrators
to change such values without having to touch the main application
configuration. Spring also provides <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/new-in-3.0.html#new-feature-el">SpEL</ulink>
and the <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/new-in-3.1.html#new-in-3.1-environment-abstraction">environment
abstraction</ulink> one to support externalization of environment
specific properties from the main code base, easing the deployment
across multiple machines.</para>
</note>
<note>
<para>To avoid initialization problems, the
<interfacename>CacheServer</interfacename>s started by Spring Data
GemFire will start <emphasis>after</emphasis> the 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 items as the server might
start after your components and thus not be seen by the clients
connecting right away.</para>
</note>
</section>
<section id="bootstrap:cache:client">
<title>Configuring a GemFire Client Cache</title>
<para>Another configuration addition in Spring Data GemFire 1.1 is the
dedicated support for configuring <ulink
url="http://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/client/ClientCache.html">ClientCache</ulink>.
This is similar to a <link linkend="bootstrap:cache">cache</link> in both
usage and definition and supported by
<classname>org.springframework.data.gemfire.clientClientCacheFactoryBean</classname>.</para>
<programlisting language="xml">&lt;beans&gt;
&lt;gfe:client-cache /&gt;
&lt;/beans&gt;</programlisting>
<para><literal>client-cache</literal> supports much of the same options as
the <emphasis>cache</emphasis> element. However as opposed to a
<emphasis>full</emphasis> cache, a client cache connects to a remote cache
server through a pool. By default a pool is created to connect to a server
on <literal>localhost</literal> port <literal>40404</literal>. The the
default pool is used by all client regions unless the region is configured
to use a different pool.</para>
<para>Pools can be defined through the <literal>pool</literal> element;
The client side <literal>pool</literal> can be used to configure
connectivity to the server for individual entities or for the entire
cache. For example, to customize the default pool used by
<literal>client-cache</literal>, one needs to define a pool and wire it to
cache definition:</para>
<programlisting language="xml">&lt;beans&gt;
&lt;gfe:client-cache id="simple" pool-name="my-pool"/&gt;
&lt;gfe:pool id="my-pool" subscription-enabled="true"&gt;
&lt;gfe:locator host="${locatorHost}" port="${locatorPort}"/&gt;
&lt;/gfe:pool&gt;
&lt;/beans&gt;</programlisting>
</section>
<para>The &lt;client-cache&gt; tag also includes a <literal>ready-for-events</literal>
attribute. If set to <literal>true</literal>, the client cache initialization will include
<ulink url="http://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/client/ClientCache.html#readyForEvents()">ClientCache.readyForEvents()</ulink>. </para>
<para>Client side configuration is covered in more detail in <xref
linkend="bootstrap:region:client"/>.</para>
</section>

View File

@@ -1,134 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<section xmlns="http://docbook.org/ns/docbook" version="5.0" xml:id="apis:cq-container">
<title>GemFire Continuous Query Container</title>
<para>A powerful functionality offered by GemFire is
<ulink url="http://community.gemstone.com/display/gemfire/Continuous+Querying">continuous querying</ulink> (or CQ).
In short, CQ allows one to create a query and automatically be notified when new data that gets added to GemFire matches the query.
Spring GemFire provides dedicated support for CQs through the <literal>org.springframework.data.gemfire.listener</literal> package and
its <emphasis>listener container</emphasis>; very similar in functionality
and naming to the JMS integration in Spring Framework; in fact, users familiar with the JMS support in Spring, should
feel right at home. Basically Spring Data GemFire allows methods on POJOs to become end-points for CQ - simply define the query and indicate the method
that should be notified when there is a match - Spring Data GemFire takes care of the rest. This is similar Java EE's message-driven bean style, but without any
requirement for base class or interface implementations, based on GemFire.</para>
<note>
<para>Currently, continuous queries are supported by GemFire only in client/server topologies. Additionally the pool used is required to have the
<literal>subscription</literal> property enabled. Please refer to the documentation for more information.</para>
</note>
<section id="apis:cq-container:containers">
<title>Continuous Query Listener Container</title>
<para>Spring Data GemFire simplifies the creation, registration, life-cycle and dispatch of CQs by taking care of the infrastructure around them through
<classname>ContinuousQueryListenerContainer</classname> which does all the heavy lifting on behalf of the user -
users familiar with EJB and JMS should find the concepts familiar as it is designed as close as possible to the
support in Spring Framework and its message-driven POJOs (MDPs)</para>
<para><classname>ContinuousQueryListenerContainer</classname> acts as an event (or message) listener container; it is used to receive the events
from the registered CQs and drive the POJOs that are injected into it. The listener container is responsible for all threading of message
reception and dispatches into the listener for processing. It acts as the intermediary between an EDP (Event Driven POJO) and the event provider
and takes care of creation and registration of CQs (to receive events), resource acquisition and release, exception conversion and the like.
This allows you as an application developer to write the (possibly complex) business logic associated with receiving an event (and reacting to it),
and delegates boilerplate GemFire infrastructure concerns to the framework.
</para>
<para>The container is fully customizable - one can chose either to use the CQ thread to perform the dispatch (synchronous delivery) or a new thread
(from an existing pool for examples) for an asynchronous approach by defining the suitable <interfacename>java.util.concurrent.Executor</interfacename>
(or Spring's <interfacename>TaskExecutor</interfacename>). Depending on the load, the number of listeners or the runtime
environment, one should change or tweak the executor to better serve her needs - in particular in managed environments (such as app servers), it is
highly recommended to pick a a proper <interfacename>TaskExecutor</interfacename> to take advantage of its runtime.</para>
</section>
<section id="apis:cq-container:adapter">
<title>The <classname>ContinuousQueryListenerAdapter</classname> and <interfacename>ContinuousQueryListener</interfacename></title>
<para>The <classname>ContinuousQueryListenerAdapter</classname> class is the
final component in Spring Data GemFire CQ support: in a nutshell, it allows you to expose almost <emphasis>any</emphasis> class
as a EDP (there are of course some constraints) - it implements <interfacename>ContinuousQueryListener</interfacename>, a simpler listener interface
similar to GemFire <ulink url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/query/CqListener.html">CqListener</ulink>.</para>
<para>Consider the following interface definition. Notice the
various event handling methods and their parameters:</para>
<programlisting language="java">public interface EventDelegate {
void handleEvent(CqEvent event);
void handleEvent(Operation baseOp);
void handleEvent(Object key);
void handleEvent(Object key, Object newValue);
void handleEvent(Throwable th);
void handleQuery(CqQuery cq);
void handleEvent(CqEvent event, Operation baseOp, byte[] deltaValue);
void handleEvent(CqEvent event, Operation baseOp, Operation queryOp, Object key, Object newValue);
}</programlisting>
<programlisting language="java">public class DefaultEventDelegate implements EventDelegate {
<lineannotation>// implementation elided for clarity...</lineannotation>
}</programlisting>
<para>In particular, note how the above implementation of the
<interfacename>EventDelegate</interfacename> interface (the above
<classname>DefaultEventDelegate</classname> class) has
<emphasis>no</emphasis> GemFire dependencies at all. It truly is a POJO that
we will make into an EDP via the following configuration (note that the class doesn't have to implement an interface,
one is present only to better show case the decoupling between contract and implementation).</para>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<lineannotation>xmlns:gfe="http://www.springframework.org/schema/gemfire"</lineannotation>
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
<lineannotation>http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd"</lineannotation>&gt;
<!-- create a client-pool that uses a pool with subscription enabled -->
&lt;gfe:client-cache pool-name="client"/&gt;
&lt;gfe:pool id="client" subscription-enabled="true"&gt;
&lt;gfe:server host="localhost" port="40404"/&gt;
&lt;/gfe:pool&gt;
&lt;gfe:cq-listener-container&gt;
&lt;!-- default handle method --&gt;
&lt;gfe:listener ref="listener" query="SELECT * from /region"/ &gt;
&lt;gfe:listener ref="another-listener" query="SELECT * from /another-region" name="my-query" method="handleQuery"/&gt;
&lt;/gfe:cq-listener-container&gt;
&lt;bean id="listener" class="gemfireexample.DefaultMessageDelegate"/&gt;
&lt;bean id="another-listener" class="gemfireexample.DefaultMessageDelegate"/&gt;
...
&lt;beans&gt;</programlisting>
<note>The example above shows some of the various forms that a listener can have; at its minimum the listener reference and the actual query definition are required. It's possible however to specify
a name for the resulting continuous query (useful for monitoring) but also the name of the method (the default is <literal>handleEvent</literal>). The specified method can have various
argument types, the <interfacename>EventDelegate</interfacename> interface lists the allowed types.</note>
<para>The example above uses the Spring Data GemFire namespace to declare the event listener container and automatically register the listeners. The full blown, <emphasis>beans</emphasis> definition
is displayed below:</para>
<programlisting language="xml"><lineannotation>&lt;!-- this is the Event Driven POJO (MDP) --&gt;</lineannotation>
<emphasis role="bold">&lt;bean id="eventListener" class="org.springframework.data.gemfire.listener.adapter.ContinuousQueryListenerAdapter"&gt;</emphasis>
&lt;constructor-arg&gt;
&lt;bean class="gemfireexample.DefaultEventDelegate"/&gt;
&lt;/constructor-arg&gt;
&lt;/bean&gt;
<lineannotation>&lt;!-- and this is the event listener container... --&gt;</lineannotation>
&lt;bean id="gemfireListenerContainer" class="org.springframework.data.gemfire.listener.ContinuousQueryListenerContainer"&gt;
&lt;property name="cache" ref="gemfireCache"/&gt;
&lt;property name="queryListeners"&gt;
<lineannotation>&lt;!-- set of listeners --&gt;</lineannotation>
&lt;set&gt;
&lt;bean class="org.springframework.data.gemfire.listener.ContinuousQueryDefinition" &gt;
&lt;constructor-arg value="SELECT * from /region" /&gt;
&lt;constructor-arg ref="eventListener" /&gt;
&lt;/bean&gt;
&lt;/set&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>Each time an event is received, the adapter automatically performs
type translation between the GemFire event and the required method argument(s) transparently. Any exception caused by the method invocation
is caught and handled by the container (by default, being logged).
</para>
</section>
</section>

View File

@@ -1,52 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<section id="data-access" version="5.0" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<title>Using the GemFire Data Access Namespace</title>
<para>In addition to the core <literal>gfe</literal> namespace, Spring Data
GemFire provides a <literal>gfe-data</literal> namespace intended primarily
to simplify the development of GemFire client applications. This namespace
currently supports for GemFire <link
linkend="gemfire-repositories">repositories</link> and function <link
linkend="function-execution">execution</link> and a
<tag>&lt;datasource&gt;</tag> tag that offers a convenient way to connect to
the data grid. </para>
<section id="data-access:datasource">
<title>An Easy Way to Connect to GemFire </title>
<para>For many applications, A basic connection to a GemFire grid, using
default values is sufficient. Spring Data GemFire's <tag>&lt;datasource&gt;</tag> tag
provides a simple way to access data. The data source creates a client
cache and connection pool. In addition, it will query the member servers
for all existing root regions and create a proxy (empty) client region for
each one. </para>
<programlisting language="xml">&lt;gfe-data:datasource&gt;
&lt;locator host="somehost" port="1234"/&gt;
&lt;/gfe-data:datasource&gt;</programlisting>
<para>The datasource tag is synactically similar to <tag>&lt;gfe:pool&gt;</tag>.
It may be configured with one or more locator or server tags to connect to
an existing data grid. Additionally, all attributes available to configure
a pool are supported. This configuration will automatically create
ClientRegion beans for each region defined on members connected to the
locator, so they may be seamlessly referenced by Spring Data mapping
annotations, GemfireTemplate, and wired into application
classes.</para>
<para>Of course, you can explicitly configure client regions. For
example, if you want to cache data in local memory:
<programlisting
language="xml">&lt;gfe-data:datasource&gt;
&lt;locator host="somehost" port="1234"/&gt;
&lt;/gfe-data:datasource&gt;
&lt;gfe:client-region id="Customer" shortcut="CACHING_PROXY"/&gt;</programlisting></para>
</section>
</section>

View File

@@ -1,355 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0"
xmlns:xi="http://www.w3.org/2001/XInclude"
xml:id="apis">
<title>Working with the GemFire APIs</title>
<para>
Once the GemFire Cache and Regions have been configured they can be injected and used inside application objects.
This chapter describes the integration with Spring's Transaction Management functionality
and <classname>DaoException</classname> hierarchy. It also covers support for dependency injection
of GemFire managed objects.
</para>
<section id="apis:exception-translation">
<title>Exception Translation</title>
<para>
Using a new data access technology requires not only accommodating a new API but also handling exceptions
specific to that technology. To accommodate this case, Spring Framework provides a technology agnostic,
consistent <ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/dao.html#dao-exceptions">exception hierarchy</ulink>
that abstracts the application from proprietary (and usually checked) exceptions to a set of focused
runtime exceptions. As mentioned in the Spring Framework documentation,
<ulink url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/orm.html#orm-exception-translation">exception translation</ulink>
can be applied transparently to your data access objects through the use of the <literal>@Repository</literal>
annotation and AOP by defining a <classname>PersistenceExceptionTranslationPostProcessor</classname> bean.
The same exception translation functionality is enabled when using GemFire as long as at least a
<classname>CacheFactoryBean</classname> is declared, e.g. using a <literal>&lt;gfe:cache/&gt;</literal>
declaration, as it acts as an exception translator which is automatically detected by the
Spring infrastructure and used accordingly.
</para>
</section>
<section id="apis:template">
<title>GemfireTemplate</title>
<para>
As with many other high-level abstractions provided by the Spring projects, Spring Data GemFire provides a
<emphasis>template</emphasis> that simplifies GemFire data access. The class provides several
<emphasis>one-line</emphasis> methods, for common region operations but also the ability to
<emphasis>execute</emphasis> code against the native GemFire API without having to deal with GemFire
checked exceptions for example through the <interfacename>GemfireCallback</interfacename>.
</para>
<para>
The template class requires a GemFire <interfacename>Region</interfacename> instance and once configured is
thread-safe and should be reused across multiple classes:
</para>
<programlisting language="xml">&lt;bean id="gemfireTemplate" class="org.springframework.data.gemfire.GemfireTemplate" p:region-ref="someRegion"/&gt;</programlisting>
<para>
Once the template is configured, one can use it alongside <interfacename>GemfireCallback</interfacename>
to work directly with the GemFire <interfacename>Region</interfacename>, without having to deal with
checked exceptions, threading or resource management concerns:
</para>
<programlisting language="java">template.execute(new GemfireCallback&lt;Iterable&lt;String&gt;&gt;() {
public Iterable&lt;String&gt; doInGemfire(Region reg) throws GemFireCheckedException, GemFireException {
// working against a Region of String
Region&lt;String, String&gt; region = reg;
region.put("1", "one");
region.put("3", "three");
return region.query("length &lt; 5");
}
});</programlisting>
<para>
For accessing the full power of the GemFire query language, one can use the <methodname>find</methodname>
and <methodname>findUnique</methodname> which, as opposed to the <methodname>query</methodname> method,
can execute queries across multiple regions, execute projections, and the like. The <methodname>find</methodname>
method should be used when the query selects multiple items (through<literal>SelectResults</literal>)
and the latter, <methodname>findUnique</methodname>, as the name suggests, when only one object is returned.
</para>
</section>
<section id="apis:spring-cache-abstraction">
<title>Support for Spring Cache Abstraction</title>
<para>
Since 1.1, Spring Data GemFire provides an implementation of the Spring 3.1
<ulink url="http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/spring-framework-reference.html#cache">cache abstraction</ulink>.
To use GemFire as a backing implementation, simply add <classname>GemfireCacheManager</classname> to your
configuration:
</para>
<programlisting language="xml"><![CDATA[<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:cache="http://www.springframework.org/schema/cache"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:p="http://www.springframework.org/schema/p"
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/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd">
<!-- turn on declarative caching -->
<cache:annotation-driven/>
<gfe:cache id="gemfire-cache"/>
<!-- declare GemFire Cache Manager -->
<bean id="cacheManager" class="org.springframework.data.gemfire.support.GemfireCacheManager" p:cache-ref="gemfire-cache">
</beans>]]></programlisting>
</section>
<section id="apis:tx-mgmt">
<title>Transaction Management</title>
<para>
One of the most popular features of Spring Framework is
<ulink url="http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/spring-framework-reference.html#transaction">transaction management</ulink>.
If you are not familiar with it, we strongly recommend
<ulink url="http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/spring-framework-reference.html#transaction-motivation">reading</ulink>
about it as it offers a consistent programming model that works transparently across multiple APIs and can be
configured either programmatically or declaratively (the most popular choice).
</para>
<para>
For GemFire, Spring Data GemFire provides a dedicated, per-cache, transaction manager that, once declared,
allows Region operations to be executed atomically through Spring:
</para>
<programlisting language="xml">&lt;gfe:transaction-manager id="tx-manager" cache-ref="cache"/&gt;</programlisting>
<note>
The example above can be simplified even more by eliminating the <literal>cache-ref</literal> attribute
if the GemFire Cache is defined under the default name<literal>gemfireCache</literal>. As with the other
Spring Data GemFire namespace elements, if the Cache bean name is not configured, the aforementioned naming
convention will used. Additionally, the transaction manager name is<literal>gemfireTransactionManager</literal>
if not explicitly specified.
</note>
<para>
Currently, GemFire supports optimistic transactions with <emphasis>read committed</emphasis> isolation.
Furthermore, to guarantee this isolation, developers should avoid making <emphasis>in-place</emphasis> changes
that manually modify values present in the Cache. To prevent this from happening, the transaction manager
configures the Cache to use <emphasis>copy on read</emphasis> semantics, meaning a clone of the actual value
is created, each time a read is performed. This behavior can be disabled if needed through the
<literal>copyOnRead</literal> property. For more information on the semantics of the underlying GemFire
transaction manager, see the GemFire
<ulink url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/CacheTransactionManager.html">documentation</ulink>.
</para>
</section>
<xi:include href="cq-container.xml"/>
<section id="apis:declarable">
<title>Wiring <interfacename>Declarable</interfacename> components</title>
<para>GemFire XML configuration (usually named
<literal>cache.xml</literal> allows <emphasis>user</emphasis> objects to
be declared as part of the configuration. Usually these objects are
<interfacename>CacheLoader</interfacename>s or other pluggable callback components
supported by GemFire. Using native GemFire configuration, each user type declared through
XML must implement the <interfacename>Declarable</interfacename> interface
which allows arbitrary parameters to be passed to the declared class
through a <classname>Properties</classname> instance.</para>
<para>In this section we describe how you can configure these pluggable
components defined in <literal>cache.xml</literal> using Spring while
keeping your Cache/Region configuration defined in
<literal>cache.xml</literal> This allows your pluggable components to
focus on the application logic and not the location or creation of
DataSources or other collaboration objects.</para>
<para>However, if you are starting a green field project, it is
recommended that you configure Cache, Region, and other pluggable
components directly in Spring. This avoids inheriting from the
<interfacename>Declarable</interfacename> interface or the base class
presented in this section. See the following sidebar for more information
on this approach.</para>
<sidebar>
<title>Eliminate <interfacename>Declarable</interfacename>
components</title>
<para>One can configure custom types entirely through Spring as
mentioned in <xref linkend="bootstrap:region" />. That way, one does not
have to implement the <interfacename>Declarable</interfacename>
interface and also benefits from all the features of the Spring IoC
container (not just dependency injection but also life-cycle
and instance management).</para>
</sidebar>
<para>As an example of configuring a
<interfacename>Declarable</interfacename> component using Spring, consider
the following declaration (taken from the
<interfacename>Declarable</interfacename> javadoc):</para>
<programlisting language="xml">&lt;cache-loader&gt;
&lt;class-name&gt;com.company.app.DBLoader&lt;/class-name&gt;
&lt;parameter name="URL"&gt;
&lt;string&gt;jdbc://12.34.56.78/mydb&lt;/string&gt;
&lt;/parameter&gt;
&lt;/cache-loader&gt;</programlisting>
<para>To simplify the task of parsing, converting the parameters and
initializing the object, Spring Data GemFire offers a base class
(<classname>WiringDeclarableSupport</classname>) that allows GemFire user
objects to be wired through a <emphasis>template</emphasis> bean
definition or, in case that is missing, perform autowiring through the
Spring container. To take advantage of this feature, the user objects need
to extend <classname>WiringDeclarableSupport</classname> which
automatically locates the declaring
<interfacename>BeanFactory</interfacename> and performs wiring as part of
the initialization process.</para>
<sidebar>
<title>Why is a base class needed?</title>
<para>In the current GemFire release there is no concept of an
<emphasis>object factory</emphasis> and the types declared are
instantiated and used as is. In other words, there is no easy way
to manage object creation outside GemFire.
</para>
</sidebar>
<section id="apis:declarable:template-wiring">
<title>Configuration using <emphasis>template</emphasis>
definitions</title>
<para>When used, <classname>WiringDeclarableSupport</classname> tries to
first locate an existing bean definition and use that as wiring
template. Unless specified, the component class name will be used as an
implicit bean definition name. Let's see how our
<classname>DBLoader</classname> declaration would look in that
case:</para>
<programlisting language="java">public class DBLoader extends WiringDeclarableSupport implements CacheLoader {
private DataSource dataSource;
public void setDataSource(DataSource ds){
this.dataSource = ds;
}
public Object load(LoaderHelper helper) { ... }
}</programlisting>
<programlisting language="xml">&lt;cache-loader&gt;
&lt;class-name&gt;com.company.app.DBLoader&lt;/class-name&gt;
&lt;!-- no parameter is passed (use the bean implicit name
that is the class name) --&gt;
&lt;/cache-loader&gt;</programlisting>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;
&lt;bean id="dataSource" ... /&gt;
&lt;!-- template bean definition --&gt;
&lt;bean id="com.company.app.DBLoader" abstract="true" p:dataSource-ref="dataSource"/&gt;
&lt;/beans&gt;</programlisting>
<para>In the scenario above, as no parameter was specified, a bean with
the id/name <literal>com.company.app.DBLoader</literal> was used as a template
for wiring the instance created by GemFire. For cases where the bean name uses a different
convention, one can pass in the <literal>bean-name</literal> parameter
in the GemFire configuration:</para>
<programlisting language="xml">&lt;cache-loader&gt;
&lt;class-name&gt;com.company.app.DBLoader&lt;/class-name&gt;
&lt;!-- pass the bean definition template name
as parameter --&gt;
&lt;parameter name="bean-name"&gt;
&lt;string&gt;template-bean&lt;/string&gt;
&lt;/parameter&gt;
&lt;/cache-loader&gt;</programlisting>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd"&gt;
&lt;bean id="dataSource" ... /&gt;
&lt;!-- template bean definition --&gt;
&lt;bean id="template-bean" abstract="true" p:dataSource-ref="dataSource"/&gt;
&lt;/beans&gt;</programlisting>
<note>
<para>The <emphasis>template</emphasis> bean definitions do not have
to be declared in XML - any format is allowed (Groovy, annotations,
etc..).</para>
</note>
</section>
<section id="apis:declarable:autowiring">
<title>Configuration using auto-wiring and annotations</title>
<para>If no bean definition is found, by default,
<classname>WiringDeclarableSupport</classname> will <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/spring-framework-reference.html#beans-factory-autowire">autowire</ulink>
the declaring instance. This means that unless any dependency injection
<emphasis>metadata</emphasis> is offered by the instance, the container
will find the object setters and try to automatically satisfy these
dependencies. However, one can also use JDK 5 annotations to provide
additional information to the auto-wiring process. We strongly recommend
reading the dedicated <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/htmlsingle/spring-framework-reference.html#beans-annotation-config">chapter</ulink>
in the Spring documentation for more information on the supported
annotations and enabling factors.</para>
<para>For example, the hypothetical <literal>DBLoader</literal>
declaration above can be injected with a Spring-configured
<interface>DataSource</interface> in the following way:</para>
<programlisting language="java">public class DBLoader extends WiringDeclarableSupport implements CacheLoader {
// use annotations to 'mark' the needed dependencies
@javax.inject.Inject
private DataSource dataSource;
public Object load(LoaderHelper helper) { ... }
}</programlisting>
<programlisting language="xml">&lt;cache-loader&gt;
&lt;class-name&gt;com.company.app.DBLoader&lt;/class-name&gt;
&lt;!-- no need to declare any parameters anymore
since the class is auto-wired --&gt;
&lt;/cache-loader&gt;</programlisting>
<programlisting language="xml">&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
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"&gt;
&lt;!-- enable annotation processing --&gt;
&lt;context:annotation-config/&gt;
&lt;/beans&gt;</programlisting>
<para>By using the JSR-330 annotations, the cache loader code has been
simplified since the location and creation of the DataSource has been
externalized and the user code is concerned only with the loading
process. The <interfacename>DataSource</interfacename> might be
transactional, created lazily, shared between multiple objects or
retrieved from JNDI - these aspects can be easily configured and changed
through the Spring container without touching the
<classname>DBLoader</classname> code.</para>
</section>
</section>
</chapter>

View File

@@ -1,38 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<section version="5.0" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook"
id="bootstrap-diskstore">
<title>Configuring a Disk Store</title>
<para>As of Release 1.2.0, Spring Data GemFire supports disk store
configuration via a top level <literal>disk-store</literal> element.</para>
<note>
<para>Prior to Release 1.2.0,
<literal>disk-store</literal> was a child element of
<literal>*-region</literal>. If you have regions configured with disk
storage using a prior release of Spring Data GemFire and want to upgrade
to the latest release, move the disk-store element to the top level,
assign an id and use the region's <literal>disk-store-ref</literal>
attribute. Also, <literal>disk-synchronous</literal> is now a region level
attribute. </para>
</note>
<programlisting language="xml" xml:lang="xml">&lt;gfe:disk-store id="diskStore1" queue-size="50" auto-compact="true"
max-oplog-size="10" time-interval="9999"&gt;
&lt;gfe:disk-dir location="/gemfire/store1/" max-size="20"/&gt;
&lt;gfe:disk-dir location="/gemfire/store2/" max-size="20"/&gt;
&lt;/gfe:disk-store&gt;</programlisting>
<para>Disk stores are used by regions for file system persistent backup or
overflow storage of evicted entries, and persistent backup of WAN gateways.
Note that multiple components may share the same disk store. Also multiple
directories may be defined for a single disk store. Please refer to the
GemFire documentation for an explanation of the configuration
options.</para>
</section>

View File

@@ -1,318 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
<chapter id="function-annotations">
<title>Annotation Support for Function Execution</title>
<section>
<title>Introduction</title>
<para>Spring Data GemFire 1.3.0 introduces annotation support to simplify
working with <ulink
url="http://pubs.vmware.com/vfabricNoSuite/index.jsp?topic=/com.vmware.vfabric.gemfire.7.0/developing/function_exec/chapter_overview.html??">GemFire
function execution</ulink>. The GemFire API provides classes to implement
and register <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/Function.html">Functions</ulink>
deployed to cache servers that may be invoked remotely by member
applications, typically cache clients. Functions may execute in parallel,
distributed among multiple servers, combining results in a map-reduce
pattern, or may be targeted to a single server. A Function execution may
be also be targeted to a specific region. </para>
<para>GemFire's also provides APIs to support remote execution of
functions targeted to various defined scopes (region, member groups,
servers, etc.) and the ability to aggregate results. The API also provides
certain runtime options. The implementation and execution of remote
functions, as with any RPC protocol, requires some boilerplate code.
Spring Data GemFire, true to Spring's core value proposition, aims to hide
the mechanics of remote function execution and allow developers to focus
on POJO programming and business logic. To this end, Spring Data GemFire
introduces annotations to declaratively register public methods as
functions, and the ability to invoke registered functions remotely via
annotated interfaces.</para>
</section>
<section>
<title>Implementation vs Execution</title>
<para>There are two separate concerns to address. First is the function
implementation (server) which must interact with the <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/FunctionContext.html">FunctionContext</ulink>
to obtain the invocation arguments, the <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/ResultSender.html">ResultsSender</ulink>
and other execution context information. The function implementation
typically accesses the Cache and or Region and is typically registered
with the <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/FunctionService.html">FunctionService</ulink>
under a unique Id. The application invoking a function (the client) does
not depend on the implementation. To invoke a function remotely, the
application instantiates an <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/Execution.html">Execution</ulink>
providing the function ID, invocation arguments, the function target or
scope (region, server, servers, member, members). If the function produces
a result, the invoker uses a <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/ResultCollector.html">ResultCollector</ulink>
to aggregate and acquire the execution results. In certain scenarios, a
custom ResultCollector implementation is required and may be registered
with the Execution. </para>
<note>
<para>'Client' and 'Server' are used here in the context of function
execution which may have a different meaning then client and server in a
client-server cache topology. While it is common for a member with a
Client Cache to invoke a function on one or more Cache Server members it
is also possible to execute functions in a peer-to-peer
configuration</para>
</note>
</section>
<section>
<title>Implementing a Function</title>
<para>Using GemFire APIs, the FunctionContext provides a runtime
invocation context including the client's calling arguments and a
ResultSender interface to send results back to the client. Additionally,
if the function is executed on a Region, the FunctionContext is an
instance of RegionFunctionContext which provides additional context such
as the target Region and any Filter (set of specific keys) associated with
the Execution. If the Region is a Partition Region, the function should
use the PartitonRegionHelper to extract only the local data. </para>
<para>Using Spring, one can write a simple POJO and enable the Spring
container bind one or more of it's public methods to a Function. The
signature for a POJO method intended to be used as a function must
generally conform to the the client's execution arguments. However, in the
case of a region execution, the region data must also be provided
(presumably the data held in the local partition if the region is a
partition region). Additionally the function may require the filter that
was applied, if any. This suggests that the client and server may share a
contract for the calling arguments but that the method signature may
include additional parameters to pass values provided by the
FunctionContext. One possibility is that the client and server share a
common interface, but this is not required. The only constraint is that
the method signature includes the same sequence of calling arguments with
which the function was invoked after the additional parameters are
resolved. For example, suppose the client provides a String and int as the
calling arguments. These are provided by the FunctionContext as an
array:</para>
<para><code language="java">Object[] args = new Object[]{"hello",
123}</code></para>
<para>Then the Spring container should be able to bind to any method
signature similar to the following. Let's ignore the return type for the
moment:</para>
<para><programlisting language="java">public Object method1(String s1, int i2) {...}
public Object method2(Map&lt;?,?&gt; data, String s1, int i2) {...}
public Object method3(String s1, Map&lt;?,?&gt;data, int i2) {...}
public Object method4(String s1, Map&lt;?,?&gt; data, Set&lt;?&gt; filter, int i2) {...}
public void method4(String s1, Set&lt;?&gt; filter, int i2, Region&lt;?,?&gt; data) {...}
public void method5(String s1, ResultSender rs, int i2);
public void method6(FunctionContest fc);</programlisting>The general rule is
that once any additional arguments, i.e., region data and filter, are
resolved the remaining arguments must correspond exactly, in order and
type, to the expected calling parameters. The method's return type must be
void or a type that may be serialized (either java.io.Serializable,
DataSerializable, or PDX serializable). The latter is also a requirement
for the calling arguments. The Region data should normally be defined as a
Map, to facilitate unit testing, but may also be of type Region if
necessary. As shown in the example above, it is also valid to pass the
FunctionContext itself, or the ResultSender, if you need to control how
the results are returned to the client.</para>
<section>
<title>Annotations for Function Implementation</title>
<para>The following example illustrates how annotations are used to
expose a POJO as a GemFire function:</para>
<para><programlisting language="java">@Component
public class MyFunctions {
@GemfireFunction
public String function1(String s1, @RegionData Map&lt;?,?&gt; data, int i2) { ... }
@GemfireFunction("myFunction", HA=true, optimizedForWrite=true, batchSize=100)
public List&lt;String&gt; function2(String s1, @RegionData Map&lt;?,?&gt; data, int i2, @Filter Set&lt;?&gt; keys) { ... }
@GemfireFunction(hasResult=true)
public void functionWithContext(FunctionContext functionContext) { ... }
} </programlisting>Note that the class itself must be registered as a Spring
bean. Here the <literal>@Component</literal> annotation is used, but you
may register the bean by any method provided by Spring (e.g. XML
configuration or Java configuration class). This allows the Spring
container to create an instance of this class and wrap it in a <ulink
url="https://github.com/SpringSource/spring-gemfire/blob/master/src/main/java/org/springframework/data/gemfire/function/PojoFunctionWrapper.java">PojoFunctionWrapper</ulink>(PFW).
Spring creates one PFW instance for each method annotated with
<literal>@GemfireFunction</literal>. Each will all share the same target
object instance to invoke the corresponding method. </para>
<note>
<para>The fact that the function class is a Spring bean may offer
other benefits since it shares the application context with GemFire
components such as a Cache and Regions. These may be injected into the
class if necessary.</para>
</note>
<para>Spring creates the wrapper class, and registers the function with
GemFire's Function Service. The function id used to register the
functions must be unique. By convention it defaults to the simple
(unqualified) method name. Note that this annotation also provides
configuration attributes, <literal>HA</literal> and
<literal>optimizedForWrite</literal> which correspond to properties
defined by GemFire's Function interface. If the method's return type is
void, then the <literal>hasResult</literal> property is automatically
set to <literal>false</literal>; otherwise it is
<literal>true</literal>. </para>
<para>For <literal>void</literal> return types, the annotation provides
a <literal>hasResult</literal> attribute that can be set to true to
override this convention, as shown in the
<literal>functionWithContext</literal> method above. Presumably, the
intention is to use the ResultSender directly to send results to the
caller. </para>
<para>The PFW implements GemFire's Function interface, binds the method
parameters, and invokes the target method in its
<literal>execute()</literal> method. It also sends the method's return
value using the ResultSender. </para>
<section>
<title>Batching Results</title>
<para>If the return type is a Collection or Array, then some
consideration must be given to how the results are returned. By
default, the PFW returns the entire collection at once. If the number
of items is large, this may incur a performance penalty. To divide the
payload into small sections (sometimes called chunking), you can set
the <literal>batchSize</literal> attribute, as illustrated in
<literal>function2</literal>, above. <note>
<para>If you need more control of the ResultSender, especially if
the method itself would use too much memory to create the
collection, you can pass the ResultSender, or access it via the
FunctionContext, to use it directly within the method.</para>
</note></para>
</section>
<section>
<title>Enabling Annotation Processing</title>
<para>In accordance with Spring standards, you must explicitly
activate annotation processing for @GemfireFunction using XML: </para>
<programlisting language="xml"> &lt;gfe:annotation-driven/&gt;</programlisting>
<para>or by annotating a Java configuration class:</para>
<programlisting language="java"> @EnableGemfireFunctions</programlisting>
</section>
</section>
</section>
<section id="function-execution">
<title>Executing a Function</title>
<para>A process invoking a remote function needs to provide calling
arguments, a function id, the execution target (onRegion, onServers,
onServer, onMember, onMembers) and optionally a Filter set. All you need
to do is define an interface supported by annotations. Spring will create
a dynamic proxy the interface which will use the FunctionService to create
an Execution, invoke the execution and coerce the results to a defined
return type, if necessary. This technique is very similar to the way
Spring Data repositories work, thus some of the configuration and concepts
should be familiar. Generally a single interface definition maps to
multiple function executions, one corresponding to each method defined in
the interface.</para>
<section>
<title>Annotations for Function Execution</title>
<para>To support client side function execution, the following
annotations are provided: <literal>@OnRegion</literal>,
<literal>@OnServer</literal>, <literal>@OnServers</literal>,
<literal>@OnMember</literal>, <literal>@OnMembers</literal>. These
correspond to the Execution implementations GemFire's FunctionService
provides. Each annotation exposes the appropriate attributes. These
annotations also provide an optional <literal>resultCollector</literal>
attribute whose value is the name of a Spring bean implementing <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/ResultCollector.html">ResultCollector</ulink>
to use for the execution. </para>
<note>
<para>The proxy interface binds all declared methods to the same
execution configuration. Although it is expected that single method
interfaces will be common, all methods in the interface are backed by
the same proxy instance and therefore are all share the same
configuration.</para>
</note>
<para>Here are some examples:</para>
<programlisting language="java">@OnRegion(region="someRegion", resultCollector="myCollector")
public interface FunctionExecution {
@FunctionId("function1")
public String doIt(String s1, int i2);
public String getString(Object arg1, @Filter Set&lt;Object&gt; keys) ;
}</programlisting>
<para>By default, the function id is the simple (unqualified) method
name. <literal>@FunctionId</literal> is used to bind this invocation to
a different function id. </para>
<section>
<title>Enabling Annotation Processing</title>
<para>The client side uses Spring's component scanning capability to
discover annotated interfaces. To enable function execution annotation
processing, you can use XML:</para>
<programlisting language="xml">&lt;gfe-data:function-executions base-package="org.example.myapp.functions"/&gt;</programlisting>
<para>Note that the <literal>function-executions</literal> tag is
provided in the <literal>gfe-data</literal> namespace. The
<literal>base-package</literal> attribute is required to avoid
scanning the entiire class path. Additional filters are provided as
described in the Spring <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/beans.html#beans-scanning-filters">reference</ulink>.</para>
<para>Or annotate your Java configuration class:</para>
<programlisting language="java"> @EnableGemfireFunctionExecutions(basePackages = "org.example.myapp.functions")</programlisting>
</section>
</section>
</section>
<section>
<title>Programmatic Function Execution</title>
<para>Using the annotated interface as described in the previous section,
simply wire your interface into a bean that will invoke the function:
</para>
<programlisting language="java">@Component
public class MyApp {
@Autowired FunctionExecution functionExecution;
public void doSomething() {
functionExecution.doIt("hello", 123);
}
}</programlisting>
<para>Alternately, you can use a Function Execution template directly. For
example GemfireOnRegionFunctionTemplate creates an onRegion execution. For
example:</para>
<para><programlisting language="java">Set&lt;?,?&gt; myFilter = getFilter();
Region&lt;?,?&gt; myRegion = getRegion();
GemfireOnRegionOperations template = new GemfireOnRegionFunctionTemplate(myRegion);
String result = template.executeAndExtract("someFunction",myFilter,"hello","world",1234);</programlisting>Internally,
function executions always return a List.
<literal>executeAndExtract</literal> assumes a singleton list containing
the result and will attempt to coerce that value into the requested type.
There is also an <literal>execute</literal> method that returns the List
itself. The first parameter is the function id. The filter argument is
optional. The following arguments are a variable argument list. </para>
</section>
</chapter>

View File

@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<section id="bootstrap:function" version="5.0"
xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<title>Configuring GemFire's Function Service</title>
<para>As of Release 1.3.0, Spring Data GemFire provides <link linkend="function-annotations">annotation</link> support
for implementing and registering functions. Spring Data GemFire also provides
namespace support for registering GemFire <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/cache/execute/Function.html">Functions</ulink>
for remote
function execution. Please refer to the GemFire documentation for more
information on the function execution framework. Functions are declared as
Spring beans and must implement the
<interfacename>com.gemstone.gemfire.cache.execute.Function</interfacename>
interface or extend
<interfacename>com.gemstone.gemfire.cache.execute.FunctionAdapter</interfacename>.
The namespace uses a familiar pattern to declare functions:</para>
<programlisting language="xml">&lt;gfe:function-service&gt;
&lt;gfe:function&gt;
&lt;bean class="com.company.example.Function1"/&gt;
&lt;ref bean="function2"/&gt;
&lt;/gfe:function&gt;
&lt;/gfe:function-service&gt;
&lt;bean id="function2" class="com.company.example.Function2"/&gt;</programlisting>
</section>

View File

@@ -1,119 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<section id="bootstrap:gateway" version="5.0"
xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns:m="http://www.w3.org/1998/Math/MathML"
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:db="http://docbook.org/ns/docbook">
<title>Configuring WAN Gateways</title>
<para>WAN gateways provide a way to synchronize GemFire distributed systems
across geographic distributed areas. As of Release 1.2.0, Spring Data
GemFire provides namespace support for configuring WAN gateways as
illustrated in the following examples:</para>
<section><title>WAN Configuration in GemFire 7.0</title>
<para>
GemFire 7.0 introduces new APIs for WAN configuration. While the original APIs provided
in GemFire 6 are still supported, it is recommended that you use the new
APIs if you are using GemFire 7.0. The Spring Data GemFire namespace
supports either. In the example below, <literal>GatewaySender</literal>s are configured for a
partitioned region by adding child elements to the region (<literal>gateway-sender</literal>
and <literal>gateway-sender-ref</literal>). The <literal>GatewaySender</literal> may register
<literal>EventFilter</literal>s and
<literal>TransportFilters</literal>. Also shown below is an example configuration of an
<literal>AsyncEventQueue</literal> which must also be wired into a region (not shown).
</para>
<programlisting language="xml">&lt;gfe:partitioned-region id="region-inner-gateway-sender" &gt;
&lt;gfe:gateway-sender
remote-distributed-system-id="1"&gt;
&lt;gfe:event-filter&gt;
&lt;bean class="org.springframework.data.gemfire.example.SomeEventFilter"/&gt;
&lt;/gfe:event-filter&gt;
&lt;gfe:transport-filter&gt;
&lt;bean class="org.springframework.data.gemfire.example.SomeTransportFilter"/&gt;
&lt;/gfe:transport-filter&gt;
&lt;/gfe:gateway-sender&gt;
&lt;gfe:gateway-sender-ref bean="gateway-sender"/&gt;
&lt;/gfe:partitioned-region&gt;
&lt;gfe:async-event-queue id="async-event-queue" batch-size="10" persistent="true" disk-store-ref="diskstore"
maximum-queue-memory="50"&gt;
&lt;gfe:async-event-listener&gt;
&lt;bean class="org.springframework.data.gemfire.example.SomeAsyncEventListener"/&gt;
&lt;/gfe:async-event-listener&gt;
&lt;/gfe:async-event-queue&gt;
&lt;gfe:gateway-sender id="gateway-sender" remote-distributed-system-id="2"&gt;
&lt;gfe:event-filter&gt;
&lt;ref bean="event-filter"/&gt;
&lt;bean class="org.springframework.data.gemfire.example.SomeEventFilter"/&gt;
&lt;/gfe:event-filter&gt;
&lt;gfe:transport-filter&gt;
&lt;ref bean="transport-filter"/&gt;
&lt;bean class="org.springframework.data.gemfire.example.SomeTransportFilter"/&gt;
&lt;/gfe:transport-filter&gt;
&lt;/gfe:gateway-sender&gt;
&lt;bean id="event-filter" class="org.springframework.data.gemfire.example.AnotherEventFilter"/&gt;
&lt;bean id="transport-filter" class="org.springframework.data.gemfire.example.AnotherTransportFilter"/&gt;
</programlisting>
<para>On the other end of a <literal>GatewaySender</literal> is a corresponding
<literal>GatewayReceiver</literal>
to receive gateway events. The <literal>GatewayReceiver</literal> may also be configured with
<literal>EventFilter</literal>s and <literal>TransportFilter</literal>s.</para>
<programlisting language="xml">&lt;gfe:gateway-receiver id="gateway-receiver"
start-port="12345" end-port="23456" bind-address="192.168.0.1"&gt;
&lt;gfe:transport-filter&gt;
&lt;bean class="org.springframework.data.gemfire.example.SomeTransportFilter"/&gt;
&lt;/gfe:transport-filter&gt;
&lt;/gfe:gateway-receiver&gt;</programlisting>
<para>Please refer to the GemFire product document for a detailed
explanation of all the configuration options.</para>
</section>
<section>
<title>WAN Configuration in GemFire 6.6</title>
<programlisting language="xml">&lt;gfe:cache/&gt;
&lt;gfe:replicated-region id="region-with-gateway" enable-gateway="true" hub-id="gateway-hub"/&gt;
&lt;gfe:gateway-hub id="gateway-hub" manual-start="true"&gt;
&lt;gfe:gateway gateway-id="gateway"&gt;
&lt;gfe:gateway-listener&gt;
&lt;bean class="com.company.example.MyGatewayListener"/&gt;
&lt;/gfe:gateway-listener&gt;
&lt;gfe:gateway-queue maximum-queue-memory="5" batch-size="3"
batch-time-interval="10" /&gt;
&lt;/gfe:gateway&gt;
&lt;gfe:gateway gateway-id="gateway2"&gt;
&lt;gfe:gateway-endpoint port="1234" host="host1" endpoint-id="endpoint1"/&gt;
&lt;gfe:gateway-endpoint port="2345" host="host2" endpoint-id="endpoint2"/&gt;
&lt;/gfe:gateway&gt;
&lt;/gfe:gateway-hub&gt;</programlisting>
<para>A region may synchronize all or part of its contents to a gateway
hub used to access one or more remote systems. The region must set
<literal>enable-gateway</literal> to <literal>true</literal> and specify
the <literal>hub-id</literal>.</para>
<para>
<note>
<para>If just a hub-id is specified, Spring Data GemFire automatically
assumes that the gateway should be enabled.</para>
</note>
</para>
<para>Please refer to the GemFire product document for a detailed
explanation of all the configuration options.</para>
</section>
</section>

View File

@@ -1,196 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="gemfire-bootstrap" version="5.0" xmlns="http://docbook.org/ns/docbook">
<title>Bootstrapping a Spring ApplicationContext in GemFire</title>
<section>
<title id="gemfire-bootstrap:intro">Introduction</title>
<para>
Normally, a Spring-based application will <link linkend="bootstrap">bootstrap GemFire</link> using
Spring Data GemFire's XML namespace. Just by specifying a <literal>&lt;gfe:cache/&gt;</literal> element
in Spring Data GemFire configuration meta-data, a single, peer GemFire Cache instance will be created
and initialized with default settings in the same JVM process as your application.
</para>
<para>
However, sometimes it is a requirement, perhaps imposed by your IT operations team, that GemFire must be
fully managed and operated using the provided GemFire tool suite, such as with
<ulink url="http://pubs.vmware.com/vfabric53/topic/com.vmware.vfabric.gemfire.7.0/tools_modules/gfsh/chapter_overview.html">Gfsh</ulink>.
Using <emphasis>Gfsh</emphasis>, even though the application and GemFire will share the same JVM process,
GemFire will bootstrap your Spring application context rather than the other way around. So, using this
approach GemFire, instead of an application server, or a Java main class using Spring Boot, will bootstrap
and host your application.
</para>
<para>
Keep in mind, however, that GemFire is not an application server. In addition, there are limitations
to using this approach where GemFire Cache configuration is concerned.
</para>
</section>
<section>
<title id="gemfire-bootstrap:initializer">Using GemFire to Bootstrap a Spring Context Started with Gfsh</title>
<para>
In order to bootstrap a Spring application context in GemFire when starting a GemFire Server process
using Gfsh, a user must make use of GemFire's
<ulink url="http://pubs.vmware.com/vfabric53/topic/com.vmware.vfabric.gemfire.7.0/basic_config/the_cache/setting_cache_initializer.html">Initalizer</ulink>
functionality. An <emphasis>Initializer</emphasis> can be used to specify a callback application that
is launched after the Cache is initialized by GemFire.
</para>
<para>
An <emphasis>Initializer</emphasis> is specified within an
<ulink url="http://pubs.vmware.com/vfabric53/topic/com.vmware.vfabric.gemfire.7.0/reference/topics/cache_xml.html?path=4_1_9_1_2_21#initializer">initializer</ulink>
element using a minimal snippet of GemFire's native configuration meta-data inside
a <literal>cache.xml</literal> file. The <literal>cache.xml</literal> file is required in order to
bootstrap the Spring application context, much like a minimal snippet of Spring XML config is needed to
bootstrap a Spring application context configured with component scanning
(e.g. <literal>&lt;context:component-scan base-packages="..."/&gt;</literal>)
</para>
<para>
As of Spring Data GemFire 1.4, such an <emphasis>Initializer</emphasis> is already conveniently provided
by the framework, the <classname>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</classname>.
The typical, yet minimal configuration for this class inside GemFire's <literal>cache.xml</literal> file
will look like the following:
</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<cache>
<initializer>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
<parameter name="contextConfigLocations">
<string>classpath:application-context.xml</string>
</parameter>
</initializer>
</cache>]]>
</programlisting>
<para>
The <classname>SpringContextBootstrappingInitializer</classname> class follows similar conventions as
Spring's ContextLoaderListener class for bootstrapping a Spring context inside a Web Application, where
application context configuration files are specified with the <literal>contextConfigLocations</literal>
Servlet Context Parameter. In addition, the <classname>SpringContextBootstrappingInitializer</classname>
class can also be used with a <literal>basePackages</literal> parameter to specify a comma-separated list
of base package containing the appropriately annotated application components that the Spring container
will search using component scanning and create Spring beans for:
</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<cache>
<initializer>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
<parameter name="basePackages">
<string>org.mycompany.myapp.services,org.mycompany.myapp.dao,...</string>
</parameter>
</initializer>
</cache>]]>
</programlisting>
<para>
Then, with a properly configured and constructed <literal>CLASSPATH</literal> along with the
<literal>cache.xml</literal> file shown above specified as a command-line option when starting
a GemFire Server in Gfsh, the command-line would be:
</para>
<programlisting>gfsh>start server --name=Server1 --log-level=config ...
--classpath="/path/to/spring-data-gemfire-1.4.0.jar:/path/to/application/classes.jar"
--cache-xml-file="/path/to/gemfire/cache.xml"
</programlisting>
<para>
The <literal>application-context.xml</literal> can be any valid Spring context configuration meta-data
including all the SDG namespace elements. The only limitation with this approach is that the GemFire
Cache cannot be configured using the Spring Data GemFire namespace. In other words, none of the
<literal>&lt;gfe:cache/&gt;</literal> element attributes, such as <literal>cache-xml-location</literal>,
<literal>properties-ref</literal>, <literal>critical-heap-percentage</literal>, <literal>pdx-serializer-ref</literal>,
<literal>lock-lease</literal>, etc can be specified. If used, these attributes will be ignored.
The main reason for this is that GemFire itself has already created an initialized the Cache before
the <emphasis>Initializer</emphasis> gets invoked. As such, the Cache will already exist and since it is
a "Singleton", it cannot be re-initialized or have any of it's configuration augmented.
</para>
</section>
<section>
<title id="gemfire-bootstrap:lazy-wiring">Lazy-Wiring GemFire Components</title>
<para>
Spring Data GemFire already provides existing support for wiring GemFire components (such as CacheListeners,
CacheLoaders or CacheWriters) that are declared and created by GemFire in <literal>cache.xml</literal>
using the <classname>WiringDeclarableSupport</classname> class as described in
<xref linkend="apis:declarable:autowiring"/>.
However, this only works when Spring does the bootstrapping (i.e. bootstraps GemFire). When your Spring
application context is the one bootstrapped by GemFire, then these GemFire components go unnoticed since
the Spring application context does not even exist yet! The Spring application context will not get created
until GemFire calls the <emphasis>Initializer</emphasis>, which occurs after all the other GemFire components
and configuration have already been created and initialized.
</para>
<para>
So, in order to solve this problem, a new <classname>LazyWiringDeclarableSupport</classname> class was
introduced, that is, in a sense, Spring application context aware. The intention of this abstract
base class is that any implementing class will register itself to be configured by the Spring
application context created by GemFire after the <emphasis>Initializer</emphasis> is called. In essence,
this give your GemFire managed component a chance to be configured and auto-wired with Spring beans defined
in the Spring application context.
</para>
<para>
In order for your GemFire application component to be auto-wired by the Spring container, create a
application class that extends the <classname>LazyWiringDeclarableSupport</classname> and annotate
any class member that needs to be provided as a Spring bean dependency, similar to:
</para>
<programlisting language="java"><![CDATA[
public static final class UserDataSourceCacheLoader extends LazyWiringDeclarableSupport implements CacheLoader<String, User> {
@Autowired
private DataSource userDataSource;
...
}
]]></programlisting>
<para>
As implied by the CacheLoader example above, you might necessarily (although, rare) have defined both
a Region and CacheListener component in GemFire <literal>cache.xml</literal>. The CacheLoader may need
access to an application DAO, or perhaps Spring application context defined JDBC Data Source
for loading "Users" into a GemFire Cache <literal>REPLICATE</literal> Region on start. Of course,
one should be careful in mixing the different life-cycles of GemFire and the Spring Container together
in this manner as not all use cases and scenarios are supported. The GemFire <literal>cache.xml</literal>
configuration would be similar to the following (which comes from SDG's test suite):
</para>
<programlisting language="xml"><![CDATA[<?xml version="1.0"?>
<!DOCTYPE cache PUBLIC "-//GemStone Systems, Inc.//GemFire Declarative Caching 7.0//EN"
"http://www.gemstone.com/dtd/cache7_0.dtd">
<cache>
<region name="Users" refid="REPLICATE">
<region-attributes initial-capacity="101" load-factor="0.85">
<key-constraint>java.lang.String</key-constraint>
<value-constraint>org.springframework.data.gemfire.repository.sample.User</value-constraint>
<cache-loader>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializerIntegrationTest$UserDataStoreCacheLoader</class-name>
</cache-loader>
</region-attributes>
</region>
<initializer>
<class-name>org.springframework.data.gemfire.support.SpringContextBootstrappingInitializer</class-name>
<parameter name="basePackages">
<string>org.springframework.data.gemfire.support.sample</string>
</parameter>
</initializer>
</cache>]]>
</programlisting>
</section>
</chapter>

View File

@@ -1,46 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="ref-introduction" version="5.0" xmlns="http://docbook.org/ns/docbook">
<title>Document Structure</title>
<para>
The following chapters explain the core functionality offered by Spring Data GemFire.
</para>
<para>
<xref linkend="bootstrap"/> describes the configuration support provided for bootstrapping, configuring,
initializing and accessing GemFire Caches, Cache Servers, Regions, and related Distributed System components.
</para>
<para>
<xref linkend="apis"/> explains the integration between the GemFire APIs and the various data access features
available in Spring, such as transaction management and exception translation.
</para>
<para>
<xref linkend="serialization"/> describes the enhancements for GemFire (de)serialization and management
of associated objects.
</para>
<para>
<xref linkend="mapping"/> describes persistence mapping for POJOs stored in GemFire using Spring Data.
</para>
<para>
<xref linkend="gemfire-repositories"/> describes how to create and use GemFire Repositories using Spring Data.
</para>
<para>
<xref linkend="function-annotations"/> describes how to create and use GemFire Functions using annotations.
</para>
<para>
<xref linkend="gemfire-bootstrap"/> describes how to bootstrap a Spring ApplicationContext running
in a GemFire Server using Gfsh.
</para>
<para>
<xref linkend="samples"/> describes the samples provided with the distribution to illustrate
the various features available in Spring Data GemFire.
</para>
</chapter>

View File

@@ -1,126 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter id="mapping" version="5.0" xmlns="http://docbook.org/ns/docbook">
<title>POJO mapping</title>
<section xml:id="mapping.entities">
<title>Entity Mapping</title>
<para>
Spring Data GemFire provides support to map entities that will be stored in a GemFire data grid.
The mapping metadata is defined using annotations at the domain classes just like this:
</para>
<example>
<title>Mapping a domain class to a GemFire Region</title>
<programlisting language="java">@Region("People")
public class Person {
@Id Long id;
String firstname;
String lastname;
@PersistenceConstructor
public Person(String firstname, String lastname) {
// …
}
}
</programlisting>
</example>
<para>
The first thing you see here is the <interfacename>@Region</interfacename> annotation that can be used to
customize the Region in which the <classname>Person</classname> class is stored in. The
<interfacename>@Id</interfacename> annotation can be used to annotate the property that shall be used as
the Cache key. The <interfacename>@PersistenceConstructor</interfacename> annotation actually helps
disambiguating multiple potentially available constructors taking parameters and explicitly marking the one
annotated as the one to be used to create entities. With none or only a single constructor you can omit the
annotation.
</para>
<para>
In addition to storing entities in top-level Regions, entities can be stored in GemFire Sub-Regions, as so:
</para>
<programlisting language="java">@Region("/Users/Admin")
public class Admin extends User {
}
@Region("/Users/Guest")
public class Guest extends User {
...
}
</programlisting>
<para>
Be sure to use the full-path of the GemFire Region, as defined in Spring Data GemFire XML namespace
configuration meta-data, as specified in the <literal>id</literal> or <literal>name</literal> attributes
of the <literal>&lt;*-region&gt;</literal> bean definition.
</para>
<para>
As alternative to specifying the Region in which the entity will be stored using the
<interfacename>@Region</interfacename> annotation on the entity class, you can also specify the
<interfacename>@Region</interfacename> annotation on the entity's <interfacename>Repository</interfacename>
abstraction. See <xref linkend="gemfire-repositories"/> for more details.
</para>
<para>
However, let's say you want to store a Person in multiple GemFire Regions (e.g. <literal>People</literal>
and <literal>Customers</literal>), then you can define your corresponding <interfacename>Repository</interfacename>
interface abstractions like so:
</para>
<programlisting language="java"><![CDATA[@Region("People")
public interface PersonRepository extends GemfireRepository<Person, String> {
}
@Region("Customers")
public interface CustomerRepository extends GemfireRepository<Person, String> {
...
}
]]></programlisting>
</section>
<section xml:id="mapping.pdx-serializer">
<title>Mapping PDX Serializer</title>
<para>Spring Data GemFire provides a custom
<interfacename>PDXSerializer</interfacename> implementation that uses the
mapping information to customize entity serialization. Beyond that it
allows customizing the entity instantiation by using the Spring Data
<interfacename>EntityInstantiator</interfacename> abstraction. By default
the serializer uses a <classname>ReflectionEntityInstantiator</classname>
that will use the persistence constructor of the mapped entity (either the
single declared one or explicitly annoted with
<interfacename>@PersistenceConstructor</interfacename>). To provide values
for constructor parameters it will read fields with name of the
constructor parameters from the <interfacename>PDXReader</interfacename>
supplied.</para>
<example>
<title>Using @Value on entity constructor parameters</title>
<programlisting language="java">public class Person {
public Person(@Value("#root.foo") String firstname, @Value("bean") String lastname) {
// …
}
} </programlisting>
</example>
<para>The entity annotated as such will get the field <code>foo</code>
read from the <interfacename>PDXReader</interfacename> and handed as
constructor parameter value for <code>firstname</code>. The value for
<code>lastname</code> will be the Spring bean with name
<code>bean</code>.</para>
</section>
</chapter>

File diff suppressed because it is too large Load Diff

View File

@@ -1,229 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.0" xml:id="gemfire-repositories"
xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:ns5="http://www.w3.org/1999/xhtml"
xmlns:ns4="http://www.w3.org/2000/svg"
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
xmlns:ns="http://docbook.org/ns/docbook">
<title>GemFire Repositories</title>
<section>
<title xml:id="gemfire-repositories.intro">Introduction</title>
<para>Spring Data GemFire provides support to use the Spring Data
repository abstraction to easily persist entities into GemFire and execute
queries. A general introduction into the repository programming model is
been provided <ulink
url="http://static.springsource.org/spring-data/data-commons/docs/current/reference/html/#repositories">here
</ulink>.</para>
</section>
<section xml:id="gemfire-repositories.spring-configuration">
<title>Spring configuration</title>
<para>To bootstrap Spring Data repositories you use the
<code>&lt;repositories /&gt;</code> element from the GemFire
namespace:</para>
<example>
<title>Bootstrap GemFire repositories</title>
<programlisting language="xml">&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe-data="http://www.springframework.org/schema/data/gemfire"
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/data/gemfire
http://www.springframework.org/schema/data/gemfire/spring-data-gemfire.xsd&gt;
&lt;gfe-data:repositories base-package="com.acme.repository" /&gt;
&lt;/beans&gt;</programlisting>
</example>
<para>This configuration snippet will look for interfaces below the
configured base package and create repository instances for those
interfaces backed by a <classname>SimpleGemFireRepository</classname>.
Note that you have to have your domain classes correctly mapped to
configured regions as the bottstrap process will fail otherwise.</para>
</section>
<section xml:id="gemfire-repositories.executing-queries">
<title>Executing OQL queries</title>
<para>The GemFire repositories allow the definition of query methods to
easily execute OQL queries against the Region the managed entity is mapped
to.</para>
<example>
<title>Sample repository</title>
<programlisting language="java">@Region("myRegion")
public class Person { … }</programlisting>
<programlisting language="java">public interface PersonRepository extends CrudRepository&lt;Person, Long&gt; {
Person findByEmailAddress(String emailAddress);
Collection&lt;Person&gt; findByFirstname(String firstname);
@Query("SELECT * FROM /Person p WHERE p.firstname = $1")
Collection&lt;Person&gt; findByFirstnameAnnotated(String firstname);
@Query("SELECT * FROM /Person p WHERE p.firstname IN SET $1")
Collection&lt;Person&gt; findByFirstnamesAnnotated(Collection&lt;String&gt; firstnames);
}</programlisting>
</example>
<para>The first method listed here will cause the following query to be
derived: <code>SELECT x FROM /myRegion x WHERE x.emailAddress = $1</code>.
The second method works the same way except it's returning all entities
found whereas the first one expects a single result value. In case the
supported keywords are not sufficient to declare your query or the method
name gets to verbose you can annotate the query methods with
<interfacename>@Query</interfacename> as seen for methods 3 and 4.</para>
<para><table>
<title>Supported keywords for query methods</title>
<tgroup cols="3">
<colspec colwidth="1*"/>
<colspec colwidth="2*"/>
<colspec colwidth="2*"/>
<thead>
<row>
<entry>Keyword</entry>
<entry>Sample</entry>
<entry>Logical result</entry>
</row>
</thead>
<tbody>
<row>
<entry><literal>GreaterThan</literal></entry>
<entry><methodname>findByAgeGreaterThan(int
age)</methodname></entry>
<entry><code>x.age &gt; $1</code></entry>
</row>
<row>
<entry><literal>GreaterThanEqual</literal></entry>
<entry><methodname>findByAgeGreaterThanEqual(int
age)</methodname></entry>
<entry><code>x.age &gt;= $1</code></entry>
</row>
<row>
<entry><literal>LessThan</literal></entry>
<entry><methodname>findByAgeLessThan(int
age)</methodname></entry>
<entry><code>x.age &lt; $1</code></entry>
</row>
<row>
<entry><literal>LessThanEqual</literal></entry>
<entry><methodname>findByAgeLessThanEqual(int
age)</methodname></entry>
<entry><code>x.age &lt;= $1</code></entry>
</row>
<row>
<entry><literal>IsNotNull</literal>,
<literal>NotNull</literal></entry>
<entry><methodname>findByFirstnameNotNull()</methodname></entry>
<entry><code>x.firstname =! NULL</code></entry>
</row>
<row>
<entry><literal>IsNull</literal>,
<literal>Null</literal></entry>
<entry><methodname>findByFirstnameNull()</methodname></entry>
<entry><code>x.firstname = NULL</code></entry>
</row>
<row>
<entry><literal>In</literal></entry>
<entry><methodname>findByFirstnameIn(Collection&lt;String&gt;
x)</methodname></entry>
<entry><code>x.firstname IN SET $1</code></entry>
</row>
<row>
<entry><literal>NotIn</literal></entry>
<entry><methodname>findByFirstnameNotIn(Collection&lt;String&gt;
x)</methodname></entry>
<entry><code>x.firstname NOT IN SET $1</code></entry>
</row>
<row>
<entry>(No keyword)</entry>
<entry><methodname>findByFirstname(String
name)</methodname></entry>
<entry><code>x.firstname = $1</code></entry>
</row>
<row>
<entry><literal>Like</literal></entry>
<entry><methodname>findByFirstnameLike(String
name)</methodname></entry>
<entry><code>x.firstname LIKE $1</code></entry>
</row>
<row>
<entry><literal>Not</literal></entry>
<entry><methodname>findByFirstnameNot(String
name)</methodname></entry>
<entry><code>x.firstname != $1</code></entry>
</row>
<row>
<entry><literal>IsTrue</literal>,
<literal>True</literal></entry>
<entry><code>findByActiveIsTrue()</code></entry>
<entry><code>x.active = true</code></entry>
</row>
<row>
<entry><literal>IsFalse</literal>,
<literal>False</literal></entry>
<entry><code>findByActiveIsFalse()</code></entry>
<entry><code>x.active = false</code></entry>
</row>
</tbody>
</tgroup>
</table></para>
</section>
</chapter>

View File

@@ -1,151 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter version="5.0" xml:id="samples" xmlns="http://docbook.org/ns/docbook"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:xi="http://www.w3.org/2001/XInclude"
xmlns:ns5="http://www.w3.org/2000/svg"
xmlns:ns4="http://www.w3.org/1999/xhtml"
xmlns:ns3="http://www.w3.org/1998/Math/MathML"
xmlns:ns="http://docbook.org/ns/docbook">
<title>Sample Applications</title>
<para><note>
Sample applications are now maintained in the
<ulink
url="https://github.com/SpringSource/spring-gemfire-examples">Spring
Data GemFire Examples</ulink>
repository.
</note></para>
<para>The Spring Data GemFire project also includes one sample application.
Named "Hello World", the sample demonstrates how to configure and use
GemFire inside a Spring application. At runtime, the sample offers a
<emphasis>shell</emphasis> to the user allowing him to run various commands
against the grid. It provides an excellent starting point for users
unfamiliar with the essential components or the Spring and GemFire
concepts.</para>
<para>The sample is bundled with the distribution and is Maven-based. One
can easily import them into any Maven-aware IDE (such as SpringSource <ulink
url="http://www.springsource.com/products/sts">Tool Suite</ulink>) or run
them from the command-line.</para>
<section id="samples:hello-world">
<title>Hello World</title>
<para>The Hello World sample demonstrates the core functionality of the
Spring GemFire project. It bootstraps GemFire, configures it, executes
arbitrary commands against it and shuts it down when the application
exits. Multiple instances can be started at the same time as they will
work with each other sharing data without any user intervention.</para>
<note>
<title>Running under Linux</title>
<para>If you experience networking problems when starting GemFire or the
samples, try adding the following system property
<literal>java.net.preferIPv4Stack=true</literal> to the command line
(insert <literal>-Djava.net.preferIPv4Stack=true</literal>). For an
alternative (global) fix especially on Ubuntu see this <ulink
url="https://jira.springsource.org/browse/SGF-28">link</ulink></para>
</note>
<section id="samples:hello-world:start-stop">
<title>Starting and stopping the sample</title>
<para>Hello World is designed as a stand-alone java application. It
features a <classname>Main</classname> class which can be started either
from your IDE of choice (in Eclipse/STS through <literal>Run As/Java
Application</literal>) or from the command line through Maven using
<literal>mvn exec:java</literal>. One can also use
<literal>java</literal> directly on the resulting artifact if the
classpath is properly set.</para>
<para>To stop the sample, simply type <literal>exit</literal> at the
command line or press <literal>Ctrl+C</literal> to stop the VM and
shutdown the Spring container.</para>
</section>
<section id="samples:hello-world:run">
<title>Using the sample</title>
<para>Once started, the sample will create a shared data grid and allow
the user to issue commands against it. The output will likely look as
follows:</para>
<programlisting>INFO: Created GemFire Cache [Spring GemFire World] v. X.Y.Z
INFO: Created new cache region [myWorld]
INFO: Member xxxxxx:50694/51611 connecting to region [myWorld]
Hello World!
Want to interact with the world ? ...
Supported commands are:
get &lt;key&gt; - retrieves an entry (by key) from the grid
put &lt;key&gt; &lt;value&gt; - puts a new entry into the grid
remove &lt;key&gt; - removes an entry (by key) from the grid
...</programlisting>
<para>For example to add new items to the grid one can use:</para>
<programlisting>-&gt; <emphasis role="bold">put 1 unu</emphasis>
INFO: Added [1=unu] to the cache
null
-&gt; <emphasis role="bold">put 1 one</emphasis>
INFO: Updated [1] from [unu] to [one]
unu
-&gt; <emphasis role="bold">size</emphasis>
1
-&gt; <emphasis role="bold">put 2 two</emphasis>
INFO: Added [2=two] to the cache
null
-&gt; <emphasis role="bold">size</emphasis>
2</programlisting>
<para>Multiple instances can be created at the same time. Once started,
the new VMs automatically see the existing region and its
information:</para>
<programlisting>INFO: Connected to Distributed System ['Spring GemFire World'=xxxx:56218/49320@yyyyy]
Hello World!
...
-&gt; <emphasis role="bold">size</emphasis>
2
-&gt; <emphasis role="bold">map</emphasis>
[2=two] [1=one]
-&gt; <emphasis role="bold">query length = 3</emphasis>
[one, two]
</programlisting>
<para>Experiment with the example, start (and stop) as many instances as
you want, run various commands in one instance and see how the others
react. To preserve data, at least one instance needs to be alive all
times - if all instances are shutdown, the grid data is completely
destroyed (in this example - to preserve data between runs, see the
GemFire documentations).</para>
</section>
<section id="samples:hello-world:explained">
<title>Hello World Sample Explained</title>
<para>Hello World uses both Spring XML and annotations for its
configuration. The initial boostrapping configuration is
<literal>app-context.xml</literal> which includes the cache
configuration, defined under <literal>cache-context.xml</literal> file
and performs classpath <ulink
url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-classpath-scanning">scanning</ulink>
for Spring <ulink
url="http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-factorybeans-annotations">components</ulink>.
The cache configuration defines the GemFire cache, region and for
illustrative purposes a simple cache listener that acts as a
logger.</para>
<para>The main <emphasis>beans</emphasis> are
<literal>HelloWorld</literal> and <literal>CommandProcessor</literal>
which rely on the <classname>GemfireTemplate</classname> to interact
with the distributed fabric. Both classes use annotations to define
their dependency and life-cycle callbacks.</para>
</section>
</section>
</chapter>

View File

@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<chapter xmlns="http://docbook.org/ns/docbook" version="5.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xi="http://www.w3.org/2001/XInclude" xml:id="serialization">
<title>Working with GemFire Serialization</title>
<para>To improve overall performance of the data grid, GemFire supports a
dedicated serialization protocol (PDX) that is both faster and offers more compact
results over the standard Java serialization and works transparently across
various language <ulink
url="http://community.gemstone.com/display/gemfire/Interoperability">platforms</ulink>
(such as <ulink
url="http://community.gemstone.com/display/gemfire/Serialization+in+Java">Java</ulink>,
<ulink
url="http://community.gemstone.com/display/gemfire/Serialization+in+.NET">.NET</ulink>
and C++). This chapter discusses the various ways in which Spring Data GemFire simplifies
and improves GemFire custom serialization in Java.</para>
<section id="serialization:wiring">
<title>Wiring deserialized instances</title>
<para>It is fairly common for serialized objects to have transient data.
Transient data is often dependent on the node or environment where it
lives at a certain point in time, for example a DataSource. Serializing
such information is useless (and potentially even dangerous) since it is
local to a certain VM/machine. For such cases, Spring Data GemFire offers a special <ulink
url="https://www.vmware.com/support/developer/vfabric-gemfire/700-api/com/gemstone/gemfire/Instantiator.html"><classname>Instantiator</classname></ulink>
that performs wiring for each new instance created by GemFire during
deserialization.</para>
<para>Through such a mechanism, one can rely on the Spring container to
inject (and manage) certain dependencies making it easy to split transient
from persistent data and have <emphasis>rich domain objects</emphasis> in
a transparent manner (Spring users might find this approach similar to
that of <ulink
url="http://static.springsource.org/spring/docs/current/spring-framework-reference/html/aop.html#aop-atconfigurable"><literal>@Configurable</literal></ulink>).
The <classname>WiringInstantiator</classname> works just like
<classname>WiringDeclarableSupport</classname>, trying to first locate a
bean definition as a wiring template and following to autowiring
otherwise. Please refer to the previous section (<xref
linkend="apis:declarable"/>) for more details on wiring
functionality.</para>
<para>To use this <classname>Instantiator</classname>, simply declare it
as a usual bean:</para>
<programlisting language="xml">&lt;bean id="instantiator" class="org.springframework.data.gemfire.serialization.WiringInstantiator"&gt;
&lt;!-- DataSerializable type --&gt;
&lt;constructor-arg&gt;org.pkg.SomeDataSerializableClass&lt;/constructor-arg&gt;
&lt;!-- type id --&gt;
&lt;constructor-arg&gt;95&lt;/constructor-arg&gt;
&lt;/bean&gt;</programlisting>
<para>During the container startup, once it is being initialized, the
<literal>instantiator</literal> will, by default, register itself with the
GemFire system and perform wiring on all instances of
<classname>SomeDataSerializableClass</classname> created by GemFire during
deserialization.</para>
</section>
<section id="serialization:instance-generator">
<title>Auto-generating custom <classname>Instantiator</classname>s</title>
<para>For data intensive applications, a large number of instances might
be created on each machine as data flows in. Out of the box, GemFire uses
reflection to create new types but for some scenarios, this might prove to
be expensive. As always, it is good to perform profiling to quantify
whether this is the case or not. For such cases, Spring Data GemFire allows the automatic
generation of <classname>Instatiator</classname> classes which instantiate
a new type (using the default constructor) without the use of
reflection:</para>
<programlisting language="xml">&lt;bean id="instantiator-factory" class="org.springframework.data.gemfire.serialization.InstantiatorFactoryBean"&gt;
&lt;property name="customTypes"&gt;
&lt;map&gt;
&lt;entry key="org.pkg.CustomTypeA" value="1025"/&gt;
&lt;entry key="org.pkg.CustomTypeB" value="1026"/&gt;
&lt;/map&gt;
&lt;/property&gt;
&lt;/bean&gt;</programlisting>
<para>The definition above, automatically generated two
<classname>Instantiator</classname>s for two classes, namely
<classname>CustomTypeA</classname> and <classname>CustomTypeB</classname>
and registers them with GemFire, under user id <literal>1025</literal> and
<literal>1026</literal>. The two instantiators avoid the use of reflection
and create the instances directly through Java code.</para>
</section>
</chapter>