DATAGEODE-122 - Refactor Function annotation configuration to be smarter in resolving Apache Geode objects on startup.
Renames OnMember, OnMembers, OnRegion, OnServer and OnServers *ExecutionBeanDefinitionBuilder classes to *FunctionExecutionBeanDefinitionBuilder.
This commit is contained in:
@@ -139,27 +139,22 @@ public class FunctionGemfireAdminTemplate extends AbstractGemfireAdminOperations
|
||||
execute(CreateIndexFunction.CREATE_INDEX_FUNCTION_ID, indexDefinition);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
<T> T execute(Function gemfireFunction, Object... arguments) {
|
||||
return newGemfireFunctionOperations().executeAndExtract(gemfireFunction, arguments);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
<T> T execute(String gemfireFunctionId, Object... arguments) {
|
||||
return newGemfireFunctionOperations().executeAndExtract(gemfireFunctionId, arguments);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected GemfireFunctionOperations newGemfireFunctionOperations() {
|
||||
return newGemfireFunctionOperations(getClientCache());
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
protected GemfireFunctionOperations newGemfireFunctionOperations(ClientCache clientCache) {
|
||||
return new GemfireOnServersFunctionTemplate(clientCache);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
boolean containsRegionInformation(Object results) {
|
||||
|
||||
return Optional.ofNullable(results)
|
||||
|
||||
@@ -27,7 +27,6 @@ class DefaultFunctionArgumentResolver implements FunctionArgumentResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.reflect.Method
|
||||
*/
|
||||
@Override
|
||||
@@ -37,28 +36,33 @@ class DefaultFunctionArgumentResolver implements FunctionArgumentResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.springframework.data.gemfire.function.FunctionArgumentResolver#resolveFunctionArguments(org.apache.geode.cache.execute.FunctionContext)
|
||||
*/
|
||||
@Override
|
||||
public Object[] resolveFunctionArguments(final FunctionContext functionContext) {
|
||||
return (isArray(functionContext.getArguments())) ? toObjectArray((Object[]) functionContext.getArguments())
|
||||
|
||||
return isArray(functionContext.getArguments())
|
||||
? toObjectArray((Object[]) functionContext.getArguments())
|
||||
: getArguments(functionContext);
|
||||
}
|
||||
|
||||
private boolean isArray(final Object value) {
|
||||
return (value != null && value.getClass().isArray());
|
||||
return value != null && value.getClass().isArray();
|
||||
}
|
||||
|
||||
private Object[] toObjectArray(final Object[] arguments) {
|
||||
|
||||
Object[] result = new Object[arguments.length];
|
||||
|
||||
System.arraycopy(arguments, 0, result, 0, arguments.length);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private Object[] getArguments(final FunctionContext context) {
|
||||
Object arguments = context.getArguments();
|
||||
return (arguments != null ? new Object[] { arguments } : EMPTY_ARRAY);
|
||||
}
|
||||
|
||||
Object arguments = context.getArguments();
|
||||
|
||||
return arguments != null ? new Object[] { arguments } : EMPTY_ARRAY;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ class FunctionContextInjectingArgumentResolver extends PdxFunctionArgumentResolv
|
||||
private final Method method;
|
||||
|
||||
public FunctionContextInjectingArgumentResolver(Method method) {
|
||||
|
||||
this.method = method;
|
||||
|
||||
int regionDataAnnotationParameterPosition = GemfireFunctionUtils.getAnnotationParameterPosition(
|
||||
@@ -76,11 +77,12 @@ class FunctionContextInjectingArgumentResolver extends PdxFunctionArgumentResolv
|
||||
|
||||
@Override
|
||||
public Method getFunctionAnnotatedMethod() {
|
||||
return method;
|
||||
return this.method;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object[] resolveFunctionArguments(FunctionContext functionContext) {
|
||||
|
||||
Object[] args = super.resolveFunctionArguments(functionContext);
|
||||
|
||||
if (functionContext instanceof RegionFunctionContext) {
|
||||
@@ -103,9 +105,9 @@ class FunctionContextInjectingArgumentResolver extends PdxFunctionArgumentResolv
|
||||
args = ArrayUtils.insert(args, resultSenderParameterPosition, functionContext.getResultSender());
|
||||
}
|
||||
|
||||
Assert.isTrue(args.length == method.getParameterTypes().length, String.format(
|
||||
"wrong number of arguments for method %s. Expected %d, but was %d", method.getName(),
|
||||
method.getParameterTypes().length, args.length));
|
||||
Assert.isTrue(args.length == this.method.getParameterTypes().length,
|
||||
String.format("Wrong number of arguments for method [%s]; Expected [%d], but was [%d]",
|
||||
this.method.getName(), this.method.getParameterTypes().length, args.length));
|
||||
|
||||
return args;
|
||||
}
|
||||
@@ -131,9 +133,6 @@ class FunctionContextInjectingArgumentResolver extends PdxFunctionArgumentResolv
|
||||
return region;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*/
|
||||
private static int getArgumentTypePosition(Method method, Class<?> requiredType) {
|
||||
int index = 0;
|
||||
int position = -1;
|
||||
@@ -152,5 +151,4 @@ class FunctionContextInjectingArgumentResolver extends PdxFunctionArgumentResolv
|
||||
|
||||
return position;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -39,18 +39,20 @@ class PdxFunctionArgumentResolver extends DefaultFunctionArgumentResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.apache.geode.cache.execute.FunctionContext
|
||||
*/
|
||||
@Override
|
||||
public Object[] resolveFunctionArguments(final FunctionContext functionContext) {
|
||||
|
||||
Object[] functionArguments = super.resolveFunctionArguments(functionContext);
|
||||
|
||||
if (isPdxSerializerConfigured()) {
|
||||
|
||||
int index = 0;
|
||||
|
||||
for (Object functionArgument : functionArguments) {
|
||||
if (functionArgument instanceof PdxInstance) {
|
||||
|
||||
String className = ((PdxInstance) functionArgument).getClassName();
|
||||
|
||||
if (isDeserializationNecessary(className)) {
|
||||
@@ -67,7 +69,6 @@ class PdxFunctionArgumentResolver extends DefaultFunctionArgumentResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.reflect.Method
|
||||
*/
|
||||
@Override
|
||||
@@ -77,7 +78,6 @@ class PdxFunctionArgumentResolver extends DefaultFunctionArgumentResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.apache.geode.cache.Cache#getPdxSerializer()
|
||||
* @see org.apache.geode.cache.CacheFactory#getAnyInstance()
|
||||
*/
|
||||
@@ -92,16 +92,15 @@ class PdxFunctionArgumentResolver extends DefaultFunctionArgumentResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadac)
|
||||
*
|
||||
* @see #isOnClasspath(String)
|
||||
* @see #functionAnnotatedMethodHasParameterOfType(String)
|
||||
*/
|
||||
boolean isDeserializationNecessary(final String className) {
|
||||
return (isOnClasspath(className) && functionAnnotatedMethodHasParameterOfType(className));
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see java.lang.Thread#currentThread()
|
||||
* @see java.lang.Thread#getContextClassLoader()
|
||||
* @see org.springframework.util.ClassUtils#isPresent(String, ClassLoader)
|
||||
@@ -112,7 +111,6 @@ class PdxFunctionArgumentResolver extends DefaultFunctionArgumentResolver {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see #getFunctionAnnotatedMethod()
|
||||
* @see java.lang.reflect.Method#getParameterTypes()
|
||||
*/
|
||||
@@ -125,5 +123,4 @@ class PdxFunctionArgumentResolver extends DefaultFunctionArgumentResolver {
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -61,10 +61,11 @@ public class PojoFunctionWrapper implements Function {
|
||||
private final String id;
|
||||
|
||||
public PojoFunctionWrapper(Object target, Method method, String id) {
|
||||
this.functionArgumentResolver = new FunctionContextInjectingArgumentResolver(method);
|
||||
|
||||
this.target = target;
|
||||
this.method = method;
|
||||
this.id = (StringUtils.hasText(id) ? id : method.getName());
|
||||
this.id = StringUtils.hasText(id) ? id : method.getName();
|
||||
this.functionArgumentResolver = new FunctionContextInjectingArgumentResolver(method);
|
||||
this.HA = false;
|
||||
this.hasResult = !method.getReturnType().equals(void.class);
|
||||
this.optimizeForWrite = false;
|
||||
@@ -108,7 +109,7 @@ public class PojoFunctionWrapper implements Function {
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void execute(final FunctionContext functionContext) {
|
||||
public void execute(FunctionContext functionContext) {
|
||||
|
||||
Object[] args = this.functionArgumentResolver.resolveFunctionArguments(functionContext);
|
||||
|
||||
@@ -123,8 +124,10 @@ public class PojoFunctionWrapper implements Function {
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
|
||||
logger.debug(String.format("About to invoke method [%s] on class [%s] as Function [%s]",
|
||||
this.method.getName(), this.target.getClass().getName(), getId()));
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug(String.format("About to invoke method [%s] on class [%s] as Function [%s]",
|
||||
this.method.getName(), this.target.getClass().getName(), getId()));
|
||||
}
|
||||
|
||||
for (Object arg : args) {
|
||||
logger.debug(String.format("Argument of type [%s] is [%s]", arg.getClass().getName(), arg.toString()));
|
||||
@@ -141,10 +144,10 @@ public class PojoFunctionWrapper implements Function {
|
||||
}
|
||||
else {
|
||||
if (ObjectUtils.isArray(result)) {
|
||||
new BatchingResultSender(batchSize, resultSender).sendArrayResults(result);
|
||||
new BatchingResultSender(this.batchSize, resultSender).sendArrayResults(result);
|
||||
}
|
||||
else if (Iterable.class.isAssignableFrom(result.getClass())) {
|
||||
new BatchingResultSender(batchSize, resultSender).sendResults((Iterable<?>) result);
|
||||
new BatchingResultSender(this.batchSize, resultSender).sendResults((Iterable<?>) result);
|
||||
}
|
||||
else {
|
||||
resultSender.lastResult(result);
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
@@ -35,40 +38,37 @@ abstract class AbstractFunctionExecutionBeanDefinitionBuilder {
|
||||
protected final Log log = LogFactory.getLog(getClass());
|
||||
|
||||
/**
|
||||
*
|
||||
* @param configuration the configuration values
|
||||
*/
|
||||
AbstractFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
Assert.notNull(configuration);
|
||||
AbstractFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
Assert.notNull(configuration, "Configuration must not be null");
|
||||
this.configuration = configuration;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Build the bean definition
|
||||
* @param registry
|
||||
* @return
|
||||
*/
|
||||
BeanDefinition build(BeanDefinitionRegistry registry) {
|
||||
BeanDefinition build(BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder functionProxyFactoryBeanBuilder = BeanDefinitionBuilder.rootBeanDefinition(
|
||||
getFunctionProxyFactoryBeanClass());
|
||||
|
||||
functionProxyFactoryBeanBuilder.addConstructorArgValue(configuration.getFunctionExecutionInterface());
|
||||
functionProxyFactoryBeanBuilder.addConstructorArgValue(this.configuration.getFunctionExecutionInterface());
|
||||
functionProxyFactoryBeanBuilder.addConstructorArgReference(BeanDefinitionReaderUtils.registerWithGeneratedName(
|
||||
buildGemfireFunctionOperations(registry), registry));
|
||||
|
||||
|
||||
return functionProxyFactoryBeanBuilder.getBeanDefinition();
|
||||
}
|
||||
}
|
||||
|
||||
protected AbstractBeanDefinition buildGemfireFunctionOperations(BeanDefinitionRegistry registry) {
|
||||
|
||||
BeanDefinitionBuilder functionTemplateBuilder = getGemfireFunctionOperationsBeanDefinitionBuilder(registry);
|
||||
|
||||
functionTemplateBuilder.setLazyInit(true);
|
||||
|
||||
String resultCollectorReference = (String) configuration.getAttribute("resultCollector");
|
||||
|
||||
if (StringUtils.hasText(resultCollectorReference)){
|
||||
functionTemplateBuilder.addPropertyReference("resultCollector", resultCollectorReference);
|
||||
}
|
||||
Optional.ofNullable(this.configuration.getAttribute("resultCollector"))
|
||||
.map(String::valueOf)
|
||||
.filter(StringUtils::hasText)
|
||||
.ifPresent(reference -> functionTemplateBuilder.addPropertyReference("resultCollector", reference));
|
||||
|
||||
return functionTemplateBuilder.getBeanDefinition();
|
||||
}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
@@ -28,11 +28,11 @@ import org.springframework.data.gemfire.function.annotation.OnServers;
|
||||
* @see org.springframework.data.gemfire.function.annotation.OnRegion
|
||||
* @see org.springframework.data.gemfire.function.annotation.OnServer
|
||||
* @see org.springframework.data.gemfire.function.annotation.OnServers
|
||||
* @see org.springframework.data.gemfire.function.config.OnMemberExecutionBeanDefinitionBuilder
|
||||
* @see org.springframework.data.gemfire.function.config.OnMembersExecutionBeanDefinitionBuilder
|
||||
* @see org.springframework.data.gemfire.function.config.OnRegionExecutionBeanDefinitionBuilder
|
||||
* @see org.springframework.data.gemfire.function.config.OnServerExecutionBeanDefinitionBuilder
|
||||
* @see org.springframework.data.gemfire.function.config.OnServersExecutionBeanDefinitionBuilder
|
||||
* @see OnMemberFunctionExecutionBeanDefinitionBuilder
|
||||
* @see OnMembersFunctionExecutionBeanDefinitionBuilder
|
||||
* @see OnRegionFunctionExecutionBeanDefinitionBuilder
|
||||
* @see OnServerFunctionExecutionBeanDefinitionBuilder
|
||||
* @see OnServersFunctionExecutionBeanDefinitionBuilder
|
||||
*/
|
||||
abstract class FunctionExecutionBeanDefinitionBuilderFactory {
|
||||
|
||||
@@ -40,22 +40,21 @@ abstract class FunctionExecutionBeanDefinitionBuilderFactory {
|
||||
String functionExecutionAnnotation = configuration.getAnnotationType();
|
||||
|
||||
if (OnMember.class.getName().equals(functionExecutionAnnotation)) {
|
||||
return new OnMemberExecutionBeanDefinitionBuilder(configuration);
|
||||
return new OnMemberFunctionExecutionBeanDefinitionBuilder(configuration);
|
||||
}
|
||||
else if (OnMembers.class.getName().equals(functionExecutionAnnotation)) {
|
||||
return new OnMembersExecutionBeanDefinitionBuilder(configuration);
|
||||
return new OnMembersFunctionExecutionBeanDefinitionBuilder(configuration);
|
||||
}
|
||||
else if (OnRegion.class.getName().equals(functionExecutionAnnotation)) {
|
||||
return new OnRegionExecutionBeanDefinitionBuilder(configuration);
|
||||
}
|
||||
return new OnRegionFunctionExecutionBeanDefinitionBuilder(configuration);
|
||||
}
|
||||
else if (OnServer.class.getName().equals(functionExecutionAnnotation)) {
|
||||
return new OnServerExecutionBeanDefinitionBuilder(configuration);
|
||||
}
|
||||
return new OnServerFunctionExecutionBeanDefinitionBuilder(configuration);
|
||||
}
|
||||
else if (OnServers.class.getName().equals(functionExecutionAnnotation)) {
|
||||
return new OnServersExecutionBeanDefinitionBuilder(configuration);
|
||||
return new OnServersFunctionExecutionBeanDefinitionBuilder(configuration);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -109,17 +109,19 @@ public class FunctionExecutionBeanDefinitionRegistrar implements ImportBeanDefin
|
||||
|
||||
Set<String> annotationTypes = beanDefinition.getMetadata().getAnnotationTypes();
|
||||
|
||||
String functionExecutionAnnotation = null;
|
||||
String existingFunctionExecutionAnnotation = null;
|
||||
|
||||
for (String annotationType : annotationTypes) {
|
||||
if (functionExecutionAnnotationTypeNames.contains(annotationType)) {
|
||||
Assert.isNull(functionExecutionAnnotation, String.format(
|
||||
"interface %1$s contains multiple Function Execution Annotations: %2$s, %3$s",
|
||||
beanDefinition.getBeanClassName(), functionExecutionAnnotation, annotationType));
|
||||
functionExecutionAnnotation = annotationType;
|
||||
|
||||
Assert.isNull(existingFunctionExecutionAnnotation,
|
||||
String.format("Interface [%1$s] contains multiple Function Execution Annotations: %2$s, %3$s",
|
||||
beanDefinition.getBeanClassName(), existingFunctionExecutionAnnotation, annotationType));
|
||||
|
||||
existingFunctionExecutionAnnotation = annotationType;
|
||||
}
|
||||
}
|
||||
|
||||
return functionExecutionAnnotation;
|
||||
return existingFunctionExecutionAnnotation;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,72 +1,81 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.context.annotation.ScannedGenericBeanDefinition;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.data.gemfire.util.SpringUtils;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Function execution configuration used by bean definition builders
|
||||
*
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
*/
|
||||
class FunctionExecutionConfiguration {
|
||||
|
||||
|
||||
private Class<?> functionExecutionInterface;
|
||||
|
||||
private final Map<String,Object> attributes;
|
||||
private final AnnotationAttributes annotationAttributes;
|
||||
|
||||
private final String annotationType;
|
||||
|
||||
/* constructor for testing purposes only! */
|
||||
/* constructor for testing purposes only */
|
||||
FunctionExecutionConfiguration() {
|
||||
this.annotationType = null;
|
||||
this.attributes = null;
|
||||
this.annotationAttributes = null;
|
||||
}
|
||||
|
||||
FunctionExecutionConfiguration(ScannedGenericBeanDefinition beanDefinition, String annotationType) {
|
||||
try {
|
||||
this.annotationType = annotationType;
|
||||
this.attributes = beanDefinition.getMetadata().getAnnotationAttributes(annotationType, true);
|
||||
this.functionExecutionInterface = beanDefinition.resolveBeanClass(beanDefinition.getClass().getClassLoader());
|
||||
|
||||
Assert.isTrue(functionExecutionInterface.isInterface(),
|
||||
String.format("The annotation %1$s only applies to an interface. It is not valid for the type %2$s",
|
||||
annotationType, functionExecutionInterface.getName()));
|
||||
|
||||
this.annotationType = annotationType;
|
||||
|
||||
this.annotationAttributes = AnnotationAttributes.fromMap(beanDefinition.getMetadata()
|
||||
.getAnnotationAttributes(annotationType, true));
|
||||
|
||||
this.functionExecutionInterface =
|
||||
beanDefinition.resolveBeanClass(beanDefinition.getClass().getClassLoader());
|
||||
|
||||
assertFunctionExecutionInterfaceIsValid(annotationType);
|
||||
}
|
||||
catch (ClassNotFoundException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void assertFunctionExecutionInterfaceIsValid(String annotationType) {
|
||||
|
||||
boolean valid = this.functionExecutionInterface != null && this.functionExecutionInterface.isInterface();
|
||||
|
||||
Assert.isTrue(valid, String.format("The annotation [%1$s] only applies to an interface; It is not valid for type [%2$s]",
|
||||
annotationType, SpringUtils.nullSafeName(this.functionExecutionInterface)));
|
||||
}
|
||||
|
||||
String getAnnotationType() {
|
||||
return this.annotationType;
|
||||
}
|
||||
|
||||
Object getAttribute(String name) {
|
||||
return attributes.get(name);
|
||||
return this.annotationAttributes.get(name);
|
||||
}
|
||||
|
||||
Map<String, Object> getAttributes() {
|
||||
return this.attributes;
|
||||
AnnotationAttributes getAttributes() {
|
||||
return this.annotationAttributes;
|
||||
}
|
||||
|
||||
Class<?> getFunctionExecutionInterface() {
|
||||
return this.functionExecutionInterface;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,8 +10,11 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.data.gemfire.function.annotation.OnMember;
|
||||
@@ -27,13 +30,15 @@ import org.springframework.util.StringUtils;
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder
|
||||
*/
|
||||
abstract class MemberBasedExecutionBeanDefinitionBuilder extends AbstractFunctionExecutionBeanDefinitionBuilder {
|
||||
abstract class MemberBasedFunctionExecutionBeanDefinitionBuilder
|
||||
extends AbstractFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
MemberBasedExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
MemberBasedFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsBeanDefinitionBuilder(org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
*/
|
||||
@Override
|
||||
@@ -42,17 +47,19 @@ abstract class MemberBasedExecutionBeanDefinitionBuilder extends AbstractFunctio
|
||||
BeanDefinitionBuilder functionTemplateBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(getGemfireOperationsClass());
|
||||
|
||||
String groups = (String)configuration.getAttribute("groups");
|
||||
|
||||
if (StringUtils.hasText(groups)) {
|
||||
functionTemplateBuilder.addConstructorArgValue(StringUtils.commaDelimitedListToStringArray(groups));
|
||||
}
|
||||
Optional.ofNullable(this.configuration.getAttribute("groups"))
|
||||
.map(String::valueOf)
|
||||
.map(StringUtils::trimAllWhitespace)
|
||||
.filter(StringUtils::hasText)
|
||||
.map(StringUtils::commaDelimitedListToStringArray)
|
||||
.ifPresent(functionTemplateBuilder::addConstructorArgValue);
|
||||
|
||||
return functionTemplateBuilder;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder#getFunctionProxyFactoryBeanClass()
|
||||
*/
|
||||
@Override
|
||||
@@ -1,36 +1,33 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import org.springframework.data.gemfire.function.execution.GemfireOnMemberFunctionTemplate;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author David Turanski
|
||||
*
|
||||
* @author John Blum
|
||||
*/
|
||||
class OnMemberExecutionBeanDefinitionBuilder extends MemberBasedExecutionBeanDefinitionBuilder {
|
||||
class OnMemberFunctionExecutionBeanDefinitionBuilder extends MemberBasedFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
/**
|
||||
* @param configuration
|
||||
*/
|
||||
OnMemberExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
OnMemberFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.MemberBasedExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsClass()
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.MemberBasedFunctionExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsClass()
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getGemfireOperationsClass() {
|
||||
@@ -1,39 +1,36 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import org.springframework.data.gemfire.function.execution.GemfireOnMembersFunctionTemplate;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
* @author John Blum
|
||||
*/
|
||||
class OnMembersExecutionBeanDefinitionBuilder extends MemberBasedExecutionBeanDefinitionBuilder {
|
||||
class OnMembersFunctionExecutionBeanDefinitionBuilder extends MemberBasedFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
/**
|
||||
* @param configuration
|
||||
*/
|
||||
OnMembersExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
OnMembersFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
// TODO Auto-generated constructor stub
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.MemberBasedExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsClass()
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.MemberBasedFunctionExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsClass()
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getGemfireOperationsClass() {
|
||||
return GemfireOnMembersFunctionTemplate.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,15 +1,16 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
@@ -21,34 +22,38 @@ import org.springframework.data.gemfire.function.execution.OnRegionFunctionProxy
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
class OnRegionExecutionBeanDefinitionBuilder extends AbstractFunctionExecutionBeanDefinitionBuilder {
|
||||
class OnRegionFunctionExecutionBeanDefinitionBuilder extends AbstractFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
/**
|
||||
* @param configuration
|
||||
*/
|
||||
OnRegionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
OnRegionFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsBeanDefinitionBuilder(org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder
|
||||
* #getGemfireFunctionOperationsBeanDefinitionBuilder(org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
*/
|
||||
@Override
|
||||
protected BeanDefinitionBuilder getGemfireFunctionOperationsBeanDefinitionBuilder(BeanDefinitionRegistry registry) {
|
||||
BeanDefinitionBuilder functionTemplateBuilder = BeanDefinitionBuilder.genericBeanDefinition(GemfireOnRegionFunctionTemplate.class);
|
||||
functionTemplateBuilder.addConstructorArgReference((String)configuration.getAttribute("region"));
|
||||
|
||||
BeanDefinitionBuilder functionTemplateBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(GemfireOnRegionFunctionTemplate.class);
|
||||
|
||||
String regionBeanName = String.valueOf(this.configuration.getAttribute("region"));
|
||||
|
||||
functionTemplateBuilder.addConstructorArgReference(regionBeanName);
|
||||
|
||||
return functionTemplateBuilder;
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder#getFunctionProxyFactoryBeanClass()
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder
|
||||
* #getFunctionProxyFactoryBeanClass()
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getFunctionProxyFactoryBeanClass() {
|
||||
return OnRegionFunctionProxyFactoryBean.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,6 +10,7 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import org.springframework.data.gemfire.function.execution.GemfireOnServerFunctionTemplate;
|
||||
@@ -18,19 +19,19 @@ import org.springframework.data.gemfire.function.execution.GemfireOnServerFuncti
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
*/
|
||||
class OnServerExecutionBeanDefinitionBuilder extends ServerBasedExecutionBeanDefinitionBuilder {
|
||||
class OnServerFunctionExecutionBeanDefinitionBuilder extends ServerBasedFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
OnServerExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
OnServerFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.ServerBasedExecutionBeanDefinitionBuilder
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.ServerBasedFunctionExecutionBeanDefinitionBuilder
|
||||
* #getGemfireFunctionOperationsClass()
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getGemfireFunctionOperationsClass() {
|
||||
return GemfireOnServerFunctionTemplate.class;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -10,25 +10,25 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import org.springframework.data.gemfire.function.execution.GemfireOnServersFunctionTemplate;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
* @author John Blum
|
||||
*/
|
||||
class OnServersExecutionBeanDefinitionBuilder extends ServerBasedExecutionBeanDefinitionBuilder {
|
||||
class OnServersFunctionExecutionBeanDefinitionBuilder extends ServerBasedFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
/**
|
||||
* @param configuration
|
||||
*/
|
||||
OnServersExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
OnServersFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.ServerBasedExecutionBeanDefinitionBuilder#getGemfireFunctionOperationsClass()
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.ServerBasedFunctionExecutionBeanDefinitionBuilder
|
||||
* #getGemfireFunctionOperationsClass()
|
||||
*/
|
||||
@Override
|
||||
protected Class<?> getGemfireFunctionOperationsClass() {
|
||||
@@ -12,13 +12,14 @@
|
||||
*/
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
import org.springframework.data.gemfire.function.annotation.OnServer;
|
||||
import org.springframework.data.gemfire.function.annotation.OnServers;
|
||||
import org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
@@ -27,38 +28,51 @@ import org.springframework.util.StringUtils;
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionBuilder
|
||||
* @see org.springframework.beans.factory.support.BeanDefinitionRegistry
|
||||
* @see org.springframework.data.gemfire.function.annotation.OnServer
|
||||
* @see org.springframework.data.gemfire.function.annotation.OnServers
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder
|
||||
*/
|
||||
abstract class ServerBasedExecutionBeanDefinitionBuilder extends AbstractFunctionExecutionBeanDefinitionBuilder {
|
||||
abstract class ServerBasedFunctionExecutionBeanDefinitionBuilder
|
||||
extends AbstractFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
ServerBasedExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
ServerBasedFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder
|
||||
* #getGemfireFunctionOperationsBeanDefinitionBuilder(org.springframework.beans.factory.support.BeanDefinitionRegistry)
|
||||
*/
|
||||
@Override
|
||||
protected BeanDefinitionBuilder getGemfireFunctionOperationsBeanDefinitionBuilder(BeanDefinitionRegistry registry) {
|
||||
|
||||
String resolvedCacheBeanName = Optional.ofNullable(this.configuration.getAttribute("cache"))
|
||||
.map(String::valueOf)
|
||||
.filter(StringUtils::hasText)
|
||||
.orElse(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
|
||||
|
||||
Optional<String> poolBeanName = Optional.ofNullable(this.configuration.getAttribute("pool"))
|
||||
.map(String::valueOf)
|
||||
.filter(StringUtils::hasText);
|
||||
|
||||
BeanDefinitionBuilder functionTemplateBuilder =
|
||||
BeanDefinitionBuilder.genericBeanDefinition(getGemfireFunctionOperationsClass());
|
||||
|
||||
String cache = (String) this.configuration.getAttribute("cache");
|
||||
String pool = (String) this.configuration.getAttribute("pool");
|
||||
functionTemplateBuilder.addConstructorArgReference(resolvedCacheBeanName);
|
||||
|
||||
Assert.state(!(StringUtils.hasText(cache) && StringUtils.hasText(pool)),
|
||||
String.format("Invalid configuration for interface [%s]; cannot specify both 'pool' and 'cache'",
|
||||
this.configuration.getFunctionExecutionInterface().getName()));
|
||||
|
||||
functionTemplateBuilder.addConstructorArgReference(StringUtils.hasText(pool)
|
||||
? pool : (StringUtils.hasText(cache) ? cache : GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME));
|
||||
poolBeanName.ifPresent(it -> {
|
||||
functionTemplateBuilder.addDependsOn(it);
|
||||
functionTemplateBuilder.addPropertyReference("pool", it);
|
||||
});
|
||||
|
||||
return functionTemplateBuilder;
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.springframework.data.gemfire.function.config.AbstractFunctionExecutionBeanDefinitionBuilder
|
||||
* #getFunctionProxyFactoryBeanClass()
|
||||
*/
|
||||
@@ -10,29 +10,32 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.geode.cache.execute.Function;
|
||||
import org.apache.geode.cache.execute.ResultCollector;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
|
||||
/**
|
||||
* The base class for GemFire FunctionTemplates used to invoke GemFire Functions.
|
||||
* The base class for {@link Function} templates used to invoke Apache Geode/Pivotal GemFire {@link Function Functions}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.execute.Function
|
||||
* @see org.apache.geode.cache.execute.ResultCollector
|
||||
* @see org.springframework.beans.factory.InitializingBean
|
||||
* @see org.springframework.data.gemfire.function.execution.GemfireFunctionOperations
|
||||
*/
|
||||
abstract class AbstractFunctionTemplate implements GemfireFunctionOperations {
|
||||
|
||||
protected Log log = LogFactory.getLog(this.getClass());
|
||||
abstract class AbstractFunctionTemplate implements GemfireFunctionOperations, InitializingBean {
|
||||
|
||||
protected long timeout;
|
||||
|
||||
protected volatile ResultCollector<?, ?> resultCollector;
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception { }
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> execute(Function function, Object... args) {
|
||||
return execute(getFunctionExecution().setArgs(args).setFunction(function));
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
@@ -16,8 +16,8 @@ import java.lang.reflect.Method;
|
||||
|
||||
import org.aopalliance.intercept.MethodInterceptor;
|
||||
import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.aop.framework.ProxyFactory;
|
||||
import org.springframework.aop.support.AopUtils;
|
||||
import org.springframework.beans.factory.BeanClassLoaderAware;
|
||||
@@ -27,7 +27,7 @@ import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* A Proxy FactoryBean for all non-Region Function Execution interfaces.
|
||||
*
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see java.lang.reflect.Method
|
||||
@@ -47,7 +47,7 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean<Object>, Met
|
||||
|
||||
private final GemfireFunctionOperations gemfireFunctionOperations;
|
||||
|
||||
protected Log logger = LogFactory.getLog(this.getClass());
|
||||
protected Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||
|
||||
private FunctionExecutionMethodMetadata<MethodMetadata> methodMetadata;
|
||||
|
||||
@@ -56,8 +56,12 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean<Object>, Met
|
||||
* @param gemfireFunctionOperations an interface used to delegate the function invocation (typically a GemFire function template)
|
||||
*/
|
||||
public GemfireFunctionProxyFactoryBean(Class<?> functionExecutionInterface, GemfireFunctionOperations gemfireFunctionOperations) {
|
||||
Assert.notNull(functionExecutionInterface, "'functionExecutionInterface' must not be null");
|
||||
Assert.isTrue(functionExecutionInterface.isInterface(), "'functionExecutionInterface' must be an interface");
|
||||
|
||||
Assert.notNull(functionExecutionInterface, "Function execution interface must not be null");
|
||||
|
||||
Assert.isTrue(functionExecutionInterface.isInterface(),
|
||||
String.format("Function execution type [%s] must be an interface",
|
||||
functionExecutionInterface.getClass().getName()));
|
||||
|
||||
this.functionExecutionInterface = functionExecutionInterface;
|
||||
this.gemfireFunctionOperations = gemfireFunctionOperations;
|
||||
@@ -76,26 +80,27 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean<Object>, Met
|
||||
@Override
|
||||
public Object invoke(MethodInvocation invocation) throws Throwable {
|
||||
if (AopUtils.isToStringMethod(invocation.getMethod())) {
|
||||
return "GemFire Function Proxy for service interface [" + this.functionExecutionInterface + "]";
|
||||
return String.format("Function Proxy for interface [%s]", this.functionExecutionInterface.getName());
|
||||
}
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("invoking method " + invocation.getMethod().getName());
|
||||
logger.debug("Invoking method {}", invocation.getMethod().getName());
|
||||
}
|
||||
|
||||
return invokeFunction(invocation.getMethod(), invocation.getArguments());
|
||||
}
|
||||
|
||||
protected Object invokeFunction(Method method, Object[] args) {
|
||||
return this.gemfireFunctionOperations.executeAndExtract(
|
||||
methodMetadata.getMethodMetadata(method).getFunctionId(), args);
|
||||
|
||||
return this.gemfireFunctionOperations
|
||||
.executeAndExtract(this.methodMetadata.getMethodMetadata(method).getFunctionId(), args);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getObject() throws Exception {
|
||||
if (functionExecutionProxy == null) {
|
||||
onInit();
|
||||
Assert.notNull(functionExecutionProxy, "failed to initialize proxy");
|
||||
Assert.notNull(this.functionExecutionProxy, "Failed to initialize Function Proxy");
|
||||
}
|
||||
|
||||
return functionExecutionProxy;
|
||||
@@ -118,5 +123,4 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean<Object>, Met
|
||||
initialized = true;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
* Copyright 2002-2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
@@ -10,6 +10,7 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import java.util.Set;
|
||||
@@ -20,50 +21,58 @@ import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
* @author John Blum
|
||||
*/
|
||||
public class GemfireOnRegionFunctionTemplate extends AbstractFunctionTemplate implements GemfireOnRegionOperations {
|
||||
|
||||
private Region<?, ?> region;
|
||||
private final Region<?, ?> region;
|
||||
|
||||
/**
|
||||
* Constructs an instance of the GemFireOnRegionFunctionTemplate with the given GemFire Cache Region.
|
||||
* Constructs a new instance of the {@link GemfireOnRegionFunctionTemplate} initialized with
|
||||
* the given {@link Region}.
|
||||
*
|
||||
* @param region the GemFire Cache Region upon which the Function will be executed.
|
||||
* @param region the {@link Region} upon which the {@link Function} will be executed.
|
||||
* @throws IllegalArgumentException if {@link Region} is {@literal null}.
|
||||
* @see org.apache.geode.cache.Region
|
||||
*/
|
||||
public GemfireOnRegionFunctionTemplate(Region<?, ?> region) {
|
||||
Assert.notNull(region, "Region cannot be null");
|
||||
|
||||
Assert.notNull(region, "Region must not be null");
|
||||
|
||||
this.region = region;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> execute(Function function, Set<?> keys, Object... args) {
|
||||
return execute(new RegionFunctionExecution(region).setKeys(keys).setFunction(function).setTimeout(timeout)
|
||||
.setArgs(args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> Iterable<T> execute(String functionId, Set<?> keys, Object... args) {
|
||||
return execute(new RegionFunctionExecution(region).setKeys(keys).setFunctionId(functionId).setTimeout(timeout)
|
||||
.setArgs(args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T executeAndextract(String functionId, Set<?> keys, Object... args) {
|
||||
return this.<T> executeAndExtract(new RegionFunctionExecution(region).setKeys(keys).setFunctionId(functionId)
|
||||
.setTimeout(timeout).setArgs(args));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractFunctionExecution getFunctionExecution() {
|
||||
protected RegionFunctionExecution getFunctionExecution() {
|
||||
return new RegionFunctionExecution(this.region);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeWithNoResult(String functionId, Set<?> keys, Object... args) {
|
||||
execute(new RegionFunctionExecution(region).setKeys(keys).setFunctionId(functionId).setTimeout(timeout)
|
||||
.setArgs(args), false);
|
||||
public <T> Iterable<T> execute(String functionId, Set<?> keys, Object... args) {
|
||||
|
||||
return execute(getFunctionExecution()
|
||||
.setKeys(keys)
|
||||
.setFunctionId(functionId)
|
||||
.setTimeout(this.timeout)
|
||||
.setArgs(args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T executeAndExtract(String functionId, Set<?> keys, Object... args) {
|
||||
|
||||
return executeAndExtract(getFunctionExecution()
|
||||
.setKeys(keys)
|
||||
.setFunctionId(functionId)
|
||||
.setTimeout(this.timeout).setArgs(args));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void executeWithNoResult(String functionId, Set<?> keys, Object... args) {
|
||||
|
||||
execute(getFunctionExecution()
|
||||
.setKeys(keys)
|
||||
.setFunctionId(functionId)
|
||||
.setTimeout(this.timeout)
|
||||
.setArgs(args), false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,20 +10,42 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.geode.cache.Region;
|
||||
import org.apache.geode.cache.execute.Function;
|
||||
|
||||
/**
|
||||
* Interface define {@link Region} {@link Function} data access operations.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.Region
|
||||
* @see org.apache.geode.cache.execute.Function
|
||||
* @see org.springframework.data.gemfire.function.execution.GemfireFunctionOperations
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public interface GemfireOnRegionOperations extends GemfireFunctionOperations {
|
||||
|
||||
public abstract <T> Iterable<T> execute(String functionId, Set<?> keys, Object... args);
|
||||
public abstract <T> Iterable<T> execute(Function function, Set<?> keys, Object... args);
|
||||
public abstract void executeWithNoResult(String functionId, Set<?> keys, Object... args);
|
||||
public abstract <T> T executeAndextract(String functionId, Set<?> keys, Object... args);
|
||||
default <T> Iterable<T> execute(Function function, Set<?> keys, Object... args) {
|
||||
return execute(function.getId(), keys, args);
|
||||
}
|
||||
|
||||
<T> Iterable<T> execute(String functionId, Set<?> keys, Object... args);
|
||||
|
||||
default <T> T executeAndExtract(Function function, Set<?> keys, Object... args) {
|
||||
return executeAndExtract(function.getId(), keys, args);
|
||||
}
|
||||
|
||||
<T> T executeAndExtract(String functionId, Set<?> keys, Object... args);
|
||||
|
||||
default void executeWithNoResult(Function function, Set<?> keys, Object... args) {
|
||||
executeWithNoResult(function.getId(), keys, args);
|
||||
}
|
||||
|
||||
void executeWithNoResult(String functionId, Set<?> keys, Object... args);
|
||||
|
||||
}
|
||||
|
||||
@@ -13,31 +13,110 @@
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.RegionService;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.apache.geode.cache.execute.Execution;
|
||||
import org.apache.geode.cache.execute.Function;
|
||||
import org.apache.shiro.util.Assert;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.util.CacheUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Creates an {@literal OnServer} {@link Function} {@link Execution} initialized with
|
||||
* either a {@link RegionService cache} or a {@link Pool}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.RegionService
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.apache.geode.cache.client.Pool
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.Function
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate
|
||||
*/
|
||||
public class GemfireOnServerFunctionTemplate extends AbstractFunctionTemplate {
|
||||
@SuppressWarnings("unused")
|
||||
public class GemfireOnServerFunctionTemplate extends AbstractFunctionTemplate {
|
||||
|
||||
private Pool pool;
|
||||
|
||||
private final Pool pool;
|
||||
private final RegionService cache;
|
||||
|
||||
private String poolName;
|
||||
|
||||
public GemfireOnServerFunctionTemplate(RegionService cache) {
|
||||
|
||||
Assert.notNull(cache, "RegionService must not be null");
|
||||
|
||||
this.cache = cache;
|
||||
this.pool = null;
|
||||
}
|
||||
|
||||
public GemfireOnServerFunctionTemplate(Pool pool) {
|
||||
this.cache = null;
|
||||
this.cache = resolveClientCache();
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public GemfireOnServerFunctionTemplate(String poolName) {
|
||||
this.cache = resolveClientCache();
|
||||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
public void setPool(Pool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public void setPoolName(String poolName) {
|
||||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractFunctionExecution getFunctionExecution() {
|
||||
return (pool != null ? new PoolServerFunctionExecution(this.pool) : new ServerFunctionExecution(this.cache));
|
||||
|
||||
Object gemfireObject = resolveRequiredGemFireObject();
|
||||
|
||||
return gemfireObject instanceof Pool
|
||||
? new PoolServerFunctionExecution((Pool) gemfireObject)
|
||||
: new ServerFunctionExecution((RegionService) gemfireObject);
|
||||
}
|
||||
|
||||
private Object resolveRequiredGemFireObject() {
|
||||
return Optional.<Object>ofNullable(resolvePool()).orElseGet(this::resolveClientCache);
|
||||
}
|
||||
|
||||
protected ClientCache resolveClientCache() {
|
||||
|
||||
return Optional.ofNullable(CacheUtils.getClientCache())
|
||||
.orElseThrow(() -> newIllegalStateException("No ClientCache instance is present"));
|
||||
}
|
||||
|
||||
protected Pool resolveDefaultPool() {
|
||||
|
||||
return Optional.ofNullable(PoolManager.find(GemfireUtils.DEFAULT_POOL_NAME))
|
||||
.orElseThrow(() -> newIllegalStateException("No Pool was configured"));
|
||||
}
|
||||
|
||||
protected Pool resolveNamedPool() {
|
||||
|
||||
if (StringUtils.hasText(this.poolName)) {
|
||||
this.pool = Optional.ofNullable(PoolManager.find(this.poolName))
|
||||
.orElseThrow(() -> newIllegalStateException("No Pool with name [%s] exists",
|
||||
this.poolName));
|
||||
}
|
||||
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
protected Pool resolvePool() {
|
||||
|
||||
this.pool = Optional.ofNullable(this.pool)
|
||||
.orElseGet(this::resolveNamedPool);
|
||||
|
||||
return this.pool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,35 +13,110 @@
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
|
||||
import static org.springframework.data.gemfire.util.RuntimeExceptionFactory.newIllegalStateException;
|
||||
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.geode.cache.RegionService;
|
||||
import org.apache.geode.cache.client.ClientCache;
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.apache.geode.cache.execute.Execution;
|
||||
import org.apache.geode.cache.execute.Function;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.util.CacheUtils;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
* Creates an {@literal OnServers} {@link Function} {@link Execution} initialized with
|
||||
* either a {@link RegionService cache} or a {@link Pool}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.RegionService
|
||||
* @see org.apache.geode.cache.client.ClientCache
|
||||
* @see org.apache.geode.cache.client.Pool
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.Function
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionTemplate
|
||||
*/
|
||||
public class GemfireOnServersFunctionTemplate extends AbstractFunctionTemplate {
|
||||
@SuppressWarnings("unused")
|
||||
public class GemfireOnServersFunctionTemplate extends AbstractFunctionTemplate {
|
||||
|
||||
private Pool pool;
|
||||
|
||||
private final RegionService cache;
|
||||
private final Pool pool;
|
||||
|
||||
private String poolName;
|
||||
|
||||
public GemfireOnServersFunctionTemplate(RegionService cache) {
|
||||
|
||||
Assert.notNull(cache, "RegionService must not be null");
|
||||
|
||||
public GemfireOnServersFunctionTemplate (RegionService cache) {
|
||||
this.cache = cache;
|
||||
this.pool = null;
|
||||
}
|
||||
|
||||
public GemfireOnServersFunctionTemplate (Pool pool) {
|
||||
public GemfireOnServersFunctionTemplate(Pool pool) {
|
||||
this.cache = resolveClientCache();
|
||||
this.pool = pool;
|
||||
this.cache = null;
|
||||
}
|
||||
|
||||
public GemfireOnServersFunctionTemplate(String poolName) {
|
||||
this.cache = resolveClientCache();
|
||||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
public void setPool(Pool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public void setPoolName(String poolName) {
|
||||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected AbstractFunctionExecution getFunctionExecution() {
|
||||
if (this.pool == null) {
|
||||
return new ServersFunctionExecution(this.cache);
|
||||
}
|
||||
return new PoolServersFunctionExecution(this.pool);
|
||||
|
||||
Object gemfireObject = resolveRequiredGemFireObject();
|
||||
|
||||
return gemfireObject instanceof Pool
|
||||
? new PoolServersFunctionExecution((Pool) gemfireObject)
|
||||
: new ServersFunctionExecution((RegionService) gemfireObject);
|
||||
}
|
||||
|
||||
protected Object resolveRequiredGemFireObject() {
|
||||
return Optional.<Object>ofNullable(resolvePool()).orElseGet(this::resolveClientCache);
|
||||
}
|
||||
|
||||
protected ClientCache resolveClientCache() {
|
||||
|
||||
return Optional.ofNullable(CacheUtils.getClientCache())
|
||||
.orElseThrow(() -> newIllegalStateException("No ClientCache instance is present"));
|
||||
}
|
||||
|
||||
protected Pool resolveDefaultPool() {
|
||||
|
||||
return Optional.ofNullable(PoolManager.find(GemfireUtils.DEFAULT_POOL_NAME))
|
||||
.orElseThrow(() -> newIllegalStateException("No Pool was configured"));
|
||||
}
|
||||
|
||||
protected Pool resolveNamedPool() {
|
||||
|
||||
if (StringUtils.hasText(this.poolName)) {
|
||||
this.pool = Optional.ofNullable(PoolManager.find(this.poolName))
|
||||
.orElseThrow(() -> newIllegalStateException("No Pool with name [%s] exists",
|
||||
this.poolName));
|
||||
}
|
||||
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
protected Pool resolvePool() {
|
||||
|
||||
this.pool = Optional.ofNullable(this.pool)
|
||||
.orElseGet(this::resolveNamedPool);
|
||||
|
||||
return this.pool;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,35 +10,47 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import org.apache.geode.cache.execute.Execution;
|
||||
import org.apache.geode.cache.execute.Function;
|
||||
import org.apache.geode.cache.execute.FunctionService;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Constructs an {@link Execution} using {@link FunctionService#onMember(String...)}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.Function
|
||||
* @see org.apache.geode.cache.execute.FunctionService
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
*/
|
||||
class GroupMemberFunctionExecution extends AbstractFunctionExecution {
|
||||
|
||||
private final String[] groups;
|
||||
|
||||
/**
|
||||
* Constructs an instance of the GroupMemberFunctionExecution class to execute a data independent Function
|
||||
* on a single member from each of the specified groups.
|
||||
* Constructs a new instance of the {@link GroupMemberFunctionExecution} initialized to execute a data independent
|
||||
* {@link Function} on a single member from each of the specified groups.
|
||||
*
|
||||
* @param groups the list of GemFire Groups from which to pick a member from each group on which to execute
|
||||
* the data independent Function.
|
||||
* @param groups array of {@link String groups} from which to pick a member from each group
|
||||
* on which to execute the data independent {@link Function}.
|
||||
* @throws IllegalArgumentException if {@link String groups} is {@literal null} or empty.
|
||||
*/
|
||||
public GroupMemberFunctionExecution(final String... groups) {
|
||||
Assert.notEmpty(groups, "'groups' cannot be null or empty.");
|
||||
public GroupMemberFunctionExecution(String... groups) {
|
||||
|
||||
Assert.notEmpty(groups, "Groups must not be null or empty");
|
||||
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
protected String[] getGroups() {
|
||||
return this.groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the data independent Function on a single member from each of the specified groups.
|
||||
*
|
||||
@@ -47,7 +59,6 @@ class GroupMemberFunctionExecution extends AbstractFunctionExecution {
|
||||
*/
|
||||
@Override
|
||||
protected Execution getExecution() {
|
||||
return FunctionService.onMember(this.groups);
|
||||
return FunctionService.onMember(getGroups());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,34 +10,47 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import org.apache.geode.cache.execute.Execution;
|
||||
import org.apache.geode.cache.execute.Function;
|
||||
import org.apache.geode.cache.execute.FunctionService;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Constructs an {@link Execution} using {@link FunctionService#onMembers(String...)}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.Function
|
||||
* @see org.apache.geode.cache.execute.FunctionService
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
*/
|
||||
class GroupMembersFunctionExecution extends AbstractFunctionExecution {
|
||||
|
||||
private final String[] groups;
|
||||
|
||||
/**
|
||||
* Constructs an instance of the GroupMembersFunctionExecution class to execute a data independent Function
|
||||
* on all members from each of the specified groups.
|
||||
* Constructs a new instance of {@link GroupMembersFunctionExecution} initialized to execute a data independent
|
||||
* {@link Function} on all members from each of the specified {@link String groups}.
|
||||
*
|
||||
* @param groups the list of GemFire Groups indicating the members on which to execute the data independent Function.
|
||||
* @param groups array of {@link String groups} indicating the members on which to execute
|
||||
* the data independent {@link Function}.
|
||||
* @throws IllegalArgumentException if {@link String groups} is {@literal null} or empty.
|
||||
*/
|
||||
public GroupMembersFunctionExecution(final String... groups) {
|
||||
Assert.notEmpty(groups, "'groups' cannot be null or empty.");
|
||||
public GroupMembersFunctionExecution(String... groups) {
|
||||
|
||||
Assert.notEmpty(groups, "Groups must not be null or empty");
|
||||
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
protected String[] getGroups() {
|
||||
return this.groups;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the data independent Function on all members from each of the specified groups.
|
||||
*
|
||||
@@ -46,7 +59,6 @@ class GroupMembersFunctionExecution extends AbstractFunctionExecution {
|
||||
*/
|
||||
@Override
|
||||
protected Execution getExecution() {
|
||||
return FunctionService.onMembers(this.groups);
|
||||
return FunctionService.onMembers(getGroups());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,57 +10,42 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
import org.apache.geode.cache.client.PoolManager;
|
||||
import org.apache.geode.cache.execute.Execution;
|
||||
import org.apache.geode.cache.execute.FunctionService;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Creates a GemFire {@link Execution} using {code}FunctionService.onServer(Pool pool){code}
|
||||
* @author David Turanski
|
||||
* Constructs an {@link Execution} using {@link FunctionService#onServer(Pool)}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.client.Pool
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.FunctionService
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
*/
|
||||
class PoolServerFunctionExecution extends AbstractFunctionExecution implements InitializingBean {
|
||||
class PoolServerFunctionExecution extends AbstractFunctionExecution {
|
||||
|
||||
private final Pool pool;
|
||||
|
||||
private Pool pool;
|
||||
private String poolname;
|
||||
PoolServerFunctionExecution(Pool pool) {
|
||||
|
||||
Assert.notNull(pool, "Pool must not be null");
|
||||
|
||||
/**
|
||||
* @param pool the {@link Pool}
|
||||
*/
|
||||
public PoolServerFunctionExecution(Pool pool) {
|
||||
super();
|
||||
Assert.notNull(pool, "pool cannot be null");
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
public PoolServerFunctionExecution(String poolname) {
|
||||
super();
|
||||
Assert.notNull(poolname, "pool name cannot be null");
|
||||
this.poolname = poolname;
|
||||
|
||||
protected Pool getPool() {
|
||||
return this.pool;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected Execution getExecution() {
|
||||
return FunctionService.onServer(this.pool);
|
||||
}
|
||||
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
|
||||
*/
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.pool = PoolManager.find(poolname);
|
||||
Assert.notNull(pool," pool " + poolname+ " does not exist");
|
||||
|
||||
return FunctionService.onServer(getPool());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import org.apache.geode.cache.client.Pool;
|
||||
@@ -18,26 +19,32 @@ import org.apache.geode.cache.execute.FunctionService;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Creates a GemFire {@link Execution} using {code}FunctionService.onServers(Pool pool){code}
|
||||
* @author David Turanski
|
||||
* Constructs an {@link Execution} using {@link FunctionService#onServers(Pool)}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.client.Pool
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.FunctionService
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
*/
|
||||
class PoolServersFunctionExecution extends AbstractFunctionExecution {
|
||||
|
||||
|
||||
private final Pool pool;
|
||||
|
||||
/**
|
||||
* @param pool the {@link Pool}
|
||||
*/
|
||||
public PoolServersFunctionExecution(Pool pool ) {
|
||||
super();
|
||||
Assert.notNull(pool, "pool cannot be null");
|
||||
PoolServersFunctionExecution(Pool pool) {
|
||||
|
||||
Assert.notNull(pool, "Pool must not be null");
|
||||
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
protected Pool getPool() {
|
||||
return pool;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Execution getExecution() {
|
||||
return FunctionService.onServers(this.pool);
|
||||
return FunctionService.onServers(getPool());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,30 +10,41 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import org.apache.geode.cache.RegionService;
|
||||
import org.apache.geode.cache.execute.Execution;
|
||||
import org.apache.geode.cache.execute.FunctionService;
|
||||
import org.springframework.util.Assert;
|
||||
import org.apache.shiro.util.Assert;
|
||||
|
||||
/**
|
||||
* Creates a GemFire {@link Execution} using {code}FunctionService.onServer(RegionService regionService){code}
|
||||
* @author David Turanski
|
||||
* Constructs an {@link Execution} using {@link FunctionService#onServer(RegionService)}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.RegionService
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.FunctionService
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
*/
|
||||
class ServerFunctionExecution extends AbstractFunctionExecution {
|
||||
|
||||
private final RegionService regionService;
|
||||
|
||||
public ServerFunctionExecution(RegionService regionService) {
|
||||
ServerFunctionExecution(RegionService regionService) {
|
||||
|
||||
Assert.notNull(regionService, "RegionService must not be null");
|
||||
|
||||
this.regionService = regionService;
|
||||
}
|
||||
|
||||
protected RegionService getRegionService() {
|
||||
return regionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Execution getExecution() {
|
||||
return FunctionService.onServer(this.regionService);
|
||||
return FunctionService.onServer(getRegionService());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
import org.apache.geode.cache.RegionService;
|
||||
@@ -18,29 +19,32 @@ import org.apache.geode.cache.execute.FunctionService;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Creates a GemFire {@link Execution} using {code}FunctionService.onServers(RegionService regionService){code}
|
||||
* @author David Turanski
|
||||
* Constructs an {@link Execution} using {@link FunctionService#onServers(RegionService)}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.apache.geode.cache.RegionService
|
||||
* @see org.apache.geode.cache.execute.Execution
|
||||
* @see org.apache.geode.cache.execute.FunctionService
|
||||
* @see org.springframework.data.gemfire.function.execution.AbstractFunctionExecution
|
||||
*/
|
||||
class ServersFunctionExecution extends AbstractFunctionExecution {
|
||||
|
||||
|
||||
private final RegionService regionService;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param regionService e.g., Cache,Client, or GemFireCache
|
||||
* @param function
|
||||
* @param args
|
||||
*/
|
||||
public ServersFunctionExecution(RegionService regionService ) {
|
||||
super();
|
||||
Assert.notNull(regionService,"regionService cannot be null");
|
||||
ServersFunctionExecution(RegionService regionService) {
|
||||
|
||||
Assert.notNull(regionService, "RegionService must not be null");
|
||||
|
||||
this.regionService = regionService;
|
||||
}
|
||||
|
||||
protected RegionService getRegionService() {
|
||||
return regionService;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Execution getExecution() {
|
||||
return FunctionService.onServers(this.regionService);
|
||||
return FunctionService.onServers(getRegionService());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -105,6 +105,14 @@ public abstract class SpringUtils {
|
||||
return (obj1 != null && obj1.equals(obj2));
|
||||
}
|
||||
|
||||
public static String nullSafeName(Class<?> type) {
|
||||
return type != null ? type.getName() : null;
|
||||
}
|
||||
|
||||
public static String nullSafeSimpleName(Class<?> type) {
|
||||
return type != null ? type.getSimpleName() : null;
|
||||
}
|
||||
|
||||
public static <T> T safeGetValue(Supplier<T> valueSupplier) {
|
||||
return safeGetValue(valueSupplier, (T) null);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.ArgumentMatchers.isA;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.spy;
|
||||
import static org.mockito.Mockito.times;
|
||||
@@ -82,8 +83,8 @@ public class FunctionGemfireAdminTemplateUnitTests {
|
||||
|
||||
this.template = spy(new FunctionGemfireAdminTemplate(this.mockClientCache));
|
||||
|
||||
when(this.template.newGemfireFunctionOperations(any(ClientCache.class)))
|
||||
.thenReturn(this.mockFunctionOperations);
|
||||
doReturn(this.mockFunctionOperations).when(this.template)
|
||||
.newGemfireFunctionOperations(any(ClientCache.class));
|
||||
|
||||
when(this.mockIndex.getName()).thenReturn("MockIndex");
|
||||
when(this.mockRegion.getName()).thenReturn("MockRegion");
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright 2018 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.MockitoJUnitRunner;
|
||||
import org.springframework.beans.factory.config.BeanDefinition;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link MemberBasedFunctionExecutionBeanDefinitionBuilder}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mock
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.mockito.junit.MockitoJUnitRunner
|
||||
* @see org.springframework.data.gemfire.function.config.MemberBasedFunctionExecutionBeanDefinitionBuilder
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class MemberBasedFunctionExecutionBeanDefinitionBuilderUnitTests {
|
||||
|
||||
@Mock
|
||||
private FunctionExecutionConfiguration mockFunctionExecutionConfiguration;
|
||||
|
||||
private MemberBasedFunctionExecutionBeanDefinitionBuilder beanDefinitionBuilder;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
this.beanDefinitionBuilder =
|
||||
new TestMemberBasedFunctionExecutionBeanDefinitionBuilder(this.mockFunctionExecutionConfiguration);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void getGemfireFunctionOperationsBeanDefinitionBuilderIsSuccessful() {
|
||||
|
||||
when(this.mockFunctionExecutionConfiguration.getAttribute(eq("groups")))
|
||||
.thenReturn(" TestGroupOne, TestGroupTwo ");
|
||||
|
||||
BeanDefinitionBuilder builder =
|
||||
this.beanDefinitionBuilder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
|
||||
assertThat(builder).isNotNull();
|
||||
|
||||
BeanDefinition beanDefinition = builder.getRawBeanDefinition();
|
||||
|
||||
assertThat(beanDefinition).isNotNull();
|
||||
assertThat(beanDefinition.getBeanClassName()).isEqualTo(Object.class.getName());
|
||||
assertThat(beanDefinition.getConstructorArgumentValues().getArgumentCount()).isEqualTo(1);
|
||||
|
||||
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
|
||||
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, String[].class);
|
||||
|
||||
assertThat(constructorArgumentValue).isNotNull();
|
||||
assertThat((String[]) constructorArgumentValue.getValue()).containsExactly("TestGroupOne", "TestGroupTwo");
|
||||
|
||||
verify(this.mockFunctionExecutionConfiguration, times(1))
|
||||
.getAttribute(eq("groups"));
|
||||
}
|
||||
|
||||
private static final class TestMemberBasedFunctionExecutionBeanDefinitionBuilder
|
||||
extends MemberBasedFunctionExecutionBeanDefinitionBuilder {
|
||||
|
||||
private TestMemberBasedFunctionExecutionBeanDefinitionBuilder(FunctionExecutionConfiguration configuration) {
|
||||
super(configuration);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getGemfireOperationsClass() {
|
||||
return Object.class;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,40 +16,30 @@
|
||||
|
||||
package org.springframework.data.gemfire.function.config;
|
||||
|
||||
import static org.hamcrest.CoreMatchers.containsString;
|
||||
import static org.hamcrest.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.hamcrest.CoreMatchers.nullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.ExpectedException;
|
||||
import org.springframework.beans.PropertyValue;
|
||||
import org.springframework.beans.factory.config.ConstructorArgumentValues;
|
||||
import org.springframework.beans.factory.config.RuntimeBeanReference;
|
||||
import org.springframework.beans.factory.support.AbstractBeanDefinition;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.data.gemfire.config.xml.GemfireConstants;
|
||||
|
||||
/**
|
||||
* The ServerBasedExecutionBeanDefinitionBuilderTest class is test suite of test cases testing the contract
|
||||
* and functionality of the ServerBasedExecutionBeanDefinitionBuilder class.
|
||||
* Unit tests for {@link ServerBasedFunctionExecutionBeanDefinitionBuilder}.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.springframework.data.gemfire.function.config.ServerBasedExecutionBeanDefinitionBuilder
|
||||
* @see org.springframework.data.gemfire.function.config.ServerBasedFunctionExecutionBeanDefinitionBuilder
|
||||
* @since 1.7.0
|
||||
*/
|
||||
public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
|
||||
@Rule
|
||||
public ExpectedException expectedException = ExpectedException.none();
|
||||
public class ServerBasedFunctionExecutionBeanDefinitionBuilderUnitTests {
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -59,11 +49,11 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
mock(FunctionExecutionConfiguration.class, "MockFunctionExecutionConfiguration");
|
||||
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn(null);
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn(" ");
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn("");
|
||||
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
|
||||
|
||||
ServerBasedExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
|
||||
@Override
|
||||
protected Class<?> getGemfireFunctionOperationsClass() {
|
||||
@@ -71,21 +61,25 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
}
|
||||
};
|
||||
|
||||
BeanDefinitionBuilder beanDefinitionBuilder = builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
BeanDefinitionBuilder beanDefinitionBuilder =
|
||||
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
|
||||
assertThat(beanDefinitionBuilder, is(notNullValue()));
|
||||
assertThat(beanDefinitionBuilder).isNotNull();
|
||||
|
||||
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
|
||||
|
||||
assertThat(beanDefinition, is(notNullValue()));
|
||||
assertThat(beanDefinition.getBeanClass(), is(equalTo(Object.class)));
|
||||
assertThat(String.valueOf(beanDefinition.getConstructorArgumentValues()
|
||||
.getArgumentValue(0, RuntimeBeanReference.class).getValue()),
|
||||
containsString(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME));
|
||||
assertThat(beanDefinition).isNotNull();
|
||||
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
|
||||
|
||||
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
|
||||
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
|
||||
|
||||
assertThat(constructorArgumentValue).isNotNull();
|
||||
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("gemfireCache");
|
||||
assertThat(beanDefinition.getPropertyValues().getPropertyValue("pool")).isNull();
|
||||
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -96,11 +90,10 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
mock(FunctionExecutionConfiguration.class, "MockFunctionExecutionConfiguration");
|
||||
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn("TestCache");
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn(" ");
|
||||
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn(" ");
|
||||
|
||||
ServerBasedExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
|
||||
@Override
|
||||
protected Class<?> getGemfireFunctionOperationsClass() {
|
||||
@@ -108,20 +101,25 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
}
|
||||
};
|
||||
|
||||
BeanDefinitionBuilder beanDefinitionBuilder = builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
BeanDefinitionBuilder beanDefinitionBuilder =
|
||||
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
|
||||
assertThat(beanDefinitionBuilder, is(notNullValue()));
|
||||
assertThat(beanDefinitionBuilder).isNotNull();
|
||||
|
||||
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
|
||||
|
||||
assertThat(beanDefinition, is(notNullValue()));
|
||||
assertThat(beanDefinition.getBeanClass(), is(equalTo(Object.class)));
|
||||
assertThat(String.valueOf(beanDefinition.getConstructorArgumentValues()
|
||||
.getArgumentValue(0, RuntimeBeanReference.class).getValue()), containsString("TestCache"));
|
||||
assertThat(beanDefinition).isNotNull();
|
||||
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
|
||||
|
||||
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
|
||||
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
|
||||
|
||||
assertThat(constructorArgumentValue).isNotNull();
|
||||
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("TestCache");
|
||||
assertThat(beanDefinition.getPropertyValues().getPropertyValue("pool")).isNull();
|
||||
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -133,10 +131,9 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn(null);
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn("TestPool");
|
||||
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
|
||||
|
||||
ServerBasedExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
|
||||
@Override
|
||||
protected Class<?> getGemfireFunctionOperationsClass() {
|
||||
@@ -144,20 +141,29 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
}
|
||||
};
|
||||
|
||||
BeanDefinitionBuilder beanDefinitionBuilder = builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
BeanDefinitionBuilder beanDefinitionBuilder =
|
||||
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
|
||||
assertThat(beanDefinitionBuilder, is(notNullValue()));
|
||||
assertThat(beanDefinitionBuilder).isNotNull();
|
||||
|
||||
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
|
||||
|
||||
assertThat(beanDefinition, is(notNullValue()));
|
||||
assertThat(beanDefinition.getBeanClass(), is(equalTo(Object.class)));
|
||||
assertThat(String.valueOf(beanDefinition.getConstructorArgumentValues()
|
||||
.getArgumentValue(0, RuntimeBeanReference.class).getValue()), containsString("TestPool"));
|
||||
assertThat(beanDefinition).isNotNull();
|
||||
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
|
||||
|
||||
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
|
||||
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
|
||||
|
||||
assertThat(constructorArgumentValue).isNotNull();
|
||||
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("gemfireCache");
|
||||
|
||||
PropertyValue propertyValue = beanDefinition.getPropertyValues().getPropertyValue("pool");
|
||||
|
||||
assertThat(propertyValue).isNotNull();
|
||||
assertThat(((RuntimeBeanReference) propertyValue.getValue()).getBeanName()).isEqualTo("TestPool");
|
||||
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -169,10 +175,9 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("cache"))).thenReturn("TestCache");
|
||||
when(mockFunctionExecutionConfiguration.getAttribute(eq("pool"))).thenReturn("TestPool");
|
||||
when(mockFunctionExecutionConfiguration.getFunctionExecutionInterface()).thenAnswer(invocation -> Object.class);
|
||||
|
||||
ServerBasedExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
ServerBasedFunctionExecutionBeanDefinitionBuilder builder =
|
||||
new ServerBasedFunctionExecutionBeanDefinitionBuilder(mockFunctionExecutionConfiguration) {
|
||||
|
||||
@Override
|
||||
protected Class<?> getGemfireFunctionOperationsClass() {
|
||||
@@ -180,15 +185,29 @@ public class ServerBasedExecutionBeanDefinitionBuilderTest {
|
||||
}
|
||||
};
|
||||
|
||||
expectedException.expect(IllegalStateException.class);
|
||||
expectedException.expectCause(is(nullValue(Throwable.class)));
|
||||
expectedException.expectMessage(is(equalTo("Invalid configuration for interface [java.lang.Object];"
|
||||
+ " cannot specify both 'pool' and 'cache'")));
|
||||
|
||||
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
BeanDefinitionBuilder beanDefinitionBuilder =
|
||||
builder.getGemfireFunctionOperationsBeanDefinitionBuilder(null);
|
||||
|
||||
assertThat(beanDefinitionBuilder).isNotNull();
|
||||
|
||||
AbstractBeanDefinition beanDefinition = beanDefinitionBuilder.getRawBeanDefinition();
|
||||
|
||||
assertThat(beanDefinition).isNotNull();
|
||||
assertThat(beanDefinition.getBeanClass()).isEqualTo(Object.class);
|
||||
|
||||
ConstructorArgumentValues.ValueHolder constructorArgumentValue =
|
||||
beanDefinition.getConstructorArgumentValues().getArgumentValue(0, RuntimeBeanReference.class);
|
||||
|
||||
assertThat(constructorArgumentValue).isNotNull();
|
||||
assertThat(((RuntimeBeanReference) constructorArgumentValue.getValue()).getBeanName()).isEqualTo("TestCache");
|
||||
|
||||
PropertyValue propertyValue = beanDefinition.getPropertyValues().getPropertyValue("pool");
|
||||
|
||||
assertThat(propertyValue).isNotNull();
|
||||
assertThat(((RuntimeBeanReference) propertyValue.getValue()).getBeanName()).isEqualTo("TestPool");
|
||||
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("cache"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getAttribute(eq("pool"));
|
||||
verify(mockFunctionExecutionConfiguration, times(1)).getFunctionExecutionInterface();
|
||||
}
|
||||
}
|
||||
@@ -1,26 +1,20 @@
|
||||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
*
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
|
||||
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations under the License.
|
||||
*/
|
||||
package org.springframework.data.gemfire.function.execution;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -34,81 +28,92 @@ import org.aopalliance.intercept.MethodInvocation;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.springframework.data.gemfire.function.annotation.FunctionId;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author David Turanski
|
||||
*
|
||||
*/
|
||||
|
||||
public class GemfireFunctionProxyFactoryBeanTests {
|
||||
|
||||
/**
|
||||
* Unit tests for {@link GemfireFunctionProxyFactoryBean}.
|
||||
*
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.mockito.Mockito
|
||||
* @see org.aopalliance.intercept.MethodInvocation
|
||||
* @see org.springframework.data.gemfire.function.execution.GemfireFunctionProxyFactoryBean
|
||||
*/
|
||||
public class GemfireFunctionProxyFactoryBeanUnitTests {
|
||||
|
||||
private GemfireFunctionOperations functionOperations;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
functionOperations = mock(GemfireFunctionOperations.class);
|
||||
this.functionOperations = mock(GemfireFunctionOperations.class);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testInvokeAndExtractWithAnnotatedFunctionId() throws Throwable {
|
||||
|
||||
|
||||
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class,functionOperations);
|
||||
|
||||
MethodInvocation invocation = new TestInvocation(IFoo.class).withMethodNameAndArgTypes("oneArg",String.class);
|
||||
|
||||
int results = 1;
|
||||
|
||||
when(functionOperations.executeAndExtract("oneArg",invocation.getArguments())).thenReturn(results);
|
||||
public void invoke() throws Throwable {
|
||||
|
||||
MethodInvocation invocation = new TestMethodInvocation(IFoo.class)
|
||||
.withMethodNameAndArgTypes("collections",List.class);
|
||||
|
||||
when(this.functionOperations.executeAndExtract("collections",invocation.getArguments()))
|
||||
.thenReturn(Arrays.asList(1, 2, 3));
|
||||
|
||||
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class, this.functionOperations);
|
||||
|
||||
Object result = proxy.invoke(invocation);
|
||||
verify(functionOperations).executeAndExtract("oneArg",invocation.getArguments());
|
||||
assertTrue(result.getClass().getName(), result instanceof Integer);
|
||||
assertEquals(1,result);
|
||||
|
||||
assertThat(result).isInstanceOf(List.class);
|
||||
assertThat((List) result).hasSize(3);
|
||||
|
||||
verify(this.functionOperations, times(1))
|
||||
.executeAndExtract("collections",invocation.getArguments());
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "rawtypes" })
|
||||
|
||||
@Test
|
||||
public void testInvoke() throws Throwable {
|
||||
|
||||
|
||||
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class, functionOperations);
|
||||
|
||||
MethodInvocation invocation = new TestInvocation(IFoo.class).withMethodNameAndArgTypes("collections",List.class);
|
||||
|
||||
List results = Arrays.asList(new Integer[]{1,2,3});
|
||||
|
||||
when(functionOperations.executeAndExtract("collections",invocation.getArguments())).thenReturn(results);
|
||||
public void invokeAndExtractWithAnnotatedFunctionId() throws Throwable {
|
||||
|
||||
MethodInvocation invocation = new TestMethodInvocation(IFoo.class)
|
||||
.withMethodNameAndArgTypes("oneArg", String.class);
|
||||
|
||||
when(this.functionOperations.executeAndExtract("oneArg",invocation.getArguments())).thenReturn(1);
|
||||
|
||||
GemfireFunctionProxyFactoryBean proxy = new GemfireFunctionProxyFactoryBean(IFoo.class, this.functionOperations);
|
||||
|
||||
Object result = proxy.invoke(invocation);
|
||||
verify(functionOperations).executeAndExtract("collections",invocation.getArguments()); ;
|
||||
assertTrue(result instanceof List);
|
||||
assertEquals(3,((List<?>)result).size());
|
||||
|
||||
assertThat(result).describedAs(result.getClass().getName()).isInstanceOf(Integer.class);
|
||||
assertThat(result).isEqualTo(1);
|
||||
|
||||
verify(this.functionOperations, times(1))
|
||||
.executeAndExtract("oneArg", invocation.getArguments());
|
||||
}
|
||||
|
||||
|
||||
|
||||
static class TestInvocation implements MethodInvocation {
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private static class TestMethodInvocation implements MethodInvocation {
|
||||
|
||||
private Class<?> type;
|
||||
|
||||
private Class<?>[] argTypes;
|
||||
private Class<?> clazz;
|
||||
private String methodName;
|
||||
|
||||
private Object[] arguments;
|
||||
|
||||
public TestInvocation(Class<?> clazz) {
|
||||
this.clazz = clazz;
|
||||
private String methodName;
|
||||
|
||||
public TestMethodInvocation(Class<?> type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public TestInvocation withArguments(Object ...arguments){
|
||||
|
||||
public TestMethodInvocation withArguments(Object ...arguments){
|
||||
|
||||
this.arguments = arguments;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public TestInvocation withMethodNameAndArgTypes(String methodName,Class<?>... argTypes) {
|
||||
|
||||
public TestMethodInvocation withMethodNameAndArgTypes(String methodName,Class<?>... argTypes) {
|
||||
|
||||
this.methodName = methodName;
|
||||
this.argTypes = argTypes;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
@@ -117,7 +122,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
|
||||
*/
|
||||
@Override
|
||||
public Object[] getArguments() {
|
||||
// TODO Auto-generated method stub
|
||||
return this.arguments;
|
||||
}
|
||||
|
||||
@@ -126,7 +130,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
|
||||
*/
|
||||
@Override
|
||||
public Object proceed() throws Throwable {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -135,7 +138,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
|
||||
*/
|
||||
@Override
|
||||
public Object getThis() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -144,7 +146,6 @@ public class GemfireFunctionProxyFactoryBeanTests {
|
||||
*/
|
||||
@Override
|
||||
public AccessibleObject getStaticPart() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -153,35 +154,27 @@ public class GemfireFunctionProxyFactoryBeanTests {
|
||||
*/
|
||||
@Override
|
||||
public Method getMethod() {
|
||||
Method method = null;
|
||||
|
||||
try {
|
||||
method = clazz.getMethod(methodName, argTypes);
|
||||
} catch (SecurityException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
} catch (NoSuchMethodException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
return this.type.getMethod(methodName, argTypes);
|
||||
}
|
||||
catch (NoSuchMethodException | SecurityException cause) {
|
||||
return null;
|
||||
}
|
||||
return method;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public interface IFoo {
|
||||
|
||||
@FunctionId("oneArg")
|
||||
public abstract Integer oneArg(String key);
|
||||
Integer oneArg(String key);
|
||||
|
||||
public abstract Integer twoArg(String akey, String bkey);
|
||||
Integer twoArg(String akey, String bkey);
|
||||
|
||||
public abstract List<Integer> collections(List<Integer> args);
|
||||
List<Integer> collections(List<Integer> args);
|
||||
|
||||
public abstract Map<String, Integer> getMapWithNoArgs();
|
||||
Map<String, Integer> getMapWithNoArgs();
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user