SGF-441 - Fix possible CacheClosedException in ClientCacheFactoryBean onApplicationEvent(:ContextRefreshedEvent) when the ClientCache initialization is lazy.
(cherry picked from commit f645e7d1a4ea1954c21aa2416b46669d97f4e18d) Signed-off-by: John Blum <jblum@pivotal.io>
This commit is contained in:
@@ -38,6 +38,7 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.dao.InvalidDataAccessApiUsageException;
|
||||
import org.springframework.data.gemfire.test.AbstractMockerySupport;
|
||||
import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
@@ -66,13 +67,14 @@ import com.gemstone.gemfire.cache.query.TypeMismatchException;
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.data.gemfire.GemfireTemplate
|
||||
* @see org.springframework.data.gemfire.test.AbstractMockerySupport
|
||||
* @see org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations="basic-template.xml", initializers=GemfireTestApplicationContextInitializer.class)
|
||||
@ContextConfiguration(locations = "basic-template.xml", initializers = GemfireTestApplicationContextInitializer.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class GemfireTemplateTest {
|
||||
public class GemfireTemplateTest extends AbstractMockerySupport {
|
||||
|
||||
private static final String MULTI_QUERY = "SELECT * FROM /simple";
|
||||
private static final String SINGLE_QUERY = "(SELECT * FROM /simple).size";
|
||||
@@ -86,17 +88,19 @@ public class GemfireTemplateTest {
|
||||
@Before
|
||||
@SuppressWarnings("rawtypes")
|
||||
public void setUp() throws FunctionDomainException, TypeMismatchException, NameResolutionException, QueryInvocationTargetException {
|
||||
QueryService queryService = simple.getRegionService().getQueryService();
|
||||
Query singleQuery = mock(Query.class);
|
||||
if (isMocking()) {
|
||||
QueryService queryService = simple.getRegionService().getQueryService();
|
||||
Query singleQuery = mock(Query.class);
|
||||
|
||||
when(singleQuery.execute(any(Object[].class))).thenReturn(0);
|
||||
when(queryService.newQuery(SINGLE_QUERY)).thenReturn(singleQuery);
|
||||
when(singleQuery.execute(any(Object[].class))).thenReturn(0);
|
||||
when(queryService.newQuery(SINGLE_QUERY)).thenReturn(singleQuery);
|
||||
|
||||
Query multipleQuery = mock(Query.class);
|
||||
SelectResults selectResults = mock(SelectResults.class);
|
||||
Query multipleQuery = mock(Query.class);
|
||||
SelectResults selectResults = mock(SelectResults.class);
|
||||
|
||||
when(multipleQuery.execute(any(Object[].class))).thenReturn(selectResults);
|
||||
when(queryService.newQuery(MULTI_QUERY)).thenReturn(multipleQuery);
|
||||
when(multipleQuery.execute(any(Object[].class))).thenReturn(selectResults);
|
||||
when(queryService.newQuery(MULTI_QUERY)).thenReturn(multipleQuery);
|
||||
}
|
||||
}
|
||||
|
||||
@After
|
||||
|
||||
@@ -681,9 +681,21 @@ public class ClientCacheFactoryBeanTest {
|
||||
verify(mockClientCache, never()).getDistributedSystem();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void isReadyForEventsIsFalseWhenClientCacheNotInitialized() {
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean() {
|
||||
@Override protected <T extends GemFireCache> T fetchCache() {
|
||||
throw new CacheClosedException("test");
|
||||
}
|
||||
};
|
||||
|
||||
assertThat(clientCacheFactoryBean.getReadyForEvents(), is(nullValue()));
|
||||
assertThat(clientCacheFactoryBean.isReadyForEvents(), is(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SuppressWarnings("unchecked")
|
||||
public void isReadyForEventsIsTrueWhenDurableClientIdSet() {
|
||||
public void isReadyForEventsIsTrueWhenDurableClientIdIsSet() {
|
||||
final ClientCache mockClientCache = mockClientCache("TestDurableClientId");
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean() {
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2010-2013 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.CoreMatchers.equalTo;
|
||||
import static org.hamcrest.CoreMatchers.is;
|
||||
import static org.hamcrest.CoreMatchers.notNullValue;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.util.Properties;
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
/**
|
||||
* The LazyInitializedClientCacheIntegrationTest class is a test suite of test cases testing the proper behavior a
|
||||
* lazy initialized ClientCache by the SDG ClientCacheFactoryBean when the ClientCache instance is "looked up"
|
||||
* in fetchCache() to ascertain whether the client is durable and readyForEvents needs to be signaled or not.
|
||||
*
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.context.annotation.Bean
|
||||
* @see org.springframework.context.annotation.Configuration
|
||||
* @see org.springframework.data.gemfire.client.ClientCacheFactoryBean
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @link https://jira.spring.io/browse/SGF-441
|
||||
* @since 1.0.0
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(classes = LazyInitializedClientCacheIntegrationTest.GemFireConfiguration.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class LazyInitializedClientCacheIntegrationTest {
|
||||
|
||||
@Resource(name = "&clientCache")
|
||||
private ClientCacheFactoryBean clientCacheFactoryBean;
|
||||
|
||||
@Autowired
|
||||
private Properties gemfireProperties;
|
||||
|
||||
@Test
|
||||
public void clientCacheFactoryBeanConfiguration() {
|
||||
assertThat(clientCacheFactoryBean, is(notNullValue()));
|
||||
assertThat(clientCacheFactoryBean.getBeanName(), is(equalTo("clientCache")));
|
||||
assertThat(clientCacheFactoryBean.isLazyInitialize(), is(equalTo(true)));
|
||||
assertThat(clientCacheFactoryBean.getProperties(), is(equalTo(gemfireProperties)));
|
||||
}
|
||||
|
||||
@Configuration
|
||||
public static class GemFireConfiguration {
|
||||
|
||||
@Bean
|
||||
public Properties gemfireProperties() {
|
||||
Properties gemfireProperties = new Properties();
|
||||
gemfireProperties.setProperty("name", LazyInitializedClientCacheIntegrationTest.class.getSimpleName());
|
||||
gemfireProperties.setProperty("mcast-port", "0");
|
||||
gemfireProperties.setProperty("log-level", "warning");
|
||||
return gemfireProperties;
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ClientCacheFactoryBean clientCache() {
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = new ClientCacheFactoryBean();
|
||||
clientCacheFactoryBean.setUseBeanFactoryLocator(false);
|
||||
clientCacheFactoryBean.setProperties(gemfireProperties());
|
||||
clientCacheFactoryBean.setLazyInitialize(true);
|
||||
return clientCacheFactoryBean;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -179,9 +179,9 @@ public class CacheNamespaceTest{
|
||||
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testNoBeanFactoryLocator() throws Exception {
|
||||
assertTrue(context.containsBean("no-bean-factory-locator"));
|
||||
assertTrue(context.containsBean("no-bean-factory-locator-cache"));
|
||||
|
||||
CacheFactoryBean cacheFactoryBean = context.getBean("&no-bean-factory-locator", CacheFactoryBean.class);
|
||||
CacheFactoryBean cacheFactoryBean = context.getBean("&no-bean-factory-locator-cache", CacheFactoryBean.class);
|
||||
|
||||
assertThat(ReflectionTestUtils.getField(cacheFactoryBean, "beanFactoryLocator"), is(nullValue()));
|
||||
|
||||
@@ -189,7 +189,7 @@ public class CacheNamespaceTest{
|
||||
|
||||
try {
|
||||
assertNotNull(beanFactoryLocator.useBeanFactory("cache-with-name"));
|
||||
beanFactoryLocator.useBeanFactory("no-bean-factory-locator");
|
||||
beanFactoryLocator.useBeanFactory("no-bean-factory-locator-cache");
|
||||
}
|
||||
finally {
|
||||
beanFactoryLocator.destroy();
|
||||
@@ -197,7 +197,7 @@ public class CacheNamespaceTest{
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNamedClientCache() throws Exception {
|
||||
public void namedClientCacheWithNoProperties() throws Exception {
|
||||
assertTrue(context.containsBean("client-cache-with-name"));
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = context.getBean("&client-cache-with-name", ClientCacheFactoryBean.class);
|
||||
@@ -211,7 +211,7 @@ public class CacheNamespaceTest{
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testClientCacheWithXml() throws Exception {
|
||||
public void clientCacheWithXmlNoProperties() throws Exception {
|
||||
assertTrue(context.containsBean("client-cache-with-xml"));
|
||||
|
||||
ClientCacheFactoryBean clientCacheFactoryBean = context.getBean("&client-cache-with-xml", ClientCacheFactoryBean.class);
|
||||
|
||||
@@ -46,7 +46,7 @@ import com.gemstone.gemfire.cache.client.PoolManager;
|
||||
* @author John Blum
|
||||
*/
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations="pool-ns.xml", initializers=GemfireTestApplicationContextInitializer.class)
|
||||
@ContextConfiguration(locations = "pool-ns.xml", initializers = GemfireTestApplicationContextInitializer.class)
|
||||
@SuppressWarnings("unused")
|
||||
public class PoolNamespaceTest {
|
||||
|
||||
@@ -117,10 +117,10 @@ public class PoolNamespaceTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testComplexPool() throws Exception {
|
||||
assertTrue(context.containsBean("complex"));
|
||||
public void testServerPool() throws Exception {
|
||||
assertTrue(context.containsBean("server"));
|
||||
|
||||
PoolFactoryBean poolFactoryBean = context.getBean("&complex", PoolFactoryBean.class);
|
||||
PoolFactoryBean poolFactoryBean = context.getBean("&server", PoolFactoryBean.class);
|
||||
|
||||
assertEquals(2000, TestUtils.readField("freeConnectionTimeout", poolFactoryBean));
|
||||
assertEquals(20000l, TestUtils.readField("idleTimeout", poolFactoryBean));
|
||||
|
||||
@@ -19,6 +19,8 @@ package org.springframework.data.gemfire.test;
|
||||
import org.springframework.data.gemfire.test.support.IdentifierSequence;
|
||||
import org.springframework.data.gemfire.test.support.StackTraceUtils;
|
||||
|
||||
import com.gemstone.gemfire.management.internal.cli.util.spring.StringUtils;
|
||||
|
||||
/**
|
||||
* The AbstractMockery class is an abstract base class supporting the creation and use of mock objects in unit tests.
|
||||
*
|
||||
@@ -30,6 +32,19 @@ public abstract class AbstractMockerySupport {
|
||||
|
||||
protected static final String NOT_IMPLEMENTED = "Not Implemented";
|
||||
|
||||
protected boolean isMocking() {
|
||||
String gemfireTestRunnerNoMock = StringUtils.trimWhitespace(System.getProperty(
|
||||
GemfireTestApplicationContextInitializer.GEMFIRE_TEST_RUNNER_DISABLED, "false"));
|
||||
|
||||
return !(Boolean.parseBoolean(gemfireTestRunnerNoMock)
|
||||
|| "yes".equalsIgnoreCase(gemfireTestRunnerNoMock)
|
||||
|| "y".equalsIgnoreCase(gemfireTestRunnerNoMock));
|
||||
}
|
||||
|
||||
protected boolean isNotMocking() {
|
||||
return !isMocking();
|
||||
}
|
||||
|
||||
protected Object getMockId() {
|
||||
StackTraceElement element = StackTraceUtils.getTestCaller();
|
||||
return (element != null ? StackTraceUtils.getCallerSimpleName(element): IdentifierSequence.nextId());
|
||||
|
||||
@@ -48,7 +48,8 @@ public class GemfireTestApplicationContextInitializer implements ApplicationCont
|
||||
|
||||
private boolean isGemFireTestRunnerDisable(final String systemPropertyValue) {
|
||||
return (Boolean.valueOf(StringUtils.trimAllWhitespace(systemPropertyValue))
|
||||
|| "yes".equalsIgnoreCase(systemPropertyValue));
|
||||
|| "yes".equalsIgnoreCase(systemPropertyValue)
|
||||
|| "y".equalsIgnoreCase(systemPropertyValue));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user