SGF-768 - Replace all direct URL/links with Asciidoc variables.
Replace all product names with Asciidoc variables. Replace all product versions with Asciidoc variables.
This commit is contained in:
@@ -1,22 +1,22 @@
|
||||
[[function-annotations]]
|
||||
= Annotation Support for Function Execution
|
||||
|
||||
Spring Data for Pivotal GemFire includes annotation support to simplify working with Pivotal GemFire
|
||||
http://geode.apache.org/docs/guide/11/developing/function_exec/chapter_overview.html[function execution].
|
||||
Under the hood, the Pivotal GemFire API provides classes to implement and register Pivotal GemFire
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/Function.html[functions]
|
||||
that are deployed on Pivotal GemFire servers, which may then be invoked by other peer member applications
|
||||
Spring Data for {data-store-name} includes annotation support to simplify working with {data-store-name}
|
||||
{x-data-store-docs}/developing/function_exec/chapter_overview.html[function execution].
|
||||
Under the hood, the {data-store-name} API provides classes to implement and register {data-store-name}
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/Function.html[functions]
|
||||
that are deployed on {data-store-name} servers, which may then be invoked by other peer member applications
|
||||
or remotely from cache clients.
|
||||
|
||||
Functions can execute in parallel, distributed among multiple Pivotal GemFire servers in the cluster, aggregating results
|
||||
Functions can execute in parallel, distributed among multiple {data-store-name} servers in the cluster, aggregating results
|
||||
with the map-reduce pattern that are sent back to the caller. Functions can also be targeted to run on a single server
|
||||
or region. The Pivotal GemFire API supports remote execution of functions targeted by using various predefined scopes:
|
||||
or region. The {data-store-name} API supports remote execution of functions targeted by using various predefined scopes:
|
||||
on region, on members (in groups), on servers, and others. The implementation and execution of remote functions,
|
||||
as with any RPC protocol, requires some boilerplate code.
|
||||
|
||||
Spring Data for Pivotal GemFire, true to Spring's core value proposition, aims to hide the mechanics of remote function execution
|
||||
and let you focus on core POJO programming and business logic. To this end, Spring Data for Pivotal GemFire introduces
|
||||
annotations to declaratively register the public methods of a POJO class as Pivotal GemFire functions along with the ability to
|
||||
Spring Data for {data-store-name}, true to Spring's core value proposition, aims to hide the mechanics of remote function execution
|
||||
and let you focus on core POJO programming and business logic. To this end, Spring Data for {data-store-name} introduces
|
||||
annotations to declaratively register the public methods of a POJO class as {data-store-name} functions along with the ability to
|
||||
invoke registered functions (including remotely) by using annotated interfaces.
|
||||
|
||||
== Implementation Versus Execution
|
||||
@@ -24,26 +24,26 @@ invoke registered functions (including remotely) by using annotated interfaces.
|
||||
There are two separate concerns to address implementation and execution.
|
||||
|
||||
The first is function implementation (server-side), which must interact with the
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionContext.html[`FunctionContext`]
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/FunctionContext.html[`FunctionContext`]
|
||||
to access the invocation arguments,
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/ResultSender.html[`ResultsSender`],
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/ResultSender.html[`ResultsSender`],
|
||||
and other execution context information. The function implementation typically accesses the cache and regions
|
||||
and is registered with the
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionService.html[`FunctionService`]
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/FunctionService.html[`FunctionService`]
|
||||
under a unique ID.
|
||||
|
||||
A cache client application invoking a function does not depend on the implementation. To invoke a function,
|
||||
the application instantiates an
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/Execution.html[`Execution`]
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/Execution.html[`Execution`]
|
||||
providing the function ID, invocation arguments, and the function target, which defines its scope:
|
||||
region, server, servers, member, or members. If the function produces a result, the invoker uses a
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/ResultCollector.html[`ResultCollector`]
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/ResultCollector.html[`ResultCollector`]
|
||||
to aggregate and acquire the execution results. In certain cases, a custom `ResultCollector` implementation
|
||||
is required and may be registered with the `Execution`.
|
||||
|
||||
NOTE: 'Client' and 'Server' are used here in the context of function execution, which may have a different meaning
|
||||
than client and server in Pivotal GemFire's client-server topology. While it is common for an application using a `ClientCache`
|
||||
to invoke a function on one or more Pivotal GemFire servers in a cluster, it is also possible to execute functions
|
||||
than client and server in {data-store-name}'s client-server topology. While it is common for an application using a `ClientCache`
|
||||
to invoke a function on one or more {data-store-name} servers in a cluster, it is also possible to execute functions
|
||||
in a peer-to-peer (P2P) configuration, where the application is a member of the cluster hosting a peer `Cache`.
|
||||
Keep in mind that a peer member cache application is subject to all the constraints of being a peer member
|
||||
of the cluster.
|
||||
@@ -51,7 +51,7 @@ of the cluster.
|
||||
[[function-implementation]]
|
||||
== Implementing a Function
|
||||
|
||||
Using Pivotal GemFire APIs, the `FunctionContext` provides a runtime invocation context that includes the client's
|
||||
Using {data-store-name} APIs, the `FunctionContext` provides a runtime invocation context that includes the client's
|
||||
calling arguments and a `ResultSender` implementation to send results back to the client. Additionally,
|
||||
if the function is executed on a region, the `FunctionContext` is actually an instance of `RegionFunctionContext`,
|
||||
which provides additional information, such as the target region on which the function was invoked,
|
||||
@@ -98,7 +98,7 @@ or the `ResultSender` if you need to control how the results are returned to the
|
||||
=== Annotations for Function Implementation
|
||||
|
||||
The following example shows how SDG's function annotations are used to expose POJO methods
|
||||
as Pivotal GemFire functions:
|
||||
as {data-store-name} functions:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -117,7 +117,7 @@ public class ApplicationFunctions {
|
||||
}
|
||||
----
|
||||
|
||||
Note that the class itself must be registered as a Spring bean and each Pivotal GemFire Function is annotated
|
||||
Note that the class itself must be registered as a Spring bean and each {data-store-name} Function is annotated
|
||||
with `@GemfireFunction`. In the preceding example, Spring's `@Component` annotation was used, but you can register the bean
|
||||
by using any method supported by Spring (such as XML configuration or with a Java configuration class when using Spring Boot).
|
||||
This lets the Spring container create an instance of this class and wrap it in a
|
||||
@@ -126,15 +126,15 @@ Spring creates a wrapper instance for each method annotated with `@GemfireFuncti
|
||||
the same target object instance to invoke the corresponding method.
|
||||
|
||||
TIP: The fact that the POJO Function class is a Spring bean may offer other benefits, since it shares
|
||||
the `ApplicationContext` with Pivotal GemFire components, such as the cache and regions. These may be injected into the class
|
||||
the `ApplicationContext` with {data-store-name} components, such as the cache and regions. These may be injected into the class
|
||||
if necessary.
|
||||
|
||||
Spring creates the wrapper class and registers the functions with Pivotal GemFire's function service. The function ID used
|
||||
Spring creates the wrapper class and registers the functions with {data-store-name}'s function service. The function ID used
|
||||
to register each function must be unique. By using convention, it defaults to the simple (unqualified) method name.
|
||||
The name can be explicitly defined by using the `id` attribute of the `@GemfireFunction` annotation.
|
||||
The `@GemfireFunction` annotation also provides other configuration attributes, `HA` and `optimizedForWrite`,
|
||||
which correspond to properties defined by Pivotal GemFire's
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/Function.html[`Function`] interface.
|
||||
which correspond to properties defined by {data-store-name}'s
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/Function.html[`Function`] interface.
|
||||
If the method's return type is `void`, then the `hasResult` property is automatically set to `false`.
|
||||
Otherwise, if the method returns a value, the `hasResult` attributes is set to `true`.
|
||||
|
||||
@@ -142,7 +142,7 @@ Even for `void` return types, the annotation's `hasResult` attribute can be set
|
||||
as shown in the `functionWithContext` method show previously. Presumably, the intention is to use the `ResultSender` directly
|
||||
to send results to the caller.
|
||||
|
||||
The `PojoFunctionWrapper` implements Pivotal GemFire's `Function` interface, binds method parameters, and invokes the target method
|
||||
The `PojoFunctionWrapper` implements {data-store-name}'s `Function` interface, binds method parameters, and invokes the target method
|
||||
in its `execute()` method. It also sends the method's return value by using the `ResultSender`.
|
||||
|
||||
=== Batching Results
|
||||
@@ -179,11 +179,11 @@ class ApplicationConfiguration { .. }
|
||||
== Executing a Function
|
||||
|
||||
A process that invokes a remote function needs to provide the function's ID, calling arguments, the execution target
|
||||
(`onRegion`, `onServers`, `onServer`, `onMember`, or `onMembers`) and (optionally) a filter set. By using Spring Data for Pivotal GemFire,
|
||||
(`onRegion`, `onServers`, `onServer`, `onMember`, or `onMembers`) and (optionally) a filter set. By using Spring Data for {data-store-name},
|
||||
all you need do is define an interface supported by annotations. Spring creates a dynamic proxy
|
||||
for the interface, which uses the `FunctionService` to create an `Execution`, invoke the `Execution`, and (if necessary) coerce
|
||||
the results to the defined return type. This technique is similar to the way
|
||||
Spring Data for Pivotal GemFire's repository extension works. Thus, some of the configuration and concepts should be familiar.
|
||||
Spring Data for {data-store-name}'s repository extension works. 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.
|
||||
|
||||
@@ -191,11 +191,11 @@ defined in the interface.
|
||||
|
||||
To support client-side Function execution, the following SDG Function annotations are provided: `@OnRegion`,
|
||||
`@OnServer`, `@OnServers`, `@OnMember`, and `@OnMembers`. These annotations correspond to the `Execution` implementations
|
||||
provided by Pivotal GemFire's
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionService.html[`FunctionService`].
|
||||
provided by {data-store-name}'s
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/FunctionService.html[`FunctionService`].
|
||||
Each annotation exposes the appropriate attributes. These annotations also provide an optional
|
||||
`resultCollector` attribute whose value is the name of a Spring bean implementing the
|
||||
http://geode.apache.org/releases/latest/javadoc/org/apache/geode/cache/execute/ResultCollector.html[`ResultCollector`]
|
||||
{x-data-store-javadoc}/org/apache/geode/cache/execute/ResultCollector.html[`ResultCollector`]
|
||||
to use for the execution.
|
||||
|
||||
CAUTION: The proxy interface binds all declared methods to the same execution configuration. Although it is expected
|
||||
@@ -283,12 +283,12 @@ The filter argument is optional. The remaining arguments are a variable argument
|
||||
[[function-execution-pdx]]
|
||||
== Function Execution with PDX
|
||||
|
||||
When using Spring Data for Pivotal GemFire's function annotation support combined with Pivotal GemFire's
|
||||
http://geode.apache.org/docs/guide/11/developing/data_serialization/gemfire_pdx_serialization.html[PDX Serialization],
|
||||
When using Spring Data for {data-store-name}'s function annotation support combined with {data-store-name}'s
|
||||
{x-data-store-docs}/developing/data_serialization/gemfire_pdx_serialization.html[PDX Serialization],
|
||||
there are a few logistical things to keep in mind.
|
||||
|
||||
As explained earlier in this section, and by way of example, you should typically define Pivotal GemFire functions by using POJO classes
|
||||
annotated with Spring Data for Pivotal GemFire
|
||||
As explained earlier in this section, and by way of example, you should typically define {data-store-name} functions by using POJO classes
|
||||
annotated with Spring Data for {data-store-name}
|
||||
http://docs.spring.io/spring-data-gemfire/docs/current/api/org/springframework/data/gemfire/function/annotation/package-summary.html[function annotations],
|
||||
as follows:
|
||||
|
||||
@@ -329,7 +329,7 @@ public enum OrderSource {
|
||||
}
|
||||
----
|
||||
|
||||
Of course, you can define a function `Execution` interface to call the 'process' Pivotal GemFire server function, as follows:
|
||||
Of course, you can define a function `Execution` interface to call the 'process' {data-store-name} server function, as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -344,16 +344,16 @@ Clearly, this `process(..)` `Order` Function is being called from a client-side
|
||||
The same is true when invoking peer-to-peer member functions (such as `@OnMember(s)) between peers in the cluster.
|
||||
Any form of `distribution` requires the data transmitted between client and server (or peers) to be serialized.
|
||||
|
||||
Now, if you have configured Pivotal GemFire to use PDX for serialization (instead of Java serialization, for instance)
|
||||
Now, if you have configured {data-store-name} to use PDX for serialization (instead of Java serialization, for instance)
|
||||
you can also set the `pdx-read-serialized` attribute to `true` in your configuration
|
||||
of the Pivotal GemFire server(s), as follows:
|
||||
of the {data-store-name} server(s), as follows:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
<gfe:cache ... pdx-read-serialized="true"/>
|
||||
----
|
||||
|
||||
Alternatively, you can set the `pdx-read-serialized` attribute to `true` for a Pivotal GemFire cache client application, as follows:
|
||||
Alternatively, you can set the `pdx-read-serialized` attribute to `true` for a {data-store-name} cache client application, as follows:
|
||||
|
||||
[source,xml]
|
||||
----
|
||||
@@ -363,24 +363,24 @@ Alternatively, you can set the `pdx-read-serialized` attribute to `true` for a P
|
||||
Doing so causes all values read from the cache (that is, regions) as well as information passed between client and servers
|
||||
(or peers) to remain in serialized form, including, but not limited to, function arguments.
|
||||
|
||||
Pivotal GemFire serializes only application domain object types that you have specifically configured (registered)
|
||||
either by using Pivotal GemFire's
|
||||
http://gemfire-90-javadocs.docs.pivotal.io/org/apache/geode/pdx/ReflectionBasedAutoSerializer.html[`ReflectionBasedAutoSerializer`],
|
||||
or specifically (and recommended) by using a "`custom`" Pivotal GemFire
|
||||
http://gemfire-90-javadocs.docs.pivotal.io/org/apache/geode/pdx/PdxSerializer.html[`PdxSerializer`]. If you use
|
||||
Spring Data for Pivotal GemFire's repository extension to Spring Data Common's repository abstraction and infrastructure,
|
||||
you might even want to consider using Spring Data for Pivotal GemFire's
|
||||
{data-store-name} serializes only application domain object types that you have specifically configured (registered)
|
||||
either by using {data-store-name}'s
|
||||
{x-data-store-javadoc}/org/apache/geode/pdx/ReflectionBasedAutoSerializer.html[`ReflectionBasedAutoSerializer`],
|
||||
or specifically (and recommended) by using a "`custom`" {data-store-name}
|
||||
{x-data-store-javadoc}/org/apache/geode/pdx/PdxSerializer.html[`PdxSerializer`]. If you use
|
||||
Spring Data for {data-store-name}'s repository extension to Spring Data Common's repository abstraction and infrastructure,
|
||||
you might even want to consider using Spring Data for {data-store-name}'s
|
||||
http://docs.spring.io/spring-data-gemfire/docs/current/api/org/springframework/data/gemfire/mapping/MappingPdxSerializer.html[`MappingPdxSerializer`],
|
||||
which uses an entity's mapping meta-data to determine data from the application domain object that are serialized
|
||||
to the PDX instance.
|
||||
|
||||
What is less than apparent, though, is that Pivotal GemFire automatically handles Java `Enum` types regardless of whether they are
|
||||
What is less than apparent, though, is that {data-store-name} automatically handles Java `Enum` types regardless of whether they are
|
||||
explicitly configured (that is, registered with a `ReflectionBasedAutoSerializer` using a regex pattern
|
||||
and the `classes` parameter or are handled by a "`custom`" Pivotal GemFire `PdxSerializer`), despite the fact that Java enumerations
|
||||
and the `classes` parameter or are handled by a "`custom`" {data-store-name} `PdxSerializer`), despite the fact that Java enumerations
|
||||
implement `java.io.Serializable`.
|
||||
|
||||
So, when you set `pdx-read-serialized` to `true` on Pivotal GemFire servers where the Pivotal GemFire functions
|
||||
(including Spring Data for Pivotal GemFire function-annotated POJO classes) are registered, then you
|
||||
So, when you set `pdx-read-serialized` to `true` on {data-store-name} servers where the {data-store-name} functions
|
||||
(including Spring Data for {data-store-name} function-annotated POJO classes) are registered, then you
|
||||
may encounter surprising behavior when invoking the function `Execution`.
|
||||
|
||||
You might pass the following arguments when invoking the function:
|
||||
@@ -390,7 +390,7 @@ You might pass the following arguments when invoking the function:
|
||||
orderProcessingFunctions.process(new Order(123, customer, Calendar.getInstance(), items), OrderSource.ONLINE, 400);
|
||||
----
|
||||
|
||||
However, the Pivotal GemFire function on the server gets the following:
|
||||
However, the {data-store-name} function on the server gets the following:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -398,19 +398,19 @@ process(regionData, order:PdxInstance, :PdxInstanceEnum, 400);
|
||||
----
|
||||
|
||||
The `Order` and `OrderSource` have been passed to the function as
|
||||
http://gemfire-90-javadocs.docs.pivotal.io/org/apache/geode/pdx/PdxInstance.html[PDX instances].
|
||||
{x-data-store-javadoc}/org/apache/geode/pdx/PdxInstance.html[PDX instances].
|
||||
Again, this all happens because `pdx-read-serialized` is set to `true`, which may be necessary in cases where
|
||||
the Pivotal GemFire servers interact with multiple different clients (for example, a combination of Java clients and native clients, such as C++, C#, and others).
|
||||
the {data-store-name} servers interact with multiple different clients (for example, a combination of Java clients and native clients, such as C++, C#, and others).
|
||||
|
||||
This flies in the face of Spring Data for Pivotal GemFire's strongly-typed function-annotated POJO class method signatures,
|
||||
This flies in the face of Spring Data for {data-store-name}'s strongly-typed function-annotated POJO class method signatures,
|
||||
as you should reasonably expect application domain object types, not PDX serialized instances.
|
||||
|
||||
Consequently, Spring Data for Pivotal GemFire includes enhanced function support to automatically convert method arguments
|
||||
Consequently, Spring Data for {data-store-name} includes enhanced function support to automatically convert method arguments
|
||||
type PDX to the desired application domain object types defined by the function method's
|
||||
parameter types.
|
||||
|
||||
However, this also requires you to explicitly register a Pivotal GemFire `PdxSerializer` on the Pivotal GemFire Servers
|
||||
where Spring Data for Pivotal GemFire function-annotated POJOs are registered and used, as the following example shows:
|
||||
However, this also requires you to explicitly register a {data-store-name} `PdxSerializer` on the {data-store-name} Servers
|
||||
where Spring Data for {data-store-name} function-annotated POJOs are registered and used, as the following example shows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -419,13 +419,13 @@ where Spring Data for Pivotal GemFire function-annotated POJOs are registered an
|
||||
<gfe:cache ... pdx-serializer-ref="customPdxSerializeer" pdx-read-serialized="true"/>
|
||||
----
|
||||
|
||||
Alternatively, you can use Pivotal GemFire's
|
||||
http://gemfire-90-javadocs.docs.pivotal.io/org/apache/geode/pdx/ReflectionBasedAutoSerializer.html[`ReflectionBasedAutoSerializer`]
|
||||
Alternatively, you can use {data-store-name}'s
|
||||
{x-data-store-javadoc}/org/apache/geode/pdx/ReflectionBasedAutoSerializer.html[`ReflectionBasedAutoSerializer`]
|
||||
for convenience. Of course, we recommend that, where possible, you use a custom `PdxSerializer` to maintain
|
||||
finer-grained control over your serialization strategy.
|
||||
|
||||
Finally, Spring Data for Pivotal GemFire is careful not to convert your function arguments if you treat your function arguments
|
||||
generically or as one of Pivotal GemFire's PDX types, as follows:
|
||||
Finally, Spring Data for {data-store-name} is careful not to convert your function arguments if you treat your function arguments
|
||||
generically or as one of {data-store-name}'s PDX types, as follows:
|
||||
|
||||
[source,java]
|
||||
----
|
||||
@@ -435,9 +435,9 @@ public Object genericFunction(String value, Object domainObject, PdxInstanceEnum
|
||||
}
|
||||
----
|
||||
|
||||
Spring Data for Pivotal GemFire converts PDX type data to the corresponding application domain types if and only if
|
||||
Spring Data for {data-store-name} converts PDX type data to the corresponding application domain types if and only if
|
||||
the corresponding application domain types are on the classpath and the function-annotated POJO method expects it.
|
||||
|
||||
For a good example of custom, composed application-specific Pivotal GemFire `PdxSerializers` as well as appropriate
|
||||
POJO function parameter type handling based on the method signatures, see Spring Data for Pivotal GemFire's
|
||||
For a good example of custom, composed application-specific {data-store-name} `PdxSerializers` as well as appropriate
|
||||
POJO function parameter type handling based on the method signatures, see Spring Data for {data-store-name}'s
|
||||
https://github.com/spring-projects/spring-data-gemfire/blob/2.0.0.M2/src/test/java/org/springframework/data/gemfire/function/ClientCacheFunctionExecutionWithPdxIntegrationTest.java[`ClientCacheFunctionExecutionWithPdxIntegrationTest`] class.
|
||||
|
||||
Reference in New Issue
Block a user