CacheFactoryBean is no longer an initializing bean to address lifecycle issues with client cache and pool

This commit is contained in:
David Turanski
2012-11-26 15:13:13 -05:00
parent 2d30b81e8e
commit 1fbf96db3b
17 changed files with 64 additions and 86 deletions

View File

@@ -30,8 +30,6 @@ import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.BeanNameAware;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.core.io.Resource;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.PersistenceExceptionTranslator;
@@ -76,14 +74,13 @@ import com.gemstone.gemfire.pdx.PdxSerializer;
* @author David Turanski
*/
public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanClassLoaderAware, DisposableBean,
InitializingBean, FactoryBean<GemFireCache>, PersistenceExceptionTranslator {
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 final CacheFactory factory;
@@ -186,8 +183,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
DynamicRegionFactory.Config config = null;
if (diskDir == null) {
config = new DynamicRegionFactory.Config(null, poolName, persistent, registerInterest);
}
else {
} else {
config = new DynamicRegionFactory.Config(new File(diskDir), poolName, persistent, registerInterest);
}
DynamicRegionFactory.get().open(config);
@@ -270,8 +266,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
// Defined this way for backward compatibility
protected Object gatewayConflictResolver;
@Override
public void afterPropertiesSet() throws Exception {
private void init() throws Exception {
// initialize locator
if (useBeanFactoryLocator) {
factoryLocator = new GemfireBeanFactoryLocator();
@@ -279,12 +274,9 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
factoryLocator.setBeanName(beanName);
factoryLocator.afterPropertiesSet();
}
Properties cfgProps = mergeProperties();
// use the bean class loader to load Declarable classes
Thread th = Thread.currentThread();
ClassLoader oldTCCL = th.getContextClassLoader();
try {
th.setContextClassLoader(beanClassLoader);
@@ -293,12 +285,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
try {
cache = fetchCache();
msg = "Retrieved existing";
}
catch (CacheClosedException ex) {
} catch (CacheClosedException ex) {
initializeDynamicRegionFactory();
Object factory = createFactory(cfgProps);
Object factory = createFactory(this.properties);
// GemFire 6.6 specific options
if (pdxSerializer != null || pdxPersistent != null || pdxReadSerialized != null
@@ -333,13 +324,12 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
log.debug("Initialized cache from " + cacheXml);
}
}
setHeapPercentages();
registerTransactionListeners();
registerTransactionWriter();
registerJndiDataSources();
}
finally {
} finally {
th.setContextClassLoader(oldTCCL);
}
}
@@ -429,11 +419,6 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
return ((CacheFactory) factory).create();
}
protected Properties mergeProperties() {
Properties cfgProps = (properties != null ? (Properties) properties.clone() : new Properties());
return cfgProps;
}
@Override
public void destroy() throws Exception {
if (cache != null && !cache.isClosed()) {
@@ -461,10 +446,10 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
}
}
if (ex.getCause() instanceof GemFireException) {
return GemfireCacheUtils.convertGemfireAccessException((GemFireException)ex.getCause());
return GemfireCacheUtils.convertGemfireAccessException((GemFireException) ex.getCause());
}
if (ex.getCause() instanceof GemFireCheckedException) {
return GemfireCacheUtils.convertGemfireAccessException((GemFireCheckedException)ex.getCause());
return GemfireCacheUtils.convertGemfireAccessException((GemFireCheckedException) ex.getCause());
}
return null;
@@ -472,6 +457,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
@Override
public GemFireCache getObject() throws Exception {
init();
return cache;
}
@@ -604,11 +590,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
public void setLockTimeout(int lockTimeout) {
this.lockTimeout = lockTimeout;
}
/**
*
* @param lockLease
*/
/**
*
* @param lockLease
*/
public void setLockLease(int lockLease) {
this.lockLease = lockLease;
}
@@ -628,7 +614,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
public void setSearchTimeout(int searchTimeout) {
this.searchTimeout = searchTimeout;
}
/**
*
* @param evictionHeapPercentage
@@ -636,11 +622,11 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
public void setEvictionHeapPercentage(Float evictionHeapPercentage) {
this.evictionHeapPercentage = evictionHeapPercentage;
}
/**
*
* @param criticalHeapPercentage
*/
/**
*
* @param criticalHeapPercentage
*/
public void setCriticalHeapPercentage(Float criticalHeapPercentage) {
this.criticalHeapPercentage = criticalHeapPercentage;
}
@@ -660,6 +646,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
public void setTransactionWriter(TransactionWriter transactionWriter) {
this.transactionWriter = transactionWriter;
}
/**
* Requires GemFire 7.0 or higher
* @param gatewayConflictResolver defined as Object in the signature for backward
@@ -686,6 +673,4 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
this.jndiDataSources = jndiDataSources;
}
}

View File

@@ -19,7 +19,6 @@ package org.springframework.data.gemfire.client;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.Properties;
import java.util.logging.Handler;
import org.springframework.beans.factory.BeanInitializationException;
import org.springframework.data.gemfire.CacheFactoryBean;
@@ -27,15 +26,10 @@ import org.springframework.data.gemfire.config.GemfireConstants;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import com.gemstone.gemfire.LogWriter;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
import com.gemstone.gemfire.cache.client.Pool;
import com.gemstone.gemfire.cache.client.PoolManager;
import com.gemstone.gemfire.distributed.DistributedSystem;
import com.gemstone.gemfire.distributed.internal.InternalDistributedSystem;
import com.gemstone.gemfire.i18n.LogWriterI18n;
import com.gemstone.gemfire.i18n.StringId;
import com.gemstone.gemfire.pdx.PdxSerializer;
/**
@@ -100,6 +94,10 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
protected GemFireCache fetchCache() {
return ClientCacheFactory.getAnyInstance();
}
Properties getProperties() {
return this.properties;
}
private void initializePool(ClientCacheFactory ccf) {
Pool p = pool;
@@ -111,7 +109,7 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
// Bind this client cache to a pool that hasn't been created yet.
if (p == null) {
PoolFactoryBean.connectToTemporaryDs();
PoolFactoryBean.connectToTemporaryDs(this.properties);
}
if (StringUtils.hasText(poolName)) {

View File

@@ -231,7 +231,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
if (region != null) {
if (close) {
if (!region.getCache().isClosed()) {
if (!region.getRegionService().isClosed()) {
try {
region.close();
}

View File

@@ -112,8 +112,15 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean,
// eagerly initialize cache (if needed)
if (InternalDistributedSystem.getAnyInstance() == null) {
// no cache found, create a temp connection
connectToTemporaryDs();
Properties properties = null;
try {
ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class);
properties = clientCacheFactoryBean.getProperties();
} catch (Exception e) {
}
connectToTemporaryDs(properties);
}
// first check the configured pools
@@ -386,10 +393,10 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean,
* initialize a client-like Distributed System before initializing
* the pool
*/
static void connectToTemporaryDs() {
Properties prop = new Properties();
prop.setProperty("mcast-port", "0");
prop.setProperty("locators", "");
DistributedSystem.connect(prop);
static void connectToTemporaryDs(Properties properties) {
Properties props = properties != null? (Properties) properties.clone() : new Properties();
props.setProperty("mcast-port", "0");
props.setProperty("locators", "");
DistributedSystem.connect(props);
}
}

View File

@@ -19,7 +19,6 @@ package org.springframework.data.gemfire.config;
import java.util.List;
import org.springframework.beans.factory.BeanDefinitionStoreException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.ManagedList;
@@ -27,7 +26,6 @@ import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.CacheFactoryBean;
import org.springframework.data.gemfire.GemfireBeanPostProcessor;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.util.xml.DomUtils;
@@ -54,10 +52,6 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
super.doParse(element, builder);
// BeanDefinition gemfirePostProcessor = BeanDefinitionBuilder.genericBeanDefinition(GemfireBeanPostProcessor.class).getBeanDefinition();
// parserContext.getRegistry().registerBeanDefinition(GemfireBeanPostProcessor.class.getName(), gemfirePostProcessor);
ParsingUtils.setPropertyValue(element, builder, "cache-xml-location", "cacheXml");
ParsingUtils.setPropertyReference(element, builder, "properties-ref", "properties");
ParsingUtils.setPropertyReference(element, builder, "pdx-serializer-ref", "pdxSerializer");

View File

@@ -61,11 +61,10 @@ abstract class AbstractFunctionExecutionBeanDefinitionBuilder {
builder.addConstructorArgReference(functionTemplateName);
// builder.addConstructorArgValue(functionTemplate);
return builder.getBeanDefinition();
builder.addPropertyValue("functionId", (String)configuration.getAttribute("id"));
return builder.getBeanDefinition();
}
/*

View File

@@ -76,8 +76,6 @@ class AnnotationFunctionExecutionConfigurationSource implements FunctionExecutio
this.attributes = new AnnotationAttributes(metadata.getAnnotationAttributes(EnableGemfireFunctionExecutions.class.getName()));
this.metadata = metadata;
}
@@ -135,7 +133,9 @@ class AnnotationFunctionExecutionConfigurationSource implements FunctionExecutio
Set<ScannedGenericBeanDefinition> result = new HashSet<ScannedGenericBeanDefinition>();
for (String basePackage : getBasePackages()) {
logger.debug("scanning package " + basePackage);
if (logger.isDebugEnabled()) {
logger.debug("scanning package " + basePackage);
}
Collection<BeanDefinition> components = scanner.findCandidateComponents(basePackage);
for (BeanDefinition definition : components) {
result.add((ScannedGenericBeanDefinition)definition);

View File

@@ -41,8 +41,6 @@ public class FunctionExecutionBeanDefinitionRegistrar implements ImportBeanDefin
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry registry) {
logger.debug("registering bean definitions...");
ResourceLoader resourceLoader = new DefaultResourceLoader();
AnnotationFunctionExecutionConfigurationSource configurationSource = new AnnotationFunctionExecutionConfigurationSource(

View File

@@ -12,6 +12,8 @@
*/
package org.springframework.data.gemfire.function.config;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;
@@ -29,8 +31,8 @@ public class GemfireFunctionPostBeanProcessorRegistrar implements ImportBeanDefi
*/
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// TODO Auto-generated method stub
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(GemfireFunctionBeanPostProcessor.class);
BeanDefinitionReaderUtils.registerWithGeneratedName(builder.getBeanDefinition(), registry);
}
}

View File

@@ -134,7 +134,7 @@ public class GemfireFunctionProxyFactoryBean implements FactoryBean<Object>, Met
* Optional to set a default function Id for a single method interface with no {code}@FunctionId{code} annotations
* @param functionId
*/
protected void setFunctionId(String functionId) {
public void setFunctionId(String functionId) {
this.functionId = functionId;
}

View File

@@ -27,6 +27,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.gemstone.gemfire.cache.Cache;
/**
* Integration test for declarable support (and GEF bean factory locator).
@@ -42,6 +44,7 @@ public class DeclarableSupportTest {
@Test
public void testUserObject() throws Exception {
ctx.getBean(Cache.class);
assertNotNull(UserObject.THIS);
UserObject obj = UserObject.THIS;
assertSame(ctx, obj.getBeanFactory());

View File

@@ -47,7 +47,6 @@ public class SubRegionTest extends RecreatingContextTest {
CacheFactoryBean cfb = new CacheFactoryBean();
cfb.setBeanName("gemfireCache");
cfb.setUseBeanFactoryLocator(false);
cfb.afterPropertiesSet();
GemFireCache cache = cfb.getObject();
RegionFactoryBean rfb = new ReplicatedRegionFactoryBean();
rfb.setCache(cache);

View File

@@ -69,7 +69,7 @@ public class FunctionExecutionClientCacheTests {
@ImportResource("/org/springframework/data/gemfire/function/config/FunctionExecutionCacheClientTests-context.xml")
@EnableGemfireFunctionExecutions (basePackages = "org.springframework.data.gemfire.function.config.three",
excludeFilters = {
@ComponentScan.Filter(type=FilterType.ANNOTATION, value=OnRegion.class)/*,
/*@ComponentScan.Filter(type=FilterType.ANNOTATION, value=OnRegion.class),
@ComponentScan.Filter(type=FilterType.ANNOTATION, value=OnServer.class)*/
}
)

View File

@@ -15,8 +15,6 @@ package org.springframework.data.gemfire.function.config;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertSame;
import java.util.Set;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -24,7 +22,6 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import org.springframework.data.gemfire.TestUtils;
import org.springframework.data.gemfire.function.config.EnableGemfireFunctionExecutions;
import org.springframework.data.gemfire.function.config.two.TestOnRegionFunction;
import org.springframework.data.gemfire.function.execution.GemfireOnRegionFunctionTemplate;
import org.springframework.data.gemfire.function.execution.OnRegionFunctionProxyFactoryBean;
@@ -32,8 +29,6 @@ import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.gemstone.gemfire.cache.Region;
import com.gemstone.gemfire.cache.client.ClientCache;
import com.gemstone.gemfire.cache.client.Pool;
/**
* @author David Turanski

View File

@@ -49,7 +49,6 @@ public class GemfireRepositoriesRegistrarIntegrationTest {
public GemFireCache cache() throws Exception {
CacheFactoryBean factory = new CacheFactoryBean();
factory.afterPropertiesSet();
return factory.getObject();
}

View File

@@ -43,7 +43,6 @@ public abstract class AbstractRegionFactoryBeanTest {
CacheFactoryBean cfb = new CacheFactoryBean();
cfb.setBeanName("gemfireCache");
cfb.setUseBeanFactoryLocator(false);
cfb.afterPropertiesSet();
cache = cfb.getObject();
}

View File

@@ -2,12 +2,12 @@
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<gfe:cache cache-xml-location="classpath:cache-with-declarable.xml"/>
<bean id="cache-with-declarable" class="org.springframework.data.gemfire.CacheFactoryBean">
<property name="cacheXml" value="classpath:cache-with-declarable.xml"/>
</bean>
<bean id="bean" class="java.lang.Object"/>
<bean abstract="true" class="org.springframework.data.gemfire.UserObject" p:prop1="Enescu" p:prop2-ref="bean"/>