This is an automated email from the ASF dual-hosted git repository.
kmiller pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new 5e8aaf4 GEODE-2817 Document user-defined function authorization
levels (#855)
5e8aaf4 is described below
commit 5e8aaf423e603f69464f999fbce587b1894ec01c
Author: Karen Miller <[email protected]>
AuthorDate: Thu Oct 5 13:00:40 2017 -0700
GEODE-2817 Document user-defined function authorization levels (#855)
* GEODE-2817 Document user-defined function authorization levels
* GEODE-2817 Address review comments and update code example
---
.../function_exec/function_execution.html.md.erb | 33 +++++++++++-----------
.../how_function_execution_works.html.md.erb | 15 ++++++++--
.../implementing_authorization.html.md.erb | 17 +++++++++--
3 files changed, 44 insertions(+), 21 deletions(-)
diff --git a/geode-docs/developing/function_exec/function_execution.html.md.erb
b/geode-docs/developing/function_exec/function_execution.html.md.erb
index a7ce138..83ba8da 100644
--- a/geode-docs/developing/function_exec/function_execution.html.md.erb
+++ b/geode-docs/developing/function_exec/function_execution.html.md.erb
@@ -29,24 +29,27 @@ Main tasks:
## <a id="function_execution__section_7D43B0C628D54F579D5C434D3DF69B3C"
class="no-quick-link"></a>Write the Function Code
-To write the function code, you implement the `Function` interface or extend
the `FunctionAdapter` class. Both are in the `org.apache.geode.cache.execute`
package. The adapter class provides some default implementations for methods,
which you can override.
+To write the function code, you implement the `Function` interface in the
`org.apache.geode.cache.execute` package.
Code the methods you need for the function. These steps do not have to be done
in this order.
-1. Code `getId` to return a unique name for your function. You can use this
name to access the function through the `FunctionService` API.
-2. For high availability:
+- Implement `getId` to return a unique name for your function. You can use
this name to access the function through the `FunctionService` API.
+- For high availability:
1. Code `isHa` to return true to indicate to <%=vars.product_name%> that
it can re-execute your function after one or more members fails
2. Code your function to return a result
3. Code `hasResult` to return true
-3. Code `hasResult` to return true if your function returns results to be
processed and false if your function does not return any data - the fire and
forget function. `FunctionAdapter` `hasResult` returns true by default.
-4. If the function will be executed on a region, code `optimizeForWrite` to
return false if your function only reads from the cache, and true if your
function updates the cache. The method only works if, when you are running the
function, the `Execution` object is obtained through a `FunctionService`
`onRegion` call. `FunctionAdapter` `optimizeForWrite` returns false by default.
-5. Code the `execute` method to perform the work of the function.
+- Code `hasResult` to return true if your function returns results to be
processed and false if your function does not return any data - the fire and
forget function.
+- If the function will be executed on a region, implement `optimizeForWrite`
to return false if your function only reads from the cache, and true if your
function updates the cache. The method only works if, when you are running the
function, the `Execution` object is obtained through a `FunctionService`
`onRegion` call. `optimizeForWrite` returns false by default.
+- If the function should be run with an authorization level other than
+the default of `DATA:WRITE`,
+implement an override of the `Function.getRequiredPermissions()` method.
+See [Authorization of Function
Execution](../../managing/security/implementing_authorization.html#AuthorizeFcnExecution)
for details on this method.
+- Code the `execute` method to perform the work of the function.
1. Make `execute` thread safe to accommodate simultaneous invocations.
2. For high availability, code `execute` to accommodate multiple
identical calls to the function. Use the `RegionFunctionContext`
`isPossibleDuplicate` to determine whether the call may be a high-availability
re-execution. This boolean is set to true on execution failure and is false
otherwise.
**Note:**
The `isPossibleDuplicate` boolean can be set following a failure from
another member’s execution of the function, so it only indicates that the
execution might be a repeat run in the current member.
-
3. Use the function context to get information about the execution and
the data:
- The context holds the function ID, the `ResultSender` object for
passing results back to the originator, and function arguments provided by the
member where the function originated.
- The context provided to the function is the `FunctionContext`,
which is automatically extended to `RegionFunctionContext` if you get the
`Execution` object through a `FunctionService` `onRegion` call.
@@ -54,34 +57,32 @@ Code the methods you need for the function. These steps do
not have to be done i
- For partitioned regions, the `PartitionRegionHelper` provides
access to additional information and data for the region. For single regions,
use `getLocalDataForContext`. For colocated regions, use
`getLocalColocatedRegions`.
**Note:**
When you use `PartitionRegionHelper.getLocalDataForContext`,
`putIfAbsent` may not return expected results if you are working on local data
set instead of the region.
-
4. To propagate an error condition or exception back to the caller of the
function, throw a FunctionException from the `execute` method.
<%=vars.product_name%> transmits the exception back to the caller as if it had
been thrown on the calling side. See the Java API documentation for
[FunctionException](/releases/latest/javadoc/org/apache/geode/cache/execute/FunctionException.html)
for more information.
Example function code:
``` pre
-package quickstart;
-
import java.io.Serializable;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
-import org.apache.geode.cache.execute.FunctionAdapter;
+import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.FunctionContext;
+import org.apache.geode.cache.execute.FunctionException;
import org.apache.geode.cache.execute.RegionFunctionContext;
import org.apache.geode.cache.partition.PartitionRegionHelper;
-public class MultiGetFunction extends FunctionAdapter {
+public class MultiGetFunction implements Function {
- public void execute(FunctionContext fc) {
+ public void execute(FunctionContext fc) {
if(! (fc instanceof RegionFunctionContext)){
- throw new FunctionException("This is a data aware function, and has
-to be called using FunctionService.onRegion.");
+ throw new FunctionException("This is a data aware function, and has
+ to be called using FunctionService.onRegion.");
}
RegionFunctionContext context = (RegionFunctionContext)fc;
Set keys = context.getFilter();
- Set keysTillSecondLast = new HashSet();
+ Set keysTillSecondLast = new HashSet();
int setSize = keys.size();
Iterator keysIterator = keys.iterator();
for(int i = 0; i < (setSize -1); i++)
diff --git
a/geode-docs/developing/function_exec/how_function_execution_works.html.md.erb
b/geode-docs/developing/function_exec/how_function_execution_works.html.md.erb
index ae80b01..58d113b 100644
---
a/geode-docs/developing/function_exec/how_function_execution_works.html.md.erb
+++
b/geode-docs/developing/function_exec/how_function_execution_works.html.md.erb
@@ -39,9 +39,18 @@ See the `org.apache.geode.cache.execute.FunctionService`
Java API documentation
The following things occur when executing a function:
-1. When you call the `execute` method on the `Execution` object,
<%=vars.product_name%> invokes the function on all members where it needs to
run. The locations are determined by the `FunctionService` `on*` method calls,
region configuration, and any filters.
-2. If the function has results, they are returned to the `addResult` method
call in a `ResultCollector` object.
-3. The originating member collects results using `ResultCollector.getResult`.
+1. For security-enabled clusters, prior to executing the function,
+a check is made to see that that caller is authorized to execute
+the function.
+The required permissions for authorization are provided by
+the function's `Function.getRequiredPermissions()` method.
+See [Authorization of Function
Execution](../../managing/security/implementing_authorization.html#AuthorizeFcnExecution)
for a discussion of this method.
+2. Given successful authorization,
+<%=vars.product_name%> invokes the function on all members where it
+needs to run. The locations are determined by the `FunctionService` `on*`
+method calls, region configuration, and any filters.
+3. If the function has results, they are returned to the `addResult` method
call in a `ResultCollector` object.
+4. The originating member collects results using `ResultCollector.getResult`.
## <a
id="how_function_execution_works__section_14FF9932C7134C5584A14246BB4D4FF6"
class="no-quick-link"></a>Highly Available Functions
diff --git
a/geode-docs/managing/security/implementing_authorization.html.md.erb
b/geode-docs/managing/security/implementing_authorization.html.md.erb
index eb7966a..aed78a7 100644
--- a/geode-docs/managing/security/implementing_authorization.html.md.erb
+++ b/geode-docs/managing/security/implementing_authorization.html.md.erb
@@ -93,7 +93,7 @@ a Client-Server interaction.
| Region.registerInterest(regex) | DATA:READ:RegionName |
| Region.unregisterInterest(key) | DATA:READ:RegionName:Key |
| Region.unregisterInterest(regex) | DATA:READ:RegionName |
-| execute function | determined by the function API |
+| execute function | Defaults to DATA:WRITE. Override
`Function.getRequiredPermissions` to change the permission. |
| clear region | DATA:WRITE:RegionName |
| Region.putAll | DATA:WRITE:RegionName |
| Region.clear | DATA:WRITE:RegionName |
@@ -143,7 +143,7 @@ This table classifies the permissions assigned for `gfsh`
operations.
| destroy index | CLUSTER:MANAGE:QUERY |
| destroy lucene index | CLUSTER:MANAGE:LUCENE |
| destroy region | DATA:MANAGE |
-| execute function | determined by the function API |
+| execute function | Defaults to DATA:WRITE. Override
`Function.getRequiredPermissions` to change the permission. |
| export cluster-configuration | CLUSTER:READ |
| export config | CLUSTER:READ |
| export data | CLUSTER:READ |
@@ -276,3 +276,16 @@ for details about this property.
- Define any extra resources that the implemented authorization algorithm
needs in order to make a decision.
+### <a id="AuthorizeFcnExecution" class="no-quick-link"></a>Authorization of
Function Execution
+
+By default, a function executed on servers requires that the
+entity invoking the function have `DATA:WRITE` permission on the
+region(s) involved.
+Since the default permission may not be appropriate for all functions,
+the permissions required may be altered.
+
+To implement a different set of permissions,
+override the `Function.getRequiredPermissions()` method
+in the function's class.
+The method should return a `Collection` of the permissions
+required of the entity that invokes an execution of the function.
--
To stop receiving notification emails like this one, please contact
['"[email protected]" <[email protected]>'].