SGF-468 - Improve coordination between the PoolFactoryBean and ClientCacheFactoryBean when configuring and resolving the GemFire DistributedSystem.

This commit is contained in:
John Blum
2016-01-27 12:53:06 -08:00
parent 63169840fa
commit 770038a3aa
7 changed files with 487 additions and 15 deletions

View File

@@ -30,6 +30,7 @@ import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.data.gemfire.support.ConnectionEndpoint;
import org.springframework.data.gemfire.support.ConnectionEndpointList;
import org.springframework.data.gemfire.util.CollectionUtils;
import org.springframework.data.gemfire.util.DistributedSystemUtils;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -81,6 +82,8 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
private Pool pool;
private Properties gemfireProperties;
private String beanName;
private String name;
@@ -207,13 +210,16 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
* @see java.util.Properties
*/
protected Properties resolveGemfireProperties() {
gemfireProperties = (gemfireProperties != null ? gemfireProperties : new Properties());
try {
ClientCacheFactoryBean clientCacheFactoryBean = beanFactory.getBean(ClientCacheFactoryBean.class);
return clientCacheFactoryBean.resolveProperties();
CollectionUtils.mergePropertiesIntoMap(clientCacheFactoryBean.resolveProperties(), gemfireProperties);
}
catch (Exception ignore) {
return null;
}
return gemfireProperties;
}
/**
@@ -317,6 +323,10 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
this.pingInterval = pingInterval;
}
public void setProperties(Properties gemfireProperties) {
this.gemfireProperties = gemfireProperties;
}
public void setPrSingleHopEnabled(boolean prSingleHopEnabled) {
this.prSingleHopEnabled = prSingleHopEnabled;
}

View File

@@ -22,6 +22,7 @@ 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.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.ManagedList;
import org.springframework.beans.factory.support.ManagedMap;
import org.springframework.beans.factory.xml.AbstractSimpleBeanDefinitionParser;
@@ -42,6 +43,7 @@ import com.gemstone.gemfire.internal.datasource.ConfigProperty;
* @author Costin Leau
* @author Oliver Gierke
* @author David Turanski
* @author John Blum
*/
class CacheParser extends AbstractSimpleBeanDefinitionParser {
@@ -54,7 +56,7 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
super.doParse(element, builder);
registerCustomGemFireBeanFactoryPostProcessors(parserContext);
registerGemFireBeanFactoryPostProcessors(getRegistry(parserContext));
ParsingUtils.setPropertyValue(element, builder, "cache-xml-location", "cacheXml");
ParsingUtils.setPropertyReference(element, builder, "properties-ref", "properties");
@@ -113,9 +115,15 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
parseJndiBindings(element, builder);
}
private void registerCustomGemFireBeanFactoryPostProcessors(final ParserContext parserContext) {
/* (non-Javadoc) */
protected BeanDefinitionRegistry getRegistry(ParserContext parserContext) {
return parserContext.getRegistry();
}
/* (non-Javadoc) */
void registerGemFireBeanFactoryPostProcessors(BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils.registerWithGeneratedName(BeanDefinitionBuilder.genericBeanDefinition(
CustomEditorRegistrationBeanFactoryPostProcessor.class).getBeanDefinition(), parserContext.getRegistry());
CustomEditorRegistrationBeanFactoryPostProcessor.class).getBeanDefinition(), registry);
}
private void parsePdxDiskStore(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
@@ -124,14 +132,14 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
final String pdxDiskStoreName = element.getAttribute("pdx-disk-store");
if (!StringUtils.isEmpty(pdxDiskStoreName)) {
registerPdxDiskStoreAwareBeanFactoryPostProcessor(parserContext, pdxDiskStoreName);
registerPdxDiskStoreAwareBeanFactoryPostProcessor(getRegistry(parserContext), pdxDiskStoreName);
}
}
private void registerPdxDiskStoreAwareBeanFactoryPostProcessor(ParserContext parserContext, String pdxDiskStoreName) {
/* (non-Javadoc) */
void registerPdxDiskStoreAwareBeanFactoryPostProcessor(BeanDefinitionRegistry registry, String pdxDiskStoreName) {
BeanDefinitionReaderUtils.registerWithGeneratedName(
createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition(pdxDiskStoreName),
parserContext.getRegistry());
createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition(pdxDiskStoreName), registry);
}
private AbstractBeanDefinition createPdxDiskStoreAwareBeanFactoryPostProcessorBeanDefinition(String pdxDiskStoreName) {
@@ -181,8 +189,7 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
}
/**
* @param dynamicRegionSupport BDB for &lt;dynamic-region-factory&gt;
* element
* @param dynamicRegionSupport BDB for &lt;dynamic-region-factory&gt; element.
*/
protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) {
}

View File

@@ -17,6 +17,8 @@
package org.springframework.data.gemfire.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.beans.factory.xml.ParserContext;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.w3c.dom.Element;
@@ -27,6 +29,7 @@ import org.w3c.dom.Element;
* @author Costin Leau
* @author David Turanski
* @author Lyndon Adams
* @author John Blum
*/
class ClientCacheParser extends CacheParser {
@@ -43,10 +46,18 @@ class ClientCacheParser extends CacheParser {
ParsingUtils.setPropertyValue(element, builder, "keep-alive");
ParsingUtils.setPropertyValue(element, builder, "pool-name");
ParsingUtils.setPropertyValue(element, builder, "ready-for-events");
registerClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor(getRegistry(parserContext));
}
/* (non-Javadoc) */
void registerClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor(BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils.registerWithGeneratedName(BeanDefinitionBuilder.genericBeanDefinition(
ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor.class).getBeanDefinition(), registry);
}
@Override
protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) {
ParsingUtils.setPropertyValue(element, dynamicRegionSupport, "pool-name");
}
}

View File

@@ -0,0 +1,82 @@
/*
* Copyright 2012 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.BeansException;
import org.springframework.beans.PropertyValue;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.client.PoolFactoryBean;
import org.springframework.util.StringUtils;
/**
* The ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor class is a Spring {@link BeanFactoryPostProcessor}
* implementation responsible for making sure the GemFire {@link java.util.Properties} between the GemFire ClientCache
* and GemFire Pool are identical.
*
* @author John Blum
* @see org.springframework.beans.factory.config.BeanDefinition
* @see org.springframework.beans.factory.config.BeanFactoryPostProcessor
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
* @see org.springframework.data.gemfire.client.PoolFactoryBean
* @since 1.8.0
*/
@SuppressWarnings("unused")
class ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
protected static final String PROPERTIES_PROPERTY_NAME = "properties";
/**
* Post processes the given {@link ConfigurableListableBeanFactory} by syncing the gemfire.properties used
* to configure the GemFire Distributed System constructed by the {@link PoolFactoryBean} during Pool creation
* and resolved by the {@link ClientCacheFactoryBean} during ClientCache creation.
*
* @param beanFactory the {@link ConfigurableListableBeanFactory} to post process.
* @throws BeansException if errors occur during post processing.
* @see org.springframework.beans.factory.config.ConfigurableListableBeanFactory
*/
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition poolFactoryBeanDefinition = null;
String gemfirePropertiesBeanName = null;
for (String beanName : beanFactory.getBeanDefinitionNames()) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
if (ClientCacheFactoryBean.class.getName().equals(beanDefinition.getBeanClassName())) {
PropertyValue gemfirePropertiesPropertyValue = beanDefinition.getPropertyValues()
.getPropertyValue(PROPERTIES_PROPERTY_NAME);
gemfirePropertiesBeanName = (gemfirePropertiesPropertyValue != null
? ((RuntimeBeanReference) gemfirePropertiesPropertyValue.getValue()).getBeanName() : null);
}
else if (PoolFactoryBean.class.getName().equals(beanDefinition.getBeanClassName())) {
poolFactoryBeanDefinition = beanDefinition;
}
}
if (poolFactoryBeanDefinition != null && StringUtils.hasText(gemfirePropertiesBeanName)) {
poolFactoryBeanDefinition.getPropertyValues().add(PROPERTIES_PROPERTY_NAME,
new RuntimeBeanReference(gemfirePropertiesBeanName));
}
}
}