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 343fafc8..7a35cbf6 100644 --- a/src/main/java/org/springframework/data/gemfire/config/CacheParser.java +++ b/src/main/java/org/springframework/data/gemfire/config/CacheParser.java @@ -32,6 +32,7 @@ import org.w3c.dom.Element; */ class CacheParser extends AbstractSingleBeanDefinitionParser { + @Override protected Class getBeanClass(Element element) { return CacheFactoryBean.class; } diff --git a/src/main/java/org/springframework/data/gemfire/config/CacheServerParser.java b/src/main/java/org/springframework/data/gemfire/config/CacheServerParser.java new file mode 100644 index 00000000..b2bcafdc --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/CacheServerParser.java @@ -0,0 +1,86 @@ +/* + * Copyright 2011 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.server.CacheServerFactoryBean; +import org.springframework.util.StringUtils; +import org.springframework.util.xml.DomUtils; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; + +/** + * Namespace parser for "cache-server" element. + * + * @author Costin Leau + */ +class CacheServerParser extends AbstractSimpleBeanDefinitionParser { + + @Override + protected Class getBeanClass(Element element) { + return CacheServerFactoryBean.class; + } + + @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-server"; + } + return name; + } + + @Override + protected boolean isEligibleAttribute(Attr attribute, ParserContext parserContext) { + return super.isEligibleAttribute(attribute, parserContext) && !"groups".equals(attribute.getName()) + && !"cache-ref".equals(attribute.getName()); + } + + @Override + protected void postProcess(BeanDefinitionBuilder builder, Element element) { + + String attr = element.getAttribute("cache-ref"); + // add cache reference (fallback to default if nothing is specified) + builder.addPropertyReference("cache", (StringUtils.hasText(attr) ? attr : "gemfire-cache")); + + attr = element.getAttribute("groups"); + if (StringUtils.hasText(attr)) { + builder.addPropertyValue("serverGroups", StringUtils.commaDelimitedListToStringArray(attr)); + } + + parseSubscription(builder, element); + } + + private void parseSubscription(BeanDefinitionBuilder builder, Element element) { + Element subConfig = DomUtils.getChildElementByTagName(element, "subscription-config"); + if (subConfig == null) { + return; + } + + ParsingUtils.setPropertyValue(subConfig, builder, "capacity", "subscriptionCapacity"); + ParsingUtils.setPropertyValue(subConfig, builder, "disk-store", "subscriptionDiskStore"); + String attr = element.getAttribute("eviction-type"); + if (StringUtils.hasText(attr)) { + builder.addPropertyValue("subscriptionEvictionPolicy", attr.toUpperCase()); + } + } +} \ 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 bd2f1045..1d4101dd 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java +++ b/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java @@ -32,6 +32,7 @@ class GemfireNamespaceHandler extends NamespaceHandlerSupport { registerBeanDefinitionParser("partitioned-region", new PartitionedRegionParser()); registerBeanDefinitionParser("client-region", new ClientRegionParser()); registerBeanDefinitionParser("pool", new PoolParser()); + registerBeanDefinitionParser("cache-server", new CacheServerParser()); registerBeanDefinitionParser("transaction-manager", new TransactionManagerParser()); } diff --git a/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java b/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java index 2d590fe0..8c0db0f7 100644 --- a/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/server/CacheServerFactoryBean.java @@ -24,11 +24,13 @@ import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.SmartLifecycle; +import org.springframework.core.io.Resource; import org.springframework.util.Assert; import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.cache.InterestRegistrationListener; import com.gemstone.gemfire.cache.server.CacheServer; +import com.gemstone.gemfire.cache.server.ClientSubscriptionConfig; import com.gemstone.gemfire.cache.server.ServerLoadProbe; /** @@ -36,8 +38,8 @@ import com.gemstone.gemfire.cache.server.ServerLoadProbe; * * @author Costin Leau */ -public class CacheServerFactoryBean implements FactoryBean, - InitializingBean, DisposableBean, SmartLifecycle { +public class CacheServerFactoryBean implements FactoryBean, InitializingBean, DisposableBean, + SmartLifecycle { private boolean autoStartup = true; @@ -55,10 +57,15 @@ public class CacheServerFactoryBean implements FactoryBean, private String bindAddress = CacheServer.DEFAULT_BIND_ADDRESS; private String hostNameForClients = CacheServer.DEFAULT_HOSTNAME_FOR_CLIENTS; private Set listeners = Collections.emptySet(); - + + private SubscriptionEvictionPolicy evictionPolicy = SubscriptionEvictionPolicy.valueOf(ClientSubscriptionConfig.DEFAULT_EVICTION_POLICY.toUpperCase()); + private int subscriptionCapacity = ClientSubscriptionConfig.DEFAULT_CAPACITY; + private Resource subscriptionDiskStore; + private Cache cache; private CacheServer cacheServer; + public CacheServer getObject() { return cacheServer; } @@ -71,9 +78,9 @@ public class CacheServerFactoryBean implements FactoryBean, return true; } - public void afterPropertiesSet() { + public void afterPropertiesSet() throws IOException { Assert.notNull(cache, "cache is required"); - + cacheServer = cache.addCacheServer(); cacheServer.setBindAddress(bindAddress); cacheServer.setGroups(serverGroups); @@ -88,11 +95,17 @@ public class CacheServerFactoryBean implements FactoryBean, cacheServer.setNotifyBySubscription(notifyBySubscription); cacheServer.setPort(port); cacheServer.setSocketBufferSize(socketBufferSize); - + for (InterestRegistrationListener listener : listeners) { cacheServer.registerInterestRegistrationListener(listener); - } - + } + + // client config + ClientSubscriptionConfig config = cacheServer.getClientSubscriptionConfig(); + config.setCapacity(subscriptionCapacity); + config.setEvictionPolicy(evictionPolicy.name().toLowerCase()); + config.setDiskStoreName(subscriptionDiskStore.getFile().getCanonicalPath()); + start(); } @@ -128,7 +141,7 @@ public class CacheServerFactoryBean implements FactoryBean, } public void stop() { - if (cacheServer != null){ + if (cacheServer != null) { cacheServer.stop(); } } @@ -196,4 +209,22 @@ public class CacheServerFactoryBean implements FactoryBean, public void setCache(Cache cache) { this.cache = cache; } + + /** + * @param evictionPolicy the evictionPolicy to set + */ + public void setSubscriptionEvictionPolicy(SubscriptionEvictionPolicy evictionPolicy) { + this.evictionPolicy = evictionPolicy; + } + + /** + * @param subscriptionCapacity the subscriptionCapacity to set + */ + public void setSubscriptionCapacity(int subscriptionCapacity) { + this.subscriptionCapacity = subscriptionCapacity; + } + + public void setSubscriptionDiskStore(Resource resource) { + this.subscriptionDiskStore = resource; + } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/gemfire/server/SubscriptionEvictionPolicy.java b/src/main/java/org/springframework/data/gemfire/server/SubscriptionEvictionPolicy.java new file mode 100644 index 00000000..d7c1efda --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/server/SubscriptionEvictionPolicy.java @@ -0,0 +1,28 @@ +/* + * Copyright 2011 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.server; + +import com.gemstone.gemfire.cache.server.CacheServer; + +/** + * Enumeration of the various client subscription policies for {@link CacheServer}. + * + * @author Costin Leau + */ +public enum SubscriptionEvictionPolicy { + NONE, MEM, ENTRY +} diff --git a/src/main/resources/META-INF/spring.schemas b/src/main/resources/META-INF/spring.schemas index 25b420e3..2bb1ca58 100644 --- a/src/main/resources/META-INF/spring.schemas +++ b/src/main/resources/META-INF/spring.schemas @@ -1,2 +1,3 @@ http\://www.springframework.org/schema/gemfire/spring-gemfire-1.0.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.0.xsd -http\://www.springframework.org/schema/gemfire/spring-gemfire.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.0.xsd \ No newline at end of file +http\://www.springframework.org/schema/gemfire/spring-gemfire-1.1.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.1.xsd +http\://www.springframework.org/schema/gemfire/spring-gemfire.xsd=org/springframework/data/gemfire/config/spring-gemfire-1.1.xsd \ No newline at end of file diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.1.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.1.xsd new file mode 100644 index 00000000..184e391d --- /dev/null +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-1.1.xsd @@ -0,0 +1,906 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + namespace and its 'properties' element. + ]]> + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/java/org/springframework/data/gemfire/config/CacheServerNamespaceTest.java b/src/test/java/org/springframework/data/gemfire/config/CacheServerNamespaceTest.java new file mode 100644 index 00000000..1148c3d0 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/config/CacheServerNamespaceTest.java @@ -0,0 +1,47 @@ +/* + * Copyright 2011 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.assertTrue; + +import org.junit.Test; +import org.springframework.data.gemfire.RecreatingContextTest; + +import com.gemstone.gemfire.cache.server.CacheServer; + +/** + * + * @author Costin Leau + */ +public class CacheServerNamespaceTest extends RecreatingContextTest { + + @Override + protected String location() { + return "org/springframework/data/gemfire/config/server-ns.xml"; + } + + @Test + public void testBasicCacheServer() throws Exception { + CacheServer cacheServer = ctx.getBean("advanced-config", CacheServer.class); + assertTrue(cacheServer.isRunning()); + assertEquals(1, cacheServer.getGroups().length); + assertEquals("test-server", cacheServer.getGroups()[0]); + assertEquals(22, cacheServer.getMaxConnections()); + + } +} diff --git a/src/test/resources/org/springframework/data/gemfire/config/server-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/server-ns.xml new file mode 100644 index 00000000..a03427d6 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/config/server-ns.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/test/resources/port.properties b/src/test/resources/port.properties index 66e8f405..00ec631d 100644 --- a/src/test/resources/port.properties +++ b/src/test/resources/port.properties @@ -1,2 +1,3 @@ gfe.port=40403 -gfe.port.4=40404 \ No newline at end of file +gfe.port.4=40404 +gfe.port.6=40406 \ No newline at end of file