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

(cherry picked from commit 770038a3aa20c4a989689a5883f98716b4d925aa)
Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
John Blum
2016-01-27 12:53:06 -08:00
parent 37e800c70d
commit f24d8e9865
7 changed files with 487 additions and 15 deletions

View File

@@ -16,11 +16,14 @@
package org.springframework.data.gemfire.client;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.eq;
@@ -41,6 +44,7 @@ import org.junit.rules.ExpectedException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.data.gemfire.TestUtils;
import org.springframework.data.gemfire.test.support.CollectionUtils;
import org.springframework.data.util.ReflectionUtils;
import com.gemstone.gemfire.cache.client.Pool;
@@ -51,7 +55,9 @@ import com.gemstone.gemfire.cache.client.PoolFactory;
* of the PoolFactoryBean class.
*
* @author John Blum
* @see org.junit.Rule
* @see org.junit.Test
* @see org.junit.rules.ExpectedException
* @see org.mockito.Mockito
* @see org.springframework.data.gemfire.client.PoolFactoryBean
* @see com.gemstone.gemfire.cache.client.Pool
@@ -89,7 +95,7 @@ public class PoolFactoryBeanTest {
}
@Override void doDistributedSystemConnect(Properties properties) {
assertSame(gemfireProperties, properties);
assertThat(properties, is(equalTo(gemfireProperties)));
}
};
@@ -180,7 +186,8 @@ public class PoolFactoryBeanTest {
Properties expectedGemfireProperties = new Properties();
expectedGemfireProperties.setProperty("name", "testResolveGemfireProperties");
expectedGemfireProperties.setProperty("name", "resolveGemfirePropertiesTest");
clientCacheFactoryBean.setProperties(expectedGemfireProperties);
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
@@ -189,7 +196,40 @@ public class PoolFactoryBeanTest {
Properties resolvedGemfireProperties = poolFactoryBean.resolveGemfireProperties();
assertSame(expectedGemfireProperties, resolvedGemfireProperties);
assertThat(resolvedGemfireProperties, is(equalTo(expectedGemfireProperties)));
}
@Test
public void resolveMergedGemfireProperties() {
BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockBeanFactory");
ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean();
when(mockBeanFactory.getBean(eq(ClientCacheFactoryBean.class))).thenReturn(clientCacheFactoryBean);
Properties poolGemfireProperties = new Properties();
Properties expectedGemfireProperties = new Properties();
poolGemfireProperties.setProperty("name", "resolveMergedGemfirePropertiesTest");
poolGemfireProperties.setProperty("log-level", "warning");
CollectionUtils.mergePropertiesIntoMap(poolGemfireProperties, expectedGemfireProperties);
expectedGemfireProperties.setProperty("log-level", "config");
expectedGemfireProperties.setProperty("durableClientId", "123");
expectedGemfireProperties.setProperty("durableClientTimeout", "60");
clientCacheFactoryBean.setProperties(expectedGemfireProperties);
PoolFactoryBean poolFactoryBean = new PoolFactoryBean();
poolFactoryBean.setBeanFactory(mockBeanFactory);
poolFactoryBean.setProperties(poolGemfireProperties);
Properties resolvedGemfireProperties = poolFactoryBean.resolveGemfireProperties();
assertThat(resolvedGemfireProperties.getProperty("log-level"), is(equalTo("config")));
assertThat(resolvedGemfireProperties, is(equalTo(expectedGemfireProperties)));
}
@Test
@@ -203,7 +243,10 @@ public class PoolFactoryBeanTest {
poolFactoryBean.setBeanFactory(mockBeanFactory);
assertNull(poolFactoryBean.resolveGemfireProperties());
Properties gemfireProperties = poolFactoryBean.resolveGemfireProperties();
assertThat(gemfireProperties, is(notNullValue()));
assertThat(gemfireProperties.isEmpty(), is(true));
}
@Test

View File

@@ -0,0 +1,161 @@
/*
* 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 static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.any;
import static org.mockito.Matchers.anyString;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isNotNull;
import static org.mockito.Matchers.same;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.runners.MockitoJUnitRunner;
import org.mockito.stubbing.Answer;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
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;
import org.w3c.dom.NodeList;
/**
* The ClientCacheParserTest class is a test suite of test cases testing the contract and functionality of the
* ClientCacheParser class.
*
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.runners.MockitoJUnitRunner
* @since 1.8.0
*/
@RunWith(MockitoJUnitRunner.class)
public class ClientCacheParserTest {
@Mock
private Element mockElement;
@Test
@SuppressWarnings("all")
public void beanClassEqualsClientCacheFactoryBean() {
assertThat((Class<ClientCacheFactoryBean>) new ClientCacheParser().getBeanClass(mockElement),
is(equalTo(ClientCacheFactoryBean.class)));
}
@Test
public void doParseSetsPropertiesAndRegistersClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor() {
NodeList mockNodeList = mock(NodeList.class);
when(mockNodeList.getLength()).thenReturn(0);
when(mockElement.getAttribute(eq("durable-client-id"))).thenReturn("123");
when(mockElement.getAttribute(eq("durable-client-timeout"))).thenReturn("60");
when(mockElement.getAttribute(eq("keep-alive"))).thenReturn("false");
when(mockElement.getAttribute(eq("pool-name"))).thenReturn("testPool");
when(mockElement.getAttribute(eq("ready-for-events"))).thenReturn(null);
when(mockElement.getChildNodes()).thenReturn(mockNodeList);
final AtomicReference<BeanDefinition> beanDefinitionReference = new AtomicReference<BeanDefinition>(null);
final BeanDefinitionRegistry mockRegistry = mock(BeanDefinitionRegistry.class);
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) throws Throwable {
BeanDefinition beanFactoryPostProcessorBeanDefinition =
invocation.getArgumentAt(1, BeanDefinition.class);
if (ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor.class.getName().equals(
beanFactoryPostProcessorBeanDefinition.getBeanClassName())) {
beanDefinitionReference.compareAndSet(null, beanFactoryPostProcessorBeanDefinition);
}
return null;
}
}).when(mockRegistry).registerBeanDefinition(isNotNull(String.class), any(BeanDefinition.class));
when(mockRegistry.containsBeanDefinition(anyString())).thenReturn(false);
BeanDefinitionBuilder clientCacheBuilder = BeanDefinitionBuilder.genericBeanDefinition();
ClientCacheParser clientCacheParser = new ClientCacheParser() {
@Override protected BeanDefinitionRegistry getRegistry(ParserContext parserContext) {
return mockRegistry;
}
};
clientCacheParser.doParse(mockElement, null, clientCacheBuilder);
BeanDefinition clientCacheBeanDefinition = clientCacheBuilder.getBeanDefinition();
assertThat(clientCacheBeanDefinition, is(notNullValue()));
PropertyValues propertyValues = clientCacheBeanDefinition.getPropertyValues();
assertThat(propertyValues, is(notNullValue()));
assertThat((String) propertyValues.getPropertyValue("durableClientId").getValue(), is(equalTo("123")));
assertThat((String) propertyValues.getPropertyValue("durableClientTimeout").getValue(), is(equalTo("60")));
assertThat((String) propertyValues.getPropertyValue("keepAlive").getValue(), is(equalTo("false")));
assertThat((String) propertyValues.getPropertyValue("poolName").getValue(), is(equalTo("testPool")));
assertThat(propertyValues.getPropertyValue("readyForEvents"), is(nullValue()));
assertThat(beanDefinitionReference.get(), is(notNullValue()));
verify(mockElement, times(1)).getAttribute(eq("durable-client-id"));
verify(mockElement, times(1)).getAttribute(eq("durable-client-timeout"));
verify(mockElement, times(1)).getAttribute(eq("keep-alive"));
verify(mockElement, times(1)).getAttribute(eq("pool-name"));
verify(mockElement, times(1)).getAttribute(eq("ready-for-events"));
verify(mockRegistry, times(1)).registerBeanDefinition(isNotNull(String.class),
same(beanDefinitionReference.get()));
}
@Test
public void postProcessDynamicRegionSupportParsesPoolName() {
when(mockElement.getAttribute(eq("pool-name"))).thenReturn("testPool");
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
new ClientCacheParser().postProcessDynamicRegionSupport(mockElement, builder);
BeanDefinition beanDefinition = builder.getBeanDefinition();
assertThat(beanDefinition, is(notNullValue()));
assertThat(beanDefinition.getPropertyValues(), is(notNullValue()));
assertThat(beanDefinition.getPropertyValues().getPropertyValue("poolName"), is(notNullValue()));
assertThat((String) beanDefinition.getPropertyValues().getPropertyValue("poolName").getValue(), is(equalTo("testPool")));
verify(mockElement, times(1)).getAttribute(eq("pool-name"));
}
}

View File

@@ -0,0 +1,158 @@
/*
* 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 static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.nullValue;
import static org.junit.Assert.assertThat;
import static org.mockito.Matchers.eq;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.data.gemfire.client.ClientCacheFactoryBean;
import org.springframework.data.gemfire.client.PoolFactoryBean;
/**
* The ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessorTest class is a test suite of test cases testing
* the contract and functionality of the ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor class.
*
* @author John Blum
* @see org.junit.Test
* @see org.junit.runner.RunWith
* @see org.mockito.Mock
* @see org.mockito.Mockito
* @see org.mockito.runners.MockitoJUnitRunner
* @see org.springframework.data.gemfire.config.ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor
* @since 1.0.0
*/
@RunWith(MockitoJUnitRunner.class)
public class ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessorTest {
protected static final String PROPERTIES_PROPERTY_NAME_SHORTCUT =
ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor.PROPERTIES_PROPERTY_NAME;
private ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor beanFactoryPostProcessor =
new ClientCachePoolGemfirePropertiesSyncingBeanFactoryPostProcessor();
@Mock
private ConfigurableListableBeanFactory mockBeanFactory;
protected String getBeanReference(Object reference) {
return (reference instanceof RuntimeBeanReference ? ((RuntimeBeanReference) reference).getBeanName() : null);
}
protected BeanDefinition newBeanDefinition(Class<?> type) {
return BeanDefinitionBuilder.genericBeanDefinition(type).getBeanDefinition();
}
protected <T> T[] toArray(T... array) {
return array;
}
@Test
public void postProcessSyncsGemfireProperties() {
BeanDefinition objectBean = newBeanDefinition(Object.class);
BeanDefinition clientCacheBean = newBeanDefinition(ClientCacheFactoryBean.class);
clientCacheBean.getPropertyValues().addPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT,
new RuntimeBeanReference("gemfireProperties"));
BeanDefinition poolBean = newBeanDefinition(PoolFactoryBean.class);
when(mockBeanFactory.getBeanDefinitionNames()).thenReturn(toArray("objectBean", "clientCacheBean", "poolBean"));
when(mockBeanFactory.getBeanDefinition(eq("objectBean"))).thenReturn(objectBean);
when(mockBeanFactory.getBeanDefinition(eq("clientCacheBean"))).thenReturn(clientCacheBean);
when(mockBeanFactory.getBeanDefinition(eq("poolBean"))).thenReturn(poolBean);
assertThat(poolBean.getPropertyValues().getPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT), is(nullValue()));
beanFactoryPostProcessor.postProcessBeanFactory(mockBeanFactory);
assertThat(getBeanReference(poolBean.getPropertyValues().getPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT).getValue()),
is(equalTo("gemfireProperties")));
verify(mockBeanFactory, times(1)).getBeanDefinitionNames();
verify(mockBeanFactory, times(1)).getBeanDefinition(eq("objectBean"));
verify(mockBeanFactory, times(1)).getBeanDefinition(eq("clientCacheBean"));
verify(mockBeanFactory, times(1)).getBeanDefinition(eq("poolBean"));
}
@Test
public void postProcessDoesNotSyncGemfirePropertiesWhenNoClientCacheFactoryBeanIsDeclared() {
BeanDefinition poolBean = newBeanDefinition(PoolFactoryBean.class);
when(mockBeanFactory.getBeanDefinitionNames()).thenReturn(toArray("poolBean"));
when(mockBeanFactory.getBeanDefinition(eq("poolBean"))).thenReturn(poolBean);
assertThat(poolBean.getPropertyValues().getPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT), is(nullValue()));
beanFactoryPostProcessor.postProcessBeanFactory(mockBeanFactory);
assertThat(poolBean.getPropertyValues().getPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT), is(nullValue()));
verify(mockBeanFactory, times(1)).getBeanDefinitionNames();
verify(mockBeanFactory, times(1)).getBeanDefinition(eq("poolBean"));
}
@Test
public void postProcessDoesNotSyncGemfirePropertiesWhenNoPoolFactoryBeanIsDeclared() {
BeanDefinition clientCacheBean = newBeanDefinition(ClientCacheFactoryBean.class);
clientCacheBean.getPropertyValues().addPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT,
new RuntimeBeanReference("gemfireProperties"));
when(mockBeanFactory.getBeanDefinitionNames()).thenReturn(toArray("clientCacheBean"));
when(mockBeanFactory.getBeanDefinition(eq("clientCacheBean"))).thenReturn(clientCacheBean);
beanFactoryPostProcessor.postProcessBeanFactory(mockBeanFactory);
verify(mockBeanFactory, times(1)).getBeanDefinitionNames();
verify(mockBeanFactory, times(1)).getBeanDefinition(eq("clientCacheBean"));
}
@Test
public void postProcessDoesNotSyncWhenGemfirePropertiesAreUnspecified() {
BeanDefinition clientCacheBean = newBeanDefinition(ClientCacheFactoryBean.class);
BeanDefinition poolBean = newBeanDefinition(PoolFactoryBean.class);
when(mockBeanFactory.getBeanDefinitionNames()).thenReturn(toArray("clientCacheBean", "poolBean"));
when(mockBeanFactory.getBeanDefinition(eq("clientCacheBean"))).thenReturn(clientCacheBean);
when(mockBeanFactory.getBeanDefinition(eq("poolBean"))).thenReturn(poolBean);
assertThat(poolBean.getPropertyValues().getPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT), is(nullValue()));
beanFactoryPostProcessor.postProcessBeanFactory(mockBeanFactory);
assertThat(poolBean.getPropertyValues().getPropertyValue(PROPERTIES_PROPERTY_NAME_SHORTCUT), is(nullValue()));
verify(mockBeanFactory, times(1)).getBeanDefinitionNames();
verify(mockBeanFactory, times(1)).getBeanDefinition(eq("clientCacheBean"));
verify(mockBeanFactory, times(1)).getBeanDefinition(eq("poolBean"));
}
}