From f0d5b7cf252c06a352e842180e05212888e9f3a4 Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 16 Feb 2016 18:46:24 -0800 Subject: [PATCH] SGF-473 - Allow a Spring-configured ClientCache to be constructed without a Pool. (cherry picked from commit b385dbc25e6554e023c416f02ad8f69b9c6d3f11) Signed-off-by: John Blum --- .../client/ClientCacheFactoryBean.java | 23 ++- .../client/ClientCacheFactoryBeanTest.java | 45 +++--- .../LocalOnlyClientCacheIntegrationTest.java | 140 ++++++++++++++++++ 3 files changed, 168 insertions(+), 40 deletions(-) create mode 100644 src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java diff --git a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java index 61fdb956..f48335ef 100644 --- a/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java +++ b/src/main/java/org/springframework/data/gemfire/client/ClientCacheFactoryBean.java @@ -18,7 +18,7 @@ package org.springframework.data.gemfire.client; import java.util.Properties; -import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.beans.BeansException; import org.springframework.context.ApplicationListener; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.data.gemfire.CacheFactoryBean; @@ -202,20 +202,19 @@ public class ClientCacheFactoryBean extends CacheFactoryBean implements Applicat localPool = PoolManager.find(poolName); if (localPool == null) { - try { - if (StringUtils.hasText(poolName) && getBeanFactory().isTypeMatch(poolName, Pool.class)) { - localPool = getBeanFactory().getBean(poolName, Pool.class); - } - else { + if (StringUtils.hasText(poolName) && getBeanFactory().isTypeMatch(poolName, Pool.class)) { + localPool = getBeanFactory().getBean(poolName, Pool.class); + } + else { + try { localPool = getBeanFactory().getBean(Pool.class); this.poolName = localPool.getName(); } - } - catch (Exception e) { - throw new BeanInitializationException(String.format( - "no bean of type '%1$s' having name '%2$s' was found%3$s", Pool.class.getName(), poolName, - (GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME.equals(poolName) - ? "; a ClientCache requires a Pool" : "")), e); + catch (BeansException ignore) { + log.info(String.format("no bean of type '%1$s' having name '%2$s' was found", + Pool.class.getName(), (StringUtils.hasText(poolName) ? poolName + : GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME))); + } } } } diff --git a/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java b/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java index ab41632b..cd538c69 100644 --- a/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java +++ b/src/test/java/org/springframework/data/gemfire/client/ClientCacheFactoryBeanTest.java @@ -29,6 +29,7 @@ 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.anyString; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; @@ -41,12 +42,10 @@ import java.util.Properties; import org.junit.Test; import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.BeanInitializationException; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; import org.springframework.context.event.ContextRefreshedEvent; import org.springframework.data.gemfire.TestUtils; -import org.springframework.data.gemfire.config.GemfireConstants; import org.springframework.data.gemfire.util.DistributedSystemUtils; -import org.springframework.util.ObjectUtils; import com.gemstone.gemfire.cache.CacheClosedException; import com.gemstone.gemfire.cache.GemFireCache; @@ -433,37 +432,27 @@ public class ClientCacheFactoryBeanTest { verify(mockClientCacheFactory, never()).setPoolThreadLocalConnections(eq(false)); } - @Test(expected = BeanInitializationException.class) + @Test public void resolveUnresolvablePool() { + BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory"); ClientCacheFactory mockClientCacheFactory = mock(ClientCacheFactory.class, "MockGemFireClientCacheFactory"); - try { - BeanFactory mockBeanFactory = mock(BeanFactory.class, "MockSpringBeanFactory"); + when(mockBeanFactory.getBean(eq(Pool.class))).thenThrow(new NoSuchBeanDefinitionException("TEST")); - when(mockBeanFactory.isTypeMatch(eq(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME), eq(Pool.class))) - .thenReturn(true); - when(mockBeanFactory.getBean(eq(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME), eq(Pool.class))) - .thenThrow(new IllegalArgumentException("TEST")); + ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); - ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean(); + clientCacheFactoryBean.setBeanFactory(mockBeanFactory); - clientCacheFactoryBean.setBeanFactory(mockBeanFactory); - clientCacheFactoryBean.setPoolName(GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME); - clientCacheFactoryBean.setReadyForEvents(false); - clientCacheFactoryBean.createCache(mockClientCacheFactory); - } - catch (BeanInitializationException expected) { - assertTrue(expected.getMessage(), expected.getMessage().startsWith(String.format( - "no bean of type '%1$s' having name '%2$s' was found; a ClientCache requires a Pool", - Pool.class.getName(), GemfireConstants.DEFAULT_GEMFIRE_POOL_NAME))); - assertTrue(String.format("Cause was: %1$s!", ObjectUtils.nullSafeClassName(expected.getCause())), - expected.getCause() instanceof IllegalArgumentException); - assertEquals("TEST", expected.getCause().getMessage()); - throw expected; - } - finally { - verify(mockClientCacheFactory, never()).create(); - } + assertThat(clientCacheFactoryBean.getPoolName(), is(nullValue())); + + clientCacheFactoryBean.createCache(mockClientCacheFactory); + + assertThat(clientCacheFactoryBean.getPoolName(), is(nullValue())); + + verify(mockBeanFactory, never()).isTypeMatch(anyString(), eq(Pool.class)); + verify(mockBeanFactory, never()).getBean(anyString(), eq(Pool.class)); + verify(mockBeanFactory, times(1)).getBean(eq(Pool.class)); + verify(mockClientCacheFactory, times(1)).create(); } @Test diff --git a/src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java b/src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java new file mode 100644 index 00000000..949da941 --- /dev/null +++ b/src/test/java/org/springframework/data/gemfire/client/LocalOnlyClientCacheIntegrationTest.java @@ -0,0 +1,140 @@ +/* + * 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.client; + +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 java.util.Properties; +import javax.annotation.Resource; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.PropertySourcesPlaceholderConfigurer; +import org.springframework.data.gemfire.RegionAttributesFactoryBean; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; + +import com.gemstone.gemfire.cache.DataPolicy; +import com.gemstone.gemfire.cache.Region; +import com.gemstone.gemfire.cache.RegionAttributes; +import com.gemstone.gemfire.cache.client.ClientCache; +import com.gemstone.gemfire.cache.client.ClientRegionShortcut; + +/** + * The LocalOnlyClientCacheIntegrationTest class... + * + * @author John Blum + * @since 1.0.0 + */ +@RunWith(SpringJUnit4ClassRunner.class) +@ContextConfiguration +@SuppressWarnings("unused") +public class LocalOnlyClientCacheIntegrationTest { + + @Resource(name = "Example") + private Region example; + + @Before + public void assertRegionDetails() { + assertThat(example, is(notNullValue())); + assertThat(example.getName(), is(equalTo("Example"))); + assertThat(example.getFullPath(), is(equalTo(String.format("%1$sExample", Region.SEPARATOR)))); + assertThat(example.getAttributes(), is(notNullValue())); + assertThat(example.getAttributes().getDataPolicy(), is(equalTo(DataPolicy.NORMAL))); + assertThat(example.getAttributes().getKeyConstraint(), is(equalTo(Long.class))); + assertThat(example.getAttributes().getValueConstraint(), is(equalTo(String.class))); + } + + @Test + public void getAndPutsAreSuccessful() { + assertThat(example.put(1l, "one"), is(nullValue())); + assertThat(example.put(2l, "two"), is(nullValue())); + assertThat(example.put(3l, "three"), is(nullValue())); + assertThat(example.get(1l), is(equalTo("one"))); + assertThat(example.get(2l), is(equalTo("two"))); + assertThat(example.get(3l), is(equalTo("three"))); + assertThat(example.get(0l), is(nullValue())); + assertThat(example.get(4l), is(nullValue())); + } + + @Configuration + static class GemFireClientCacheConfiguration { + + @Bean + PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() { + return new PropertySourcesPlaceholderConfigurer(); + } + + @Bean + Properties gemfireProperties(@Value("${spring.gemfire.log.level:config}") String logLevel) { + Properties gemfireProperties = new Properties(); + + gemfireProperties.setProperty("name", LocalOnlyClientCacheIntegrationTest.class.getSimpleName()); + gemfireProperties.setProperty("log-level", logLevel); + + return gemfireProperties; + } + + @Bean + ClientCacheFactoryBean gemfireCache(@Qualifier("gemfireProperties") Properties gemfireProperties) { + ClientCacheFactoryBean gemfireCache = new ClientCacheFactoryBean(); + + gemfireCache.setClose(true); + gemfireCache.setProperties(gemfireProperties); + gemfireCache.setUseBeanFactoryLocator(false); + + return gemfireCache; + } + + @Bean(name = "Example") + ClientRegionFactoryBean exampleRegion(ClientCache gemfireCache, + RegionAttributes exampleAttributes) { + + ClientRegionFactoryBean exampleRegion = new ClientRegionFactoryBean(); + + exampleRegion.setCache(gemfireCache); + exampleRegion.setAttributes(exampleAttributes); + exampleRegion.setName("Example"); + exampleRegion.setPersistent(false); + exampleRegion.setShortcut(ClientRegionShortcut.LOCAL); + + return exampleRegion; + } + + @Bean + @SuppressWarnings("unchecked") + RegionAttributesFactoryBean exampleRegionAttributes() { + RegionAttributesFactoryBean exampleRegionAttributes = new RegionAttributesFactoryBean(); + + exampleRegionAttributes.setKeyConstraint(Long.class); + exampleRegionAttributes.setValueConstraint(String.class); + + return exampleRegionAttributes; + } + } + +}