SGF-434 - Add a durable GemFire client cache test to assert proper behavior by SDG.
This commit is contained in:
@@ -78,7 +78,7 @@ import com.gemstone.gemfire.pdx.PdxSerializer;
|
||||
* @see org.springframework.dao.support.PersistenceExceptionTranslator
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, FactoryBean<Cache>,
|
||||
public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware, BeanNameAware, FactoryBean<GemFireCache>,
|
||||
InitializingBean, DisposableBean, PersistenceExceptionTranslator {
|
||||
|
||||
protected boolean close = true;
|
||||
@@ -96,7 +96,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
protected Boolean pdxReadSerialized;
|
||||
protected Boolean useClusterConfiguration;
|
||||
|
||||
protected Cache cache;
|
||||
protected GemFireCache cache;
|
||||
|
||||
protected ClassLoader beanClassLoader;
|
||||
|
||||
@@ -226,7 +226,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
|
||||
/* (non-Javadoc) */
|
||||
private Cache init() throws Exception {
|
||||
private GemFireCache init() throws Exception {
|
||||
initBeanFactoryLocator();
|
||||
|
||||
final ClassLoader currentThreadContextClassLoader = Thread.currentThread().getContextClassLoader();
|
||||
@@ -497,7 +497,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
Cache localCache = fetchCache();
|
||||
|
||||
if (localCache != null && !localCache.isClosed()) {
|
||||
localCache.close();
|
||||
close(localCache);
|
||||
}
|
||||
|
||||
this.cache = null;
|
||||
@@ -509,6 +509,10 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
}
|
||||
|
||||
protected void close(GemFireCache cache) {
|
||||
cache.close();
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataAccessException translateExceptionIfPossible(RuntimeException e) {
|
||||
if (e instanceof GemFireException) {
|
||||
@@ -844,7 +848,7 @@ public class CacheFactoryBean implements BeanClassLoaderAware, BeanFactoryAware,
|
||||
}
|
||||
|
||||
@Override
|
||||
public Cache getObject() throws Exception {
|
||||
public GemFireCache getObject() throws Exception {
|
||||
return init();
|
||||
}
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.springframework.util.ClassUtils;
|
||||
|
||||
import com.gemstone.gemfire.cache.CacheFactory;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.client.ClientCacheFactory;
|
||||
|
||||
/**
|
||||
* GemfireUtils is an abstract utility class encapsulating common functionality to access features and capabilities
|
||||
@@ -32,10 +33,31 @@ import com.gemstone.gemfire.cache.Region;
|
||||
* @see org.springframework.data.gemfire.util.DistributedSystemUtils
|
||||
* @since 1.3.3
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public abstract class GemfireUtils extends DistributedSystemUtils {
|
||||
|
||||
public final static String GEMFIRE_VERSION = CacheFactory.getVersion();
|
||||
|
||||
public static boolean closeCache() {
|
||||
try {
|
||||
CacheFactory.getAnyInstance().close();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean closeClientCache() {
|
||||
try {
|
||||
ClientCacheFactory.getAnyInstance().close();
|
||||
return true;
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isGemfireVersionGreaterThanEqual(double expectedVersion) {
|
||||
double actualVersion = Double.parseDouble(GEMFIRE_VERSION.substring(0, 3));
|
||||
return actualVersion >= expectedVersion;
|
||||
|
||||
@@ -16,10 +16,11 @@
|
||||
|
||||
package org.springframework.data.gemfire.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.springframework.beans.factory.BeanInitializationException;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.event.ContextRefreshedEvent;
|
||||
import org.springframework.data.gemfire.CacheFactoryBean;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.config.GemfireConstants;
|
||||
@@ -40,19 +41,26 @@ import com.gemstone.gemfire.pdx.PdxSerializer;
|
||||
* @author Costin Leau
|
||||
* @author Lyndon Adams
|
||||
* @author John Blum
|
||||
* @see org.springframework.context.ApplicationListener
|
||||
* @see org.springframework.context.event.ContextRefreshedEvent
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCacheFactory
|
||||
* @see com.gemstone.gemfire.cache.client.Pool
|
||||
* @see com.gemstone.gemfire.cache.client.PoolManager
|
||||
* @see com.gemstone.gemfire.distributed.DistributedSystem
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
public class ClientCacheFactoryBean extends CacheFactoryBean implements ApplicationListener<ContextRefreshedEvent> {
|
||||
|
||||
protected Boolean keepAlive = false;
|
||||
|
||||
protected Boolean readyForEvents = false;
|
||||
|
||||
private Pool pool;
|
||||
|
||||
private String poolName;
|
||||
protected String poolName;
|
||||
|
||||
@Override
|
||||
protected void postProcessPropertiesBeforeInitialization(Properties gemfireProperties) {
|
||||
@@ -213,18 +221,14 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
/**
|
||||
* Register for events after Pool and Regions have been created and iff non-durable client...
|
||||
*
|
||||
* @param <T> parameterized Class type extension of GemFireCache.
|
||||
* @param cache the GemFire cache instance to process.
|
||||
* @return the processed cache instance after ready for events.
|
||||
* @throws java.io.IOException if an error occurs during post processing.
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean#postProcess(com.gemstone.gemfire.cache.GemFireCache)
|
||||
* @see #readyForEvents(com.gemstone.gemfire.cache.GemFireCache)
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @param event the ApplicationContextEvent fired when the ApplicationContext is refreshed.
|
||||
* @see org.springframework.context.Lifecycle#start()
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @see #readyForEvents(com.gemstone.gemfire.cache.GemFireCache)
|
||||
*/
|
||||
@Override
|
||||
protected <T extends GemFireCache> T postProcess(T cache) throws IOException {
|
||||
return readyForEvents(super.postProcess(cache));
|
||||
public void onApplicationEvent(final ContextRefreshedEvent event) {
|
||||
readyForEvents(this.cache);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -243,6 +247,11 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
return clientCache;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void close(final GemFireCache cache) {
|
||||
((ClientCache) cache).close(isKeepAlive());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setEnableAutoReconnect(final Boolean enableAutoReconnect) {
|
||||
throw new UnsupportedOperationException("Auto-reconnect is not supported on ClientCache.");
|
||||
@@ -258,6 +267,26 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
return (cache != null ? cache.getClass() : ClientCache.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether the server(s) should keep the durable client's queue alive for the duration of the timeout
|
||||
* when the client voluntarily disconnects.
|
||||
*
|
||||
* @param keepAlive a boolean value indicating to the server to keep the durable client's queues alive.
|
||||
*/
|
||||
public void setKeepAlive(Boolean keepAlive) {
|
||||
this.keepAlive = keepAlive;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the server(s) should keep the durable client's queue alive for the duration of the timeout
|
||||
* when the client voluntarily disconnects.
|
||||
*
|
||||
* @return a boolean value indicating whether the server should keep the durable client's queues alive.
|
||||
*/
|
||||
public boolean isKeepAlive() {
|
||||
return Boolean.TRUE.equals(this.keepAlive);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the pool used by this client.
|
||||
*
|
||||
@@ -278,6 +307,15 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
|
||||
this.poolName = poolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the pool name used by this client.
|
||||
*
|
||||
* @return the name of the GemFire Pool used by the GemFire Client Cache.
|
||||
*/
|
||||
public String getPoolName() {
|
||||
return poolName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the readyForEvents flag.
|
||||
*
|
||||
|
||||
@@ -49,6 +49,14 @@ import com.gemstone.gemfire.internal.cache.GemFireCacheImpl;
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.springframework.beans.factory.BeanFactory
|
||||
* @see org.springframework.beans.factory.BeanFactoryAware
|
||||
* @see org.springframework.beans.factory.DisposableBean
|
||||
* @see org.springframework.data.gemfire.RegionLookupFactoryBean
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientCache
|
||||
* @see com.gemstone.gemfire.cache.client.ClientRegionFactory
|
||||
* @see com.gemstone.gemfire.cache.client.ClientRegionShortcut
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> implements BeanFactoryAware,
|
||||
@@ -89,7 +97,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
@SuppressWarnings("all")
|
||||
protected Region<K, V> lookupFallback(GemFireCache cache, String regionName) throws Exception {
|
||||
Assert.isTrue(cache instanceof ClientCache, String.format("Unable to create Regions from %1$s!", cache));
|
||||
|
||||
@@ -298,24 +306,6 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
|
||||
public void destroy() throws Exception {
|
||||
Region<K, V> region = getObject();
|
||||
|
||||
try {
|
||||
if (region != null && !ObjectUtils.isEmpty(interests)) {
|
||||
for (Interest<K> interest : interests) {
|
||||
if (interest instanceof RegexInterest) {
|
||||
region.unregisterInterestRegex((String) interest.getKey());
|
||||
}
|
||||
else {
|
||||
region.unregisterInterest(interest.getKey());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// NOTE AdminRegion, LocalDataSet, Proxy Region and RegionCreation all throw UnsupportedOperationException;
|
||||
// however, should not really happen since Interests are validated at start/registration
|
||||
catch (UnsupportedOperationException ex) {
|
||||
log.warn("Cannot unregister cache interests", ex);
|
||||
}
|
||||
|
||||
if (region != null) {
|
||||
if (close) {
|
||||
if (!region.getRegionService().isClosed()) {
|
||||
@@ -326,8 +316,8 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
|
||||
}
|
||||
}
|
||||
}
|
||||
// TODO I think Region.close and Region.destroyRegion are mutually exclusive; thus, 1 operation (e.g. close)
|
||||
// does not cancel the other (i.e. destroy). This should just be if, not else if.
|
||||
// TODO perhaps 'destroy' should take precedence over 'close' since 'destroy' is a functional superset
|
||||
// of 'close'
|
||||
else if (destroy) {
|
||||
region.destroyRegion();
|
||||
}
|
||||
|
||||
@@ -243,18 +243,10 @@ public class PoolFactoryBean implements FactoryBean<Pool>, InitializingBean, Dis
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param name
|
||||
* the name to set
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param pool
|
||||
* the pool to set
|
||||
*/
|
||||
public void setPool(Pool pool) {
|
||||
this.pool = pool;
|
||||
}
|
||||
|
||||
@@ -38,6 +38,7 @@ class ClientCacheParser extends CacheParser {
|
||||
@Override
|
||||
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
|
||||
super.doParse(element, parserContext, builder);
|
||||
ParsingUtils.setPropertyValue(element, builder, "keep-alive", "keepAlive");
|
||||
ParsingUtils.setPropertyValue(element, builder, "pool-name", "poolName");
|
||||
ParsingUtils.setPropertyValue(element, builder, "ready-for-events");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user