Merge branch 'client-cache'
This commit is contained in:
@@ -38,6 +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.GemFireCache;
|
||||
import com.gemstone.gemfire.distributed.DistributedMember;
|
||||
import com.gemstone.gemfire.distributed.DistributedSystem;
|
||||
import com.gemstone.gemfire.pdx.PdxSerializable;
|
||||
@@ -57,8 +58,13 @@ 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 CacheFactory factory;
|
||||
@@ -69,6 +75,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
|
||||
|
||||
public void run() {
|
||||
Assert.isAssignable(PdxSerializer.class, pdxSerializer.getClass(), "Invalid pdx serializer used");
|
||||
|
||||
factory.setPdxSerializer((PdxSerializer) pdxSerializer);
|
||||
factory.setPdxDiskStore(pdxDiskStoreName);
|
||||
factory.setPdxIgnoreUnreadFields(pdxIgnoreUnreadFields);
|
||||
@@ -77,9 +84,9 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@@ -89,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
|
||||
@@ -104,7 +111,6 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
|
||||
factoryLocator.afterPropertiesSet();
|
||||
}
|
||||
Properties cfgProps = mergeProperties();
|
||||
CacheFactory factory = new CacheFactory(cfgProps);
|
||||
|
||||
// use the bean class loader to load Declarable classes
|
||||
Thread th = Thread.currentThread();
|
||||
@@ -115,19 +121,21 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
|
||||
// first look for open caches
|
||||
String msg = null;
|
||||
try {
|
||||
cache = CacheFactory.getAnyInstance();
|
||||
cache = fetchCache();
|
||||
msg = "Retrieved existing";
|
||||
} catch (CacheClosedException ex) {
|
||||
Object factory = createFactory(cfgProps);
|
||||
|
||||
// GemFire 6.6 specific options
|
||||
if (pdxSerializer != null || pdxPersistent != null || pdxReadSerialized != null
|
||||
|| 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
|
||||
cache = factory.create();
|
||||
cache = createCache(factory);
|
||||
msg = "Created";
|
||||
}
|
||||
|
||||
@@ -136,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
|
||||
@@ -146,10 +153,34 @@ 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 GemFireCache fetchCache() {
|
||||
return CacheFactory.getAnyInstance();
|
||||
}
|
||||
|
||||
protected GemFireCache createCache(Object factory) {
|
||||
return ((CacheFactory) factory).create();
|
||||
}
|
||||
|
||||
private Properties mergeProperties() {
|
||||
Properties cfgProps = (properties != null ? (Properties) properties.clone() : new Properties());
|
||||
@@ -184,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);
|
||||
}
|
||||
|
||||
@@ -282,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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* 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.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.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).
|
||||
* Acts an utility class (as client caches are a subset with a particular configuration of the generic cache).
|
||||
*
|
||||
* @author Costin Leau
|
||||
*/
|
||||
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 GemFireCache createCache(Object factory) {
|
||||
ClientCacheFactory ccf = (ClientCacheFactory) factory;
|
||||
initializePool(ccf);
|
||||
return ccf.create();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Object createFactory(Properties props) {
|
||||
return new ClientCacheFactory(props);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GemFireCache fetchCache() {
|
||||
return ClientCacheFactory.getAnyInstance();
|
||||
}
|
||||
|
||||
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.
|
||||
*
|
||||
* @param poolName
|
||||
*/
|
||||
public void setPoolName(String poolName) {
|
||||
Assert.hasText(poolName, "pool name is required");
|
||||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pool used by this client.
|
||||
*
|
||||
* @param pool
|
||||
*/
|
||||
public void setPool(Pool pool) {
|
||||
Assert.notNull(pool, "pool cannot be null");
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void applyPdxOptions(Object factory) {
|
||||
if (factory instanceof ClientCacheFactory) {
|
||||
new PdxOptions((ClientCacheFactory) factory).run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
|
||||
private static final Log log = LogFactory.getLog(PoolFactoryBean.class);
|
||||
|
||||
// whether the pool has been created internaly or not
|
||||
// whether the pool has been created internally or not
|
||||
private boolean internalPool = true;
|
||||
|
||||
private Pool pool;
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -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());
|
||||
|
||||
Reference in New Issue
Block a user