diff --git a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java index c6f5f4e9..81bd13e0 100644 --- a/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/CacheFactoryBean.java @@ -38,7 +38,7 @@ import com.gemstone.gemfire.GemFireException; import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.cache.CacheClosedException; import com.gemstone.gemfire.cache.CacheFactory; -import com.gemstone.gemfire.cache.client.ClientCacheFactory; +import com.gemstone.gemfire.cache.GemFireCache; import com.gemstone.gemfire.distributed.DistributedMember; import com.gemstone.gemfire.distributed.DistributedSystem; import com.gemstone.gemfire.pdx.PdxSerializable; @@ -58,43 +58,35 @@ import com.gemstone.gemfire.pdx.PdxSerializer; * @author Costin Leau */ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, DisposableBean, - InitializingBean, FactoryBean, PersistenceExceptionTranslator { + InitializingBean, FactoryBean, PersistenceExceptionTranslator { + /** + * Inner class to avoid a hard dependency on the GemFire 6.6 API. + * + * @author Costin Leau + */ private class PdxOptions implements Runnable { - private Object factory; + private CacheFactory factory; - PdxOptions(Object factory) { + PdxOptions(CacheFactory factory) { this.factory = factory; } public void run() { Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used"); - // ugly duplication to go around the different factory hierarchy - if (factory instanceof CacheFactory) { - CacheFactory cf = (CacheFactory) factory; - - cf.setPdxSerializer((PdxSerializer) pdxSerializer); - cf.setPdxDiskStore(pdxDiskStoreName); - cf.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields); - cf.setPdxPersistent(pdxPersistent); - cf.setPdxReadSerialized(pdxReadSerialized); - } - if (factory instanceof ClientCacheFactory) { - ClientCacheFactory cf = (ClientCacheFactory) factory; - cf.setPdxSerializer((PdxSerializer) pdxSerializer); - cf.setPdxDiskStore(pdxDiskStoreName); - cf.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields); - cf.setPdxPersistent(pdxPersistent); - cf.setPdxReadSerialized(pdxReadSerialized); - } + factory.setPdxSerializer((PdxSerializer) pdxSerializer); + factory.setPdxDiskStore(pdxDiskStoreName); + factory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields); + factory.setPdxPersistent(pdxPersistent); + factory.setPdxReadSerialized(pdxReadSerialized); } } - private static final Log log = LogFactory.getLog(CacheFactoryBean.class); + protected final Log log = LogFactory.getLog(getClass()); - private Cache cache; + private GemFireCache cache; private Resource cacheXml; private Properties properties; private ClassLoader beanClassLoader; @@ -104,11 +96,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl private String beanName; private boolean useBeanFactoryLocator = true; // PDX options - private Object pdxSerializer; - private Boolean pdxPersistent; - private Boolean pdxReadSerialized; - private Boolean pdxIgnoreUnreadFields; - private String pdxDiskStoreName; + protected Object pdxSerializer; + protected Boolean pdxPersistent; + protected Boolean pdxReadSerialized; + protected Boolean pdxIgnoreUnreadFields; + protected String pdxDiskStoreName; public void afterPropertiesSet() throws Exception { // initialize locator @@ -139,7 +131,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl || pdxIgnoreUnreadFields != null || pdxDiskStoreName != null) { Assert.isTrue(ClassUtils.isPresent("com.gemstone.gemfire.pdx.PdxSerializer", beanClassLoader), "Cannot set PDX options since GemFire 6.6 not detected"); - new PdxOptions(factory).run(); + applyPdxOptions(factory); } // fall back to cache creation @@ -152,7 +144,6 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl log.info("Connected to Distributed System [" + system.getName() + "=" + member.getId() + "@" + member.getHost() + "]"); - log.info(msg + " GemFire v." + CacheFactory.getVersion() + " Cache [" + cache.getName() + "]"); // load/init cache.xml @@ -162,20 +153,32 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl if (log.isDebugEnabled()) log.debug("Initialized cache from " + cacheXml); + } finally { th.setContextClassLoader(oldTCCL); } } + /** + * Sets the PDX properties for the given object. Note this is implementation specific as it depends on the type + * of the factory passed in. + * + * @param factory + */ + protected void applyPdxOptions(Object factory) { + if (factory instanceof CacheFactory) { + new PdxOptions((CacheFactory) factory).run(); + } + } protected Object createFactory(Properties props) { return new CacheFactory(props); } - protected Cache fetchCache() { + protected GemFireCache fetchCache() { return CacheFactory.getAnyInstance(); } - protected Cache createCache(Object factory) { + protected GemFireCache createCache(Object factory) { return ((CacheFactory) factory).create(); } @@ -212,11 +215,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl return null; } - public Cache getObject() throws Exception { + public GemFireCache getObject() throws Exception { return cache; } - public Class getObjectType() { + public Class getObjectType() { return (cache != null ? cache.getClass() : Cache.class); } @@ -310,4 +313,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl public void setPdxDiskStoreName(String pdxDiskStoreName) { this.pdxDiskStoreName = pdxDiskStoreName; } + + /** + * @return the beanFactory + */ + protected BeanFactory getBeanFactory() { + return beanFactory; + } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java index 37a6f991..2f739c52 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java @@ -16,14 +16,19 @@ package org.springframework.data.gemfire.client; +import java.net.InetSocketAddress; +import java.util.List; import java.util.Properties; +import org.springframework.beans.factory.BeanFactory; import org.springframework.data.gemfire.CacheFactoryBean; import org.springframework.util.Assert; +import org.springframework.util.StringUtils; -import com.gemstone.gemfire.cache.Cache; +import com.gemstone.gemfire.cache.GemFireCache; import com.gemstone.gemfire.cache.client.ClientCacheFactory; import com.gemstone.gemfire.cache.client.Pool; +import com.gemstone.gemfire.pdx.PdxSerializer; /** * FactoryBean dedicated to creating client caches (caches for client JVMs). @@ -33,11 +38,38 @@ import com.gemstone.gemfire.cache.client.Pool; */ public class ClientCacheFactoryBean extends CacheFactoryBean { + /** + * Inner class to avoid a hard dependency on the GemFire 6.6 API. + * + * @author Costin Leau + */ + private class PdxOptions implements Runnable { + + private ClientCacheFactory factory; + + PdxOptions(ClientCacheFactory factory) { + this.factory = factory; + } + + public void run() { + Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used"); + + factory.setPdxSerializer((PdxSerializer) pdxSerializer); + factory.setPdxDiskStore(pdxDiskStoreName); + factory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields); + factory.setPdxPersistent(pdxPersistent); + factory.setPdxReadSerialized(pdxReadSerialized); + } + } + private String poolName; + private Pool pool; @Override - protected Cache createCache(Object factory) { - return (Cache) ((ClientCacheFactory) factory).create(); + protected GemFireCache createCache(Object factory) { + ClientCacheFactory ccf = (ClientCacheFactory) factory; + initializePool(ccf); + return ccf.create(); } @Override @@ -46,21 +78,62 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { } @Override - protected Cache fetchCache() { - return (Cache) ClientCacheFactory.getAnyInstance(); + protected GemFireCache fetchCache() { + return ClientCacheFactory.getAnyInstance(); } - // private void initPool() { - // BeanFactory beanFactory = getBeanFactory(); - // - // // try to eagerly initialize the pool name, if defined as a bean - // if (beanFactory.isTypeMatch(poolName, Pool.class)) { - // if (log.isDebugEnabled()) { - // log.debug("Found bean definition for pool '" + poolName + "'. Eagerly initializing it..."); - // } - // beanFactory.getBean(poolName, Pool.class); - // } - // } + private void initializePool(ClientCacheFactory ccf) { + Pool p = pool; + + if (p == null && StringUtils.hasText(poolName)) { + BeanFactory beanFactory = getBeanFactory(); + + // try to eagerly initialize the pool name, if defined as a bean + if (beanFactory.isTypeMatch(poolName, Pool.class)) { + if (log.isDebugEnabled()) { + log.debug("Found bean definition for pool '" + poolName + "'. Eagerly initializing it..."); + } + p = beanFactory.getBean(poolName, Pool.class); + } + } + + if (p != null) { + // copy the pool settings - this way if the pool is not found, at least the cache will have a similar config + ccf.setPoolFreeConnectionTimeout(p.getFreeConnectionTimeout()); + ccf.setPoolIdleTimeout(p.getIdleTimeout()); + ccf.setPoolLoadConditioningInterval(p.getLoadConditioningInterval()); + ccf.setPoolMaxConnections(p.getMaxConnections()); + ccf.setPoolMinConnections(p.getMinConnections()); + ccf.setPoolMultiuserAuthentication(p.getMultiuserAuthentication()); + ccf.setPoolPingInterval(p.getPingInterval()); + ccf.setPoolPRSingleHopEnabled(p.getPRSingleHopEnabled()); + ccf.setPoolReadTimeout(p.getReadTimeout()); + ccf.setPoolRetryAttempts(p.getRetryAttempts()); + ccf.setPoolServerGroup(p.getServerGroup()); + ccf.setPoolSocketBufferSize(p.getSocketBufferSize()); + ccf.setPoolStatisticInterval(p.getStatisticInterval()); + ccf.setPoolSubscriptionAckInterval(p.getSubscriptionAckInterval()); + ccf.setPoolSubscriptionEnabled(p.getSubscriptionEnabled()); + ccf.setPoolSubscriptionMessageTrackingTimeout(p.getSubscriptionMessageTrackingTimeout()); + ccf.setPoolSubscriptionRedundancy(p.getSubscriptionRedundancy()); + ccf.setPoolThreadLocalConnections(p.getThreadLocalConnections()); + + List locators = p.getLocators(); + if (locators != null) { + for (InetSocketAddress inet : locators) { + ccf.addPoolLocator(inet.getHostName(), inet.getPort()); + } + } + + + List servers = p.getServers(); + if (locators != null) { + for (InetSocketAddress inet : servers) { + ccf.addPoolLocator(inet.getHostName(), inet.getPort()); + } + } + } + } /** * Sets the pool name used by this client. @@ -79,6 +152,13 @@ public class ClientCacheFactoryBean extends CacheFactoryBean { */ public void setPool(Pool pool) { Assert.notNull(pool, "pool cannot be null"); - setPoolName(pool.getName()); + this.pool = pool; + } + + @Override + protected void applyPdxOptions(Object factory) { + if (factory instanceof ClientCacheFactory) { + new PdxOptions((ClientCacheFactory) factory).run(); + } } } \ No newline at end of file diff --git a/src/main/java/org/springframework/data/gemfire/config/ClientCacheParser.java b/src/main/java/org/springframework/data/gemfire/config/ClientCacheParser.java new file mode 100644 index 00000000..01683e71 --- /dev/null +++ b/src/main/java/org/springframework/data/gemfire/config/ClientCacheParser.java @@ -0,0 +1,41 @@ +/* + * Copyright 2010-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.support.BeanDefinitionBuilder; +import org.springframework.data.gemfire.client.ClientCacheFactoryBean; +import org.w3c.dom.Element; + +/** + * Parser for <client-cache;gt; definitions. + * + * @author Costin Leau + */ +class ClientCacheParser extends CacheParser { + + @Override + protected Class getBeanClass(Element element) { + return ClientCacheFactoryBean.class; + } + + @Override + protected void doParse(Element element, BeanDefinitionBuilder builder) { + super.doParse(element, builder); + + ParsingUtils.setPropertyValue(element, builder, "pool-name", "poolName"); + } +} \ 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 1d4101dd..7882ab01 100644 --- a/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java +++ b/src/main/java/org/springframework/data/gemfire/config/GemfireNamespaceHandler.java @@ -27,6 +27,8 @@ class GemfireNamespaceHandler extends NamespaceHandlerSupport { public void init() { registerBeanDefinitionParser("cache", new CacheParser()); + registerBeanDefinitionParser("client-cache", new ClientCacheParser()); + registerBeanDefinitionParser("lookup-region", new LookupRegionParser()); registerBeanDefinitionParser("replicated-region", new ReplicatedRegionParser()); registerBeanDefinitionParser("partitioned-region", new PartitionedRegionParser()); 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 index eb43844f..ae6ff94b 100644 --- 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 @@ -17,7 +17,42 @@ ]]> - + + + + + + + + + + + + + + + namespace and its 'properties' element. + ]]> + + + + + + + + + + + + + + + + + + + + + - - - - - - - - + + + + - - - - - namespace and its 'properties' element. - ]]> - - - - - - - + + + + @@ -733,10 +761,10 @@ cache to differ from other caches. - +