From 57b33c007ae59de18b6f46859e56beb6d7472e60 Mon Sep 17 00:00:00 2001 From: David Turanski Date: Mon, 23 Jul 2012 17:30:13 -0400 Subject: [PATCH] Added support for gateway conflict resolver and function service --- .../data/gemfire/CacheFactoryBean.java | 31 +++++++ .../gemfire/FunctionServiceFactoryBean.java | 63 +++++++++++++ .../data/gemfire/config/CacheParser.java | 14 +++ .../gemfire/config/FunctionServiceParser.java | 61 +++++++++++++ .../config/GemfireNamespaceHandler.java | 1 + .../gemfire/config/spring-gemfire-1.2.xsd | 91 +++++++++++++++++++ .../gemfire/config/CacheNamespaceTest.java | 22 ++++- .../config/FunctionServiceNamespaceTest.java | 77 ++++++++++++++++ .../data/gemfire/config/cache-ns.xml | 11 ++- .../gemfire/config/function-service-ns.xml | 21 +++++ .../data/gemfire/config/gateway-v7-ns.xml | 4 +- 11 files changed, 390 insertions(+), 6 deletions(-) create mode 100644 src/main/java/org/springframework/data/gemfire/FunctionServiceFactoryBean.java create mode 100644 src/main/java/org/springframework/data/gemfire/config/FunctionServiceParser.java create mode 100644 src/test/java/org/springframework/data/gemfire/config/FunctionServiceNamespaceTest.java create mode 100644 src/test/resources/org/springframework/data/gemfire/config/function-service-ns.xml diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index d0922b23..bb9ff271 100644 --- a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java @@ -47,6 +47,9 @@ import com.gemstone.gemfire.cache.DynamicRegionFactory; import com.gemstone.gemfire.cache.GemFireCache; import com.gemstone.gemfire.cache.TransactionListener; import com.gemstone.gemfire.cache.TransactionWriter; +import com.gemstone.gemfire.cache.execute.Function; +import com.gemstone.gemfire.cache.execute.FunctionService; +import com.gemstone.gemfire.cache.util.GatewayConflictResolver; import com.gemstone.gemfire.distributed.DistributedMember; import com.gemstone.gemfire.distributed.DistributedSystem; import com.gemstone.gemfire.internal.cache.GemFireCacheImpl; @@ -129,6 +132,10 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl if (messageSyncInterval != null) { cacheImpl.setMessageSyncInterval(messageSyncInterval); } + + if (gatewayConflictResolver != null) { + cacheImpl.setGatewayConflictResolver(gatewayConflictResolver); + } } } @@ -258,6 +265,10 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl protected List jndiDataSources; + protected List functions; + + protected GatewayConflictResolver gatewayConflictResolver; + @Override public void afterPropertiesSet() throws Exception { // initialize locator @@ -324,12 +335,24 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl registerTransactionListeners(); registerTransactionWriter(); registerJndiDataSources(); + registerFunctions(); } finally { th.setContextClassLoader(oldTCCL); } } + /** + * + */ + private void registerFunctions() { + if (!CollectionUtils.isEmpty(functions)) { + for (Function function : functions) { + FunctionService.registerFunction(function); + } + } + } + private void registerJndiDataSources() { if (jndiDataSources != null) { for (JndiDataSource jndiDataSource : jndiDataSources) { @@ -605,6 +628,14 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl this.transactionWriter = transactionWriter; } + public void setFunctions(List functions) { + this.functions = functions; + } + + public void setGatewayConflictResolver(GatewayConflictResolver gatewayConflictResolver) { + this.gatewayConflictResolver = gatewayConflictResolver; + } + public void setDynamicRegionSupport(DynamicRegionSupport dynamicRegionSupport) { this.dynamicRegionSupport = dynamicRegionSupport; } diff --git a/src/main/java/org/springframework/data/gemfire/FunctionServiceFactoryBean.java b/src/main/java/org/springframework/data/gemfire/FunctionServiceFactoryBean.java new file mode 100644 index 00000000..3affdd6d --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/FunctionServiceFactoryBean.java @@ -0,0 +1,63 @@ +/* + * Copyright 2010-2012 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; + +import java.util.List; + +import org.springframework.beans.factory.FactoryBean; +import org.springframework.beans.factory.InitializingBean; +import org.springframework.util.CollectionUtils; + +import com.gemstone.gemfire.cache.execute.Function; +import com.gemstone.gemfire.cache.execute.FunctionService; + +/** + * @author David Turanski + * + */ +public class FunctionServiceFactoryBean implements FactoryBean, InitializingBean { + static FunctionService functionService; + + private List functions; + + @Override + public void afterPropertiesSet() throws Exception { + if (!CollectionUtils.isEmpty(functions)) { + for (Function function : functions) { + FunctionService.registerFunction(function); + } + } + } + + public void setFunctions(List functions) { + this.functions = functions; + } + + @Override + public FunctionService getObject() throws Exception { + return functionService; + } + + @Override + public Class getObjectType() { + return FunctionService.class; + } + + @Override + public boolean isSingleton() { + return true; + } +} diff --git a/src/main/java/org/springframework/data/gemfire/config/CacheParser.java b/src/main/java/org/springframework/data/gemfire/config/CacheParser.java index d8cd9755..06a7933c 100644 --- a/src/main/java/org/springframework/data/gemfire/config/CacheParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/CacheParser.java @@ -84,6 +84,20 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser { ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, txWriter, builder)); } + Element gatewayConflictResolver = DomUtils.getChildElementByTagName(element, "gateway-conflict-resolver"); + if (gatewayConflictResolver != null) { + ParsingUtils.throwExceptionIfNotGemfireV7(element.getLocalName(), "gateway-conflict-resolver", + parserContext); + builder.addPropertyValue("gatewayConflictResolver", + ParsingUtils.parseRefOrSingleNestedBeanDeclaration(parserContext, gatewayConflictResolver, builder)); + } + + Element function = DomUtils.getChildElementByTagName(element, "function"); + if (function != null) { + builder.addPropertyValue("functions", + ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, function, builder)); + } + parseDynamicRegionFactory(element, builder); parseJndiBindings(element, builder); } diff --git a/src/main/java/org/springframework/data/gemfire/config/FunctionServiceParser.java b/src/main/java/org/springframework/data/gemfire/config/FunctionServiceParser.java new file mode 100644 index 00000000..6b1b528c --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/FunctionServiceParser.java @@ -0,0 +1,61 @@ +/* + * Copyright 2010-2012 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.config; + +import org.springframework.beans.factory.BeanDefinitionStoreException; +import org.springframework.beans.factory.support.AbstractBeanDefinition; +import org.springframework.beans.factory.support.BeanDefinitionBuilder; +import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser; +import org.springframework.beans.factory.xml.ParserContext; +import org.springframework.data.gemfire.FunctionServiceFactoryBean; +import org.springframework.util.StringUtils; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Element; + +/** + * Parser for <function-service;gt; definitions. + * @author David Turanski + */ +class FunctionServiceParser extends AbstractSimpleBeanDefinitionParser { + + @Override + protected Class getBeanClass(Element element) { + return FunctionServiceFactoryBean.class; + } + + @Override + protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { + builder.setLazyInit(false); + super.doParse(element, builder); + Element function = DomUtils.getChildElementByTagName(element, "function"); + if (function != null) { + builder.addPropertyValue("functions", + ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, function, builder)); + } + } + + @Override + protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext) + throws BeanDefinitionStoreException { + String name = super.resolveId(element, definition, parserContext); + if (!StringUtils.hasText(name)) { + name = "gemfire-function-service"; + } + return name; + } + +} \ No newline at end of file diff --git a/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java b/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java index 64c8c78c..fe786165 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java +++ b/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java @@ -64,6 +64,7 @@ class GemfireNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("async-event-queue", new AsyncEventQueueParser()); registerBeanDefinitionParser("gateway-sender", new GatewaySenderParser()); registerBeanDefinitionParser("gateway-receiver", new GatewayReceiverParser()); + registerBeanDefinitionParser("function-service", new FunctionServiceParser()); // V6 WAN parsers registerBeanDefinitionParser("gateway-hub", new GatewayHubParser()); } diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.2.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.2.xsd index 42d870f4..e301b8ce 100755 --- a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.2.xsd +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.2.xsd @@ -35,6 +35,45 @@ and may be nested or referenced. ]]> + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2438,6 +2477,58 @@ The id of the cache - default is gemfire-cache + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java index 8ed43f9b..c7c6dbba 100644 --- a/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java +++ b/src/test/java/org/springframework/data/gemfire/config/CacheNamespaceTest.java @@ -33,6 +33,11 @@ import org.springframework.data.gemfire.TestUtils; import org.springframework.data.gemfire.client.ClientCacheFactoryBean; import org.springframework.test.util.ReflectionTestUtils; +import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.util.GatewayConflictHelper; +import com.gemstone.gemfire.cache.util.GatewayConflictResolver; +import com.gemstone.gemfire.cache.util.TimestampedEntryEvent; + /** * @author Costin Leau */ @@ -48,9 +53,8 @@ public class CacheNamespaceTest extends RecreatingContextTest { testBasicCache(); testNamedCache(); testCacheWithXml(); - // testBasicClientCache(); - // testBasicClientCacheWithXml(); testHeapTunedCache(); + testCacheWithGatewayConflictResolver(); } private void testBasicCache() throws Exception { @@ -79,6 +83,12 @@ public class CacheNamespaceTest extends RecreatingContextTest { } + private void testCacheWithGatewayConflictResolver() { + Cache cache = ctx.getBean("cache-with-conflict-resolver", Cache.class); + assertNotNull(cache.getGatewayConflictResolver()); + assertTrue(cache.getGatewayConflictResolver() instanceof TestConflictResolver); + } + @Test(expected = IllegalArgumentException.class) public void testNoBeanFactory() throws Exception { assertTrue(ctx.containsBean("no-bl")); @@ -121,4 +131,12 @@ public class CacheNamespaceTest extends RecreatingContextTest { assertEquals(70, chp, 0.0001); assertEquals(60, ehp, 0.0001); } + + public static class TestConflictResolver implements GatewayConflictResolver { + @Override + public void onEvent(TimestampedEntryEvent arg0, GatewayConflictHelper arg1) { + // TODO Auto-generated method stub + + } + } } \ No newline at end of file diff --git a/src/test/java/org/springframework/data/gemfire/config/FunctionServiceNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/FunctionServiceNamespaceTest.java new file mode 100644 index 00000000..c481bfe0 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/config/FunctionServiceNamespaceTest.java @@ -0,0 +1,77 @@ +/* + * Copyright 2010-2012 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.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + +import org.junit.Test; +import org.springframework.data.gemfire.RecreatingContextTest; + +import com.gemstone.gemfire.cache.execute.FunctionAdapter; +import com.gemstone.gemfire.cache.execute.FunctionContext; +import com.gemstone.gemfire.cache.execute.FunctionService; + +/** + * @author Costin Leau + */ +public class FunctionServiceNamespaceTest extends RecreatingContextTest { + + @Override + protected String location() { + return "org/springframework/data/gemfire/config/function-service-ns.xml"; + } + + @Test + public void testFunctionsRegistered() throws Exception { + assertEquals(2, FunctionService.getRegisteredFunctions().size()); + assertNotNull(FunctionService.getFunction("function1")); + assertNotNull(FunctionService.getFunction("function2")); + } + + @SuppressWarnings("serial") + public static class Function1 extends FunctionAdapter { + + @Override + public void execute(FunctionContext arg0) { + // TODO Auto-generated method stub + + } + + @Override + public String getId() { + return "function1"; + } + + } + + @SuppressWarnings("serial") + public static class Function2 extends FunctionAdapter { + + @Override + public void execute(FunctionContext arg0) { + // TODO Auto-generated method stub + + } + + @Override + public String getId() { + return "function2"; + } + + } +} \ No newline at end of file diff --git a/src/test/resources/org/springframework/data/gemfire/config/cache-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/cache-ns.xml index fbe5d6ce..321244f2 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/cache-ns.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/cache-ns.xml @@ -12,7 +12,7 @@ - + @@ -29,4 +29,11 @@ - \ No newline at end of file + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/org/springframework/data/gemfire/config/function-service-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/function-service-ns.xml new file mode 100644 index 00000000..37e5af17 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/config/function-service-ns.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/org/springframework/data/gemfire/config/gateway-v7-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/gateway-v7-ns.xml index 1f68f483..44ee6696 100644 --- a/src/test/resources/org/springframework/data/gemfire/config/gateway-v7-ns.xml +++ b/src/test/resources/org/springframework/data/gemfire/config/gateway-v7-ns.xml @@ -11,7 +11,7 @@ - + - +