+ add more meat to the client-cache server
+ add a dedicated FactoryBean plus namespace
This commit is contained in:
Costin Leau
2011-08-24 21:07:09 +03:00
parent 3205db109f
commit 6944092255
5 changed files with 246 additions and 85 deletions

View File

@@ -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<Cache>, PersistenceExceptionTranslator {
InitializingBean, FactoryBean<GemFireCache>, 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<? extends Cache> getObjectType() {
public Class<? extends GemFireCache> 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;
}
}

View File

@@ -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<InetSocketAddress> locators = p.getLocators();
if (locators != null) {
for (InetSocketAddress inet : locators) {
ccf.addPoolLocator(inet.getHostName(), inet.getPort());
}
}
List<InetSocketAddress> 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();
}
}
}

View File

@@ -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 &lt;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");
}
}

View File

@@ -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());