Implements JIRA feature request SGF-227 adding support for GemFire 8.0's auto-reconnect functionality on forced disconnects.

This commit is contained in:
John Blum
2014-07-09 23:03:14 -07:00
parent d8896fd05b
commit 76aa819be7
12 changed files with 607 additions and 330 deletions

View File

@@ -89,6 +89,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
protected BeanFactory beanFactory;
protected Boolean copyOnRead;
protected Boolean enableAutoReconnect;
protected Boolean pdxIgnoreUnreadFields;
protected Boolean pdxPersistent;
protected Boolean pdxReadSerialized;
@@ -258,16 +259,14 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
catch (CacheClosedException ex) {
initializeDynamicRegionFactory();
Object factory = createFactory(this.properties);
Object factory = createFactory(getProperties());
// GemFire 6.6 specific options
if (isPdxSettingsSpecified()) {
Assert.isTrue(ClassUtils.isPresent("com.gemstone.gemfire.pdx.PdxSerializer", beanClassLoader),
"Cannot set PDX options since GemFire 6.6 not detected.");
applyPdxOptions(factory);
}
// fall back to cache creation
cache = (Cache) createCache(factory);
messagePrefix = "Created new";
}
@@ -275,20 +274,20 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
if (this.copyOnRead != null) {
cache.setCopyOnRead(this.copyOnRead);
}
if (gatewayConflictResolver != null) {
cache.setGatewayConflictResolver((GatewayConflictResolver) gatewayConflictResolver);
}
if (lockLease != null) {
cache.setLockLease(lockLease);
}
if (lockTimeout != null) {
cache.setLockTimeout(lockTimeout);
}
if (searchTimeout != null) {
cache.setSearchTimeout(searchTimeout);
}
if (messageSyncInterval != null) {
cache.setMessageSyncInterval(messageSyncInterval);
}
if (gatewayConflictResolver != null) {
cache.setGatewayConflictResolver((GatewayConflictResolver) gatewayConflictResolver);
if (searchTimeout != null) {
cache.setSearchTimeout(searchTimeout);
}
DistributedSystem system = cache.getDistributedSystem();
@@ -306,7 +305,7 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
cache.loadCacheXml(cacheXml.getInputStream());
if (log.isDebugEnabled()) {
log.debug("Initialized cache from " + cacheXml);
log.debug(String.format("Initialized Cache from '%1$s'.", cacheXml));
}
}
@@ -404,12 +403,12 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
return (cache != null ? cache : ((CacheFactory) factory).create());
}
protected GemFireCache fetchCache() {
return (cache != null ? cache : CacheFactory.getAnyInstance());
protected Object createFactory(Properties gemfireProperties) {
return new CacheFactory(gemfireProperties);
}
protected Object createFactory(Properties props) {
return new CacheFactory(props);
protected GemFireCache fetchCache() {
return (cache != null ? cache : CacheFactory.getAnyInstance());
}
@Override
@@ -481,6 +480,15 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
this.beanName = name;
}
/**
* Sets the cache configuration.
*
* @param cacheXml the cacheXml to set
*/
public void setCacheXml(Resource cacheXml) {
this.cacheXml = cacheXml;
}
/**
* Sets the cache properties.
*
@@ -491,12 +499,10 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
}
/**
* Sets the cache configuration.
*
* @param cacheXml the cacheXml to set
* @param lazyInitialize set to false to force cache initialization if no other bean references it
*/
public void setCacheXml(Resource cacheXml) {
this.cacheXml = cacheXml;
public void setLazyInitialize(boolean lazyInitialize) {
this.lazyInitialize = lazyInitialize;
}
/**
@@ -512,6 +518,10 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
this.useBeanFactoryLocator = usage;
}
public void setEnableAutoReconnect(final Boolean enableAutoReconnect) {
this.enableAutoReconnect = enableAutoReconnect;
}
/**
* Sets the {@link PdxSerializable} for this cache. Applicable on GemFire
* 6.6 or higher. The argument is of type object for compatibility with
@@ -701,10 +711,17 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
}
/**
* @param lazyInitialize set to false to force cache initialization if no other bean references it
* @return the beanClassLoader
*/
public void setLazyInitialize(boolean lazyInitialize) {
this.lazyInitialize = lazyInitialize;
public ClassLoader getBeanClassLoader() {
return beanClassLoader;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
}
/**
@@ -718,21 +735,15 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
* @return the properties
*/
public Properties getProperties() {
if (properties == null) {
properties = new Properties();
}
return properties;
}
/**
* @return the beanClassLoader
*/
public ClassLoader getBeanClassLoader() {
return beanClassLoader;
}
/**
* @return the beanName
*/
public String getBeanName() {
return beanName;
public Boolean getEnableAutoReconnect() {
return enableAutoReconnect;
}
/**
@@ -864,12 +875,19 @@ public class CacheFactoryBean implements BeanNameAware, BeanFactoryAware, BeanCl
return lazyInitialize;
}
protected void postProcessPropertiesBeforeInitialization(Properties gemfireProperties) {
gemfireProperties.setProperty("disable-auto-reconnect", String.valueOf(
!Boolean.TRUE.equals(getEnableAutoReconnect())));
}
/* (non-Javadoc)
* @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
*/
@Override
public void afterPropertiesSet() throws Exception {
if (!lazyInitialize) {
postProcessPropertiesBeforeInitialization(getProperties());
if (!isLazyInitialize()) {
init();
}
}

View File

@@ -86,11 +86,12 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
@Override
protected GemFireCache createCache(Object factory) {
ClientCacheFactory ccf = (ClientCacheFactory) factory;
initializePool(ccf);
ClientCacheFactory clientCacheFactory = (ClientCacheFactory) factory;
initializePool(clientCacheFactory);
// Now create the cache
GemFireCache cache = ccf.create();
GemFireCache cache = clientCacheFactory.create();
// Register for events after pool/regions been created and iff non-durable client
readyForEvents();
@@ -100,8 +101,8 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
}
@Override
protected Object createFactory(Properties props) {
return new ClientCacheFactory(props);
protected Object createFactory(Properties gemfireProperties) {
return new ClientCacheFactory(gemfireProperties);
}
@Override
@@ -109,10 +110,6 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
return ClientCacheFactory.getAnyInstance();
}
public Properties getProperties() {
return this.properties;
}
private void initializePool(ClientCacheFactory ccf) {
Pool p = pool;
@@ -189,20 +186,18 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
}
}
/**
* Inform the GemFire cluster that this client cache is ready to receive events.
*/
private void readyForEvents(){
ClientCache clientCache = ClientCacheFactory.getAnyInstance();
@Override
protected void postProcessPropertiesBeforeInitialization(final Properties gemfireProperties) {
}
if (Boolean.TRUE.equals(readyForEvents) && !clientCache.isClosed()) {
try {
clientCache.readyForEvents();
}
catch (IllegalStateException ignore) {
// Cannot be called for a non-durable client so exception is thrown.
}
}
@Override
public final Boolean getEnableAutoReconnect() {
return Boolean.FALSE;
}
@Override
public final void setEnableAutoReconnect(final Boolean enableAutoReconnect) {
throw new UnsupportedOperationException("Auto-reconnect is not supported on ClientCache.");
}
/**
@@ -235,11 +230,11 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
public void setReadyForEvents(Boolean readyForEvents){
this.readyForEvents = readyForEvents;
}
public Boolean getReadyForEvents(){
return this.readyForEvents;
}
@Override
protected void applyPdxOptions(Object factory) {
if (factory instanceof ClientCacheFactory) {
@@ -247,4 +242,20 @@ public class ClientCacheFactoryBean extends CacheFactoryBean {
}
}
/**
* Inform the GemFire cluster that this client cache is ready to receive events.
*/
private void readyForEvents(){
ClientCache clientCache = ClientCacheFactory.getAnyInstance();
if (Boolean.TRUE.equals(readyForEvents) && !clientCache.isClosed()) {
try {
clientCache.readyForEvents();
}
catch (IllegalStateException ignore) {
// cannot be called for a non-durable client so exception is thrown
}
}
}
}

View File

@@ -56,49 +56,54 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
ParsingUtils.setPropertyValue(element, builder, "cache-xml-location", "cacheXml");
ParsingUtils.setPropertyReference(element, builder, "properties-ref", "properties");
ParsingUtils.setPropertyReference(element, builder, "pdx-serializer-ref", "pdxSerializer");
parsePdxDiskStore(element, parserContext, builder);
ParsingUtils.setPropertyValue(element, builder, "pdx-persistent");
ParsingUtils.setPropertyValue(element, builder, "pdx-read-serialized");
ParsingUtils.setPropertyValue(element, builder, "pdx-ignore-unread-fields");
ParsingUtils.setPropertyValue(element, builder, "use-bean-factory-locator");
ParsingUtils.setPropertyValue(element, builder, "close");
ParsingUtils.setPropertyValue(element, builder, "copy-on-read");
ParsingUtils.setPropertyValue(element, builder, "lock-timeout");
ParsingUtils.setPropertyValue(element, builder, "lock-lease");
ParsingUtils.setPropertyValue(element, builder, "message-sync-interval");
ParsingUtils.setPropertyValue(element, builder, "search-timeout");
ParsingUtils.setPropertyValue(element, builder, "critical-heap-percentage");
ParsingUtils.setPropertyValue(element, builder, "eviction-heap-percentage");
ParsingUtils.setPropertyValue(element, builder, "close");
ParsingUtils.setPropertyValue(element, builder, "enable-auto-reconnect");
ParsingUtils.setPropertyValue(element, builder, "lock-lease");
ParsingUtils.setPropertyValue(element, builder, "lock-timeout");
ParsingUtils.setPropertyValue(element, builder, "message-sync-interval");
ParsingUtils.setPropertyReference(element, builder, "pdx-serializer-ref", "pdxSerializer");
ParsingUtils.setPropertyValue(element, builder, "pdx-read-serialized");
ParsingUtils.setPropertyValue(element, builder, "pdx-ignore-unread-fields");
ParsingUtils.setPropertyValue(element, builder, "pdx-persistent");
parsePdxDiskStore(element, parserContext, builder);
ParsingUtils.setPropertyValue(element, builder, "search-timeout");
ParsingUtils.setPropertyValue(element, builder, "lazy-init","lazyInitialize");
ParsingUtils.setPropertyValue(element, builder, "use-bean-factory-locator");
List<Element> txListeners = DomUtils.getChildElementsByTagName(element, "transaction-listener");
if (!CollectionUtils.isEmpty(txListeners)) {
ManagedList<Object> transactionListeners = new ManagedList<Object>();
for (Element txListener : txListeners) {
transactionListeners.add(ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, txListener,
builder));
transactionListeners.add(ParsingUtils.parseRefOrNestedBeanDeclaration(
parserContext, txListener, builder));
}
builder.addPropertyValue("transactionListeners", transactionListeners);
}
Element txWriter = DomUtils.getChildElementByTagName(element, "transaction-writer");
if (txWriter != null) {
builder.addPropertyValue("transactionWriter",
ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, txWriter, builder));
builder.addPropertyValue("transactionWriter", ParsingUtils.parseRefOrNestedBeanDeclaration(
parserContext, txWriter, builder));
}
Element gatewayConflictResolver = DomUtils.getChildElementByTagName(element, "gateway-conflict-resolver");
if (gatewayConflictResolver != null) {
ParsingUtils.throwExceptionIfNotGemfireV7(element.getLocalName(), "gateway-conflict-resolver",
parserContext);
builder.addPropertyValue("gatewayConflictResolver",
ParsingUtils.parseRefOrSingleNestedBeanDeclaration(parserContext, gatewayConflictResolver, builder));
ParsingUtils.throwExceptionIfNotGemfireV7(element.getLocalName(), "gateway-conflict-resolver", parserContext);
builder.addPropertyValue("gatewayConflictResolver", ParsingUtils.parseRefOrSingleNestedBeanDeclaration(
parserContext, gatewayConflictResolver, builder));
}
Element function = DomUtils.getChildElementByTagName(element, "function");
if (function != null) {
builder.addPropertyValue("functions",
ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, function, builder));
builder.addPropertyValue("functions", ParsingUtils.parseRefOrNestedBeanDeclaration(
parserContext, function, builder));
}
parseDynamicRegionFactory(element, builder);
@@ -130,6 +135,7 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
private void parseDynamicRegionFactory(Element element, BeanDefinitionBuilder builder) {
Element dynamicRegionFactory = DomUtils.getChildElementByTagName(element, "dynamic-region-factory");
if (dynamicRegionFactory != null) {
BeanDefinitionBuilder dynamicRegionSupport = buildDynamicRegionSupport(dynamicRegionFactory);
postProcessDynamicRegionSupport(element, dynamicRegionSupport);
@@ -137,35 +143,40 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
}
}
/**
* @param dynamicRegionSupport BDB for &lt;dynamic-region-factory&gt;
* element
*/
protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) {
}
private BeanDefinitionBuilder buildDynamicRegionSupport(Element dynamicRegionFactory) {
BeanDefinitionBuilder result = null;
if (dynamicRegionFactory != null) {
BeanDefinitionBuilder dynamicRegionSupport = BeanDefinitionBuilder
.genericBeanDefinition(CacheFactoryBean.DynamicRegionSupport.class);
String diskDir = dynamicRegionFactory.getAttribute("disk-dir");
if (StringUtils.hasText(diskDir)) {
dynamicRegionSupport.addPropertyValue("diskDir", diskDir);
BeanDefinitionBuilder dynamicRegionSupport = BeanDefinitionBuilder.genericBeanDefinition(
CacheFactoryBean.DynamicRegionSupport.class);
String diskDirectory = dynamicRegionFactory.getAttribute("disk-dir");
if (StringUtils.hasText(diskDirectory)) {
dynamicRegionSupport.addPropertyValue("diskDir", diskDirectory);
}
String persistent = dynamicRegionFactory.getAttribute("persistent");
if (StringUtils.hasText(persistent)) {
dynamicRegionSupport.addPropertyValue("persistent", persistent);
}
String registerInterest = dynamicRegionFactory.getAttribute("register-interest");
if (StringUtils.hasText(registerInterest)) {
dynamicRegionSupport.addPropertyValue("registerInterest", registerInterest);
}
result = dynamicRegionSupport;
return dynamicRegionSupport;
}
return result;
return null;
}
/**
* @param dynamicRegionSupport BDB for &lt;dynamic-region-factory&gt;
* element
*/
protected void postProcessDynamicRegionSupport(Element element, BeanDefinitionBuilder dynamicRegionSupport) {
}
private void parseJndiBindings(Element element, BeanDefinitionBuilder builder) {
@@ -222,11 +233,13 @@ class CacheParser extends AbstractSimpleBeanDefinitionParser {
protected String resolveId(Element element, AbstractBeanDefinition definition, ParserContext parserContext)
throws BeanDefinitionStoreException {
String name = super.resolveId(element, definition, parserContext);
if (!StringUtils.hasText(name)) {
name = GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME;
//For backward compatibility
parserContext.getRegistry().registerAlias(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME, "gemfire-cache");
// Set Cache bean alias for backwards compatibility...
parserContext.getRegistry().registerAlias(name, "gemfire-cache");
}
return name;
}

View File

@@ -117,15 +117,6 @@ Configures a data source to be bound to a JNDI context for use with Gemfire tran
</xsd:annotation>
</xsd:element>
</xsd:sequence>
<xsd:attribute name="copy-on-read" type="xsd:string"
use="optional" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether entry value retrieval methods return direct references to the entry value objects in the cache (false)
or copies of the objects (true).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="id" type="xsd:string" use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
@@ -150,6 +141,14 @@ consider using a dedicated utility such as the <util:*/> namespace and its 'prop
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="lazy-init" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Determines if the cache should be initialized automatically. Normally the cache will be lazily initialized, i.e., during creation of another bean references it.
For cases in which there are no declared dependencies on the cache, set this attribute to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="use-bean-factory-locator" type="xsd:string"
use="optional" default="true">
<xsd:annotation>
@@ -160,6 +159,45 @@ when the same cache is used in multiple application context/bean factories insid
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="close" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Determines if the cache should be closed when the application context is closed. This value is
true by default but should be set to false if deploying multiple applications in a jvm that share the
same cache instance.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="copy-on-read" type="xsd:string"
use="optional" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Controls whether entry value retrieval methods return direct references to the entry value objects in the cache (false)
or copies of the objects (true).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="critical-heap-percentage">
<xsd:annotation>
<xsd:documentation
source="com.gemstone.gemfire.cache.control.ResourceManager"><![CDATA[
Set the percentage of heap at or above which the cache is considered in danger of becoming inoperable
due to garbage collection pauses or out of memory exceptions. Changing this value can cause a LowMemoryException to
be thrown during certain cache operation. This feature requires additional VM flags to perform properly (see the
JavaDocs for com.gemstone.gemfire.cache.control.ResourceManager for more information).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="eviction-heap-percentage">
<xsd:annotation>
<xsd:documentation
source="com.gemstone.gemfire.cache.control.ResourceManager"><![CDATA[
Set the percentage of heap at or above which the eviction should begin on Regions configured for HeapLRU eviction.
This feature requires additional VM flags to perform properly (see the
JavaDocs for com.gemstone.gemfire.cache.control.ResourceManager for more information).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pdx-serializer-ref" type="xsd:string"
use="optional">
<xsd:annotation>
@@ -169,6 +207,15 @@ domain classes which are added to the cache in portable data exchange (PDX) form
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pdx-persistent" type="xsd:string"
use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Control whether the type metadata for PDX objects is persisted to disk.
Set to true if you are using persistent regions, WAN gateways or GemFire's JSON support.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pdx-disk-store" type="xsd:string"
use="optional">
<xsd:annotation>
@@ -179,15 +226,6 @@ If not set, the metadata will go in the default disk store.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pdx-persistent" type="xsd:string"
use="optional">
<xsd:annotation>
<xsd:documentation><![CDATA[
Control whether the type metadata for PDX objects is persisted to disk.
Set to true if you are using persistent regions, WAN gateways or GemFire's JSON support.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="pdx-read-serialized" type="xsd:string"
use="optional">
<xsd:annotation>
@@ -216,44 +254,6 @@ do not need to pay the cost of preserving the unread fields since you will never
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="critical-heap-percentage">
<xsd:annotation>
<xsd:documentation
source="com.gemstone.gemfire.cache.control.ResourceManager"><![CDATA[
Set the percentage of heap at or above which the cache is considered in danger of becoming inoperable
due to garbage collection pauses or out of memory exceptions. Changing this value can cause a LowMemoryException to
be thrown during certain cache operation. This feature requires additional VM flags to perform properly (see the
JavaDocs for com.gemstone.gemfire.cache.control.ResourceManager for more information).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="eviction-heap-percentage">
<xsd:annotation>
<xsd:documentation
source="com.gemstone.gemfire.cache.control.ResourceManager"><![CDATA[
Set the percentage of heap at or above which the eviction should begin on Regions configured for HeapLRU eviction.
This feature requires additional VM flags to perform properly (see the
JavaDocs for com.gemstone.gemfire.cache.control.ResourceManager for more information).
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="close" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Determines if the cache should be closed when the application context is closed. This value is
true by default but should be set to false if deploying multiple applications in a jvm that share the
same cache instance.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="lazy-init" default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Determines if the cache should be initialized automatically. Normally the cache will be lazily initialized, i.e., during creation of another bean references it.
For cases in which there are no declared dependencies on the cache, set this attribute to false.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
<!-- -->
<xsd:element name="cache">
@@ -271,14 +271,24 @@ Defines a GemFire Cache instance used for creating or retrieving 'regions'.
<xsd:complexType>
<xsd:complexContent>
<xsd:extension base="cacheBaseType">
<xsd:attribute name="lock-timeout" type="xsd:string"
use="optional" default="60">
<xsd:attribute name="enable-auto-reconnect" type="xsd:string" use="optional" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
The timeout, in seconds, for implicit object lock requests. This setting affects automatic locking only,
and does not apply to manual locking. If a lock request does not return before the specified timeout period,
it is cancelled and returns with a failure.
]]></xsd:documentation>
By default, GemFire 7.5 and later will attempt to reconnect and reinitialize the cache when it has been forced out
of the distributed system by a network-partition event, or has otherwise been shunned by other members.
An auto-reconnect causes all the GemFire component references (e.g. Cache, Regions, Gateways, etc) that may have
been injected into and SDG-based application to become stale. Even when using GemFire's public Java API directly,
GemFire makes no guarantees to automatically refresh any returned references to application objects that now are
stale.
Therefore, in Spring Data GemFire, the default behavior will continue to be not to 'auto-reconnect'. This behavior
is not recommended for applications that are 'peer' Caches injecting GemFire components, like the Cache, or Regions
into appliaction components (e.g. @Repository POJOs).
Enabling 'auto-reconnect' is only recommended for Spring bootstrapped GemFire Server's that use the Spring Data GemFire
XML namespace to configure GemFire instead of GemFire's cache.xml.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="lock-lease" type="xsd:string"
@@ -290,6 +300,16 @@ Once a lock is obtained, it can remain in force for the lock lease time period b
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="lock-timeout" type="xsd:string"
use="optional" default="60">
<xsd:annotation>
<xsd:documentation><![CDATA[
The timeout, in seconds, for implicit object lock requests. This setting affects automatic locking only,
and does not apply to manual locking. If a lock request does not return before the specified timeout period,
it is cancelled and returns with a failure.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="message-sync-interval" type="xsd:string"
use="optional" default="1">
<xsd:annotation>

View File

@@ -0,0 +1,75 @@
/*
* 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;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assume.assumeNotNull;
import java.io.File;
import org.junit.After;
import org.junit.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.gemfire.config.GemfireConstants;
import com.gemstone.gemfire.cache.Cache;
/**
* The CacheAutoReconnectIntegrationTests class is a tests suite of test cases testing Spring Data GemFire's support
* of GemFire's Auto-Reconnect functionality release in 8.0.
*
* @author John Blum
* @see org.junit.Test
* @since 1.5.0
*/
public class CacheAutoReconnectIntegrationTests {
private ConfigurableApplicationContext applicationContext;
@After
public void tearDown() {
assumeNotNull(applicationContext);
applicationContext.close();
}
protected Cache getCache(String configLocation) {
String baseConfigLocation = File.separator.concat(
getClass().getPackage().getName().replace('.', File.separatorChar));
applicationContext = new ClassPathXmlApplicationContext(baseConfigLocation.concat(File.separator).concat(configLocation));
return applicationContext.getBean(GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME, Cache.class);
}
@Test
public void testAutoReconnectDisabled() {
Cache cache = getCache("cacheAutoReconnectDisabledIntegrationTests.xml");
assertNotNull(cache.getDistributedSystem());
assertNotNull(cache.getDistributedSystem().getProperties());
assertTrue(Boolean.valueOf(cache.getDistributedSystem().getProperties().getProperty("disable-auto-reconnect")));
}
@Test
public void testAutoReconnectEnabled() {
Cache cache = getCache("cacheAutoReconnectEnabledIntegrationTests.xml");
assertNotNull(cache.getDistributedSystem());
assertNotNull(cache.getDistributedSystem().getProperties());
assertFalse(Boolean.valueOf(cache.getDistributedSystem().getProperties().getProperty("disable-auto-reconnect")));
}
}

View File

@@ -19,11 +19,14 @@ package org.springframework.data.gemfire.config;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import java.util.Properties;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
@@ -45,100 +48,179 @@ import com.gemstone.gemfire.cache.util.TimestampedEntryEvent;
/**
* @author Costin Leau
* @author John Blum
*/
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="/org/springframework/data/gemfire/config/cache-ns.xml",
initializers=GemfireTestApplicationContextInitializer.class)
@ContextConfiguration(locations = "cache-ns.xml", initializers = GemfireTestApplicationContextInitializer.class)
@SuppressWarnings("unused")
public class CacheNamespaceTest{
@Autowired ApplicationContext ctx;
@Autowired
private ApplicationContext context;
@Test
public void testBasicCache() throws Exception {
assertTrue(ctx.containsBean("gemfireCache"));
//Check alias is registered
assertTrue(ctx.containsBean("gemfire-cache"));
//
CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&gemfireCache");
assertNull(TestUtils.readField("cacheXml", cfb));
assertNull(TestUtils.readField("properties", cfb));
public void testNoNamedCache() throws Exception {
assertTrue(context.containsBean("gemfireCache"));
assertTrue(context.containsBean("gemfire-cache")); // assert alias is registered
Cache gemfireCache = context.getBean("gemfireCache", Cache.class);
assertNotNull(gemfireCache);
assertNotNull(gemfireCache.getDistributedSystem());
assertNotNull(gemfireCache.getDistributedSystem().getProperties());
assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties()
.getProperty("disable-auto-reconnect")));
CacheFactoryBean cacheFactoryBean = context.getBean("&gemfireCache", CacheFactoryBean.class);
assertNull(TestUtils.readField("cacheXml", cacheFactoryBean));
Properties gemfireProperties = cacheFactoryBean.getProperties();
assertNotNull(gemfireProperties);
assertTrue(gemfireProperties.containsKey("disable-auto-reconnect"));
assertTrue(Boolean.parseBoolean(gemfireProperties.getProperty("disable-auto-reconnect")));
assertFalse(cacheFactoryBean.getEnableAutoReconnect());
}
@Test
public void testNamedCache() throws Exception {
assertTrue(ctx.containsBean("cache-with-name"));
CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&cache-with-name");
assertNull(TestUtils.readField("cacheXml", cfb));
assertNull(TestUtils.readField("properties", cfb));
assertTrue(context.containsBean("cache-with-name"));
Cache gemfireCache = context.getBean("gemfireCache", Cache.class);
assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties()
.getProperty("disable-auto-reconnect")));
CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-name", CacheFactoryBean.class);
assertNull(TestUtils.readField("cacheXml", cacheFactoryBean));
Properties gemfireProperties = cacheFactoryBean.getProperties();
assertNotNull(gemfireProperties);
assertTrue(gemfireProperties.containsKey("disable-auto-reconnect"));
assertTrue(Boolean.parseBoolean(gemfireProperties.getProperty("disable-auto-reconnect")));
assertFalse(cacheFactoryBean.getEnableAutoReconnect());
}
@Test
public void testCacheWithXml() throws Exception {
assertTrue(ctx.containsBean("cache-with-xml"));
CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&cache-with-xml");
Resource res = TestUtils.readField("cacheXml", cfb);
assertEquals("gemfire-cache.xml", res.getFilename());
assertEquals(ctx.getBean("props"), TestUtils.readField("properties", cfb));
public void testCacheWithXmlAndProperties() throws Exception {
assertTrue(context.containsBean("cache-with-xml-and-props"));
assertEquals(Boolean.FALSE, TestUtils.readField("pdxIgnoreUnreadFields", cfb));
assertEquals(Boolean.TRUE, TestUtils.readField("pdxPersistent", cfb));
CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-xml-and-props", CacheFactoryBean.class);
Resource cacheXmlResource = TestUtils.readField("cacheXml", cacheFactoryBean);
assertEquals("gemfire-cache.xml", cacheXmlResource.getFilename());
assertTrue(context.containsBean("gemfireProperties"));
assertEquals(context.getBean("gemfireProperties"), TestUtils.readField("properties", cacheFactoryBean));
assertEquals(Boolean.TRUE, TestUtils.readField("pdxReadSerialized", cacheFactoryBean));
assertEquals(Boolean.FALSE, TestUtils.readField("pdxIgnoreUnreadFields", cacheFactoryBean));
assertEquals(Boolean.TRUE, TestUtils.readField("pdxPersistent", cacheFactoryBean));
}
@Test
public void testCacheWithGatewayConflictResolver() {
Cache cache = ctx.getBean("cache-with-conflict-resolver", Cache.class);
assertNotNull(cache.getGatewayConflictResolver());
assertTrue(cache.getGatewayConflictResolver() instanceof TestConflictResolver);
}
Cache cache = context.getBean("cache-with-gateway-conflict-resolver", Cache.class);
@Test(expected = IllegalArgumentException.class)
public void testNoBeanFactory() throws Exception {
assertTrue(ctx.containsBean("no-bl"));
CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&no-bl");
assertThat(ReflectionTestUtils.getField(cfb, "factoryLocator"), is(nullValue()));
GemfireBeanFactoryLocator locator = new GemfireBeanFactoryLocator();
try {
assertNotNull(locator.useBeanFactory("cache-with-name"));
locator.useBeanFactory("no-bl");
}
finally {
locator.destroy();
}
assertTrue(cache.getGatewayConflictResolver() instanceof TestGatewayConflictResolver);
}
@Test
public void testBasicClientCache() throws Exception {
assertTrue(ctx.containsBean("client-cache"));
ClientCacheFactoryBean cfb = (ClientCacheFactoryBean) ctx.getBean("&client-cache");
assertNull(TestUtils.readField("cacheXml", cfb));
assertNull(TestUtils.readField("properties", cfb));
public void testCacheWithAutoReconnectDisabled() {
assertTrue(context.containsBean("cache-with-auto-reconnect-disabled"));
Cache gemfireCache = context.getBean("cache-with-auto-reconnect-disabled", Cache.class);
assertTrue(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties()
.getProperty("disable-auto-reconnect")));
CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-auto-reconnect-disabled", CacheFactoryBean.class);
assertFalse(cacheFactoryBean.getEnableAutoReconnect());
}
@Test
public void testBasicClientCacheWithXml() throws Exception {
assertTrue(ctx.containsBean("client-cache-with-xml"));
ClientCacheFactoryBean cfb = (ClientCacheFactoryBean) ctx.getBean("&client-cache-with-xml");
Resource res = TestUtils.readField("cacheXml", cfb);
assertEquals("gemfire-client-cache.xml", res.getFilename());
public void testCacheWithAutoReconnectEnabled() {
assertTrue(context.containsBean("cache-with-auto-reconnect-enabled"));
Cache gemfireCache = context.getBean("cache-with-auto-reconnect-enabled", Cache.class);
assertFalse(Boolean.parseBoolean(gemfireCache.getDistributedSystem().getProperties()
.getProperty("disable-auto-reconnect")));
CacheFactoryBean cacheFactoryBean = context.getBean("&cache-with-auto-reconnect-enabled", CacheFactoryBean.class);
assertTrue(cacheFactoryBean.getEnableAutoReconnect());
}
@Test
public void testHeapTunedCache() throws Exception {
assertTrue(ctx.containsBean("heap-tuned-cache"));
CacheFactoryBean cfb = (CacheFactoryBean) ctx.getBean("&heap-tuned-cache");
Float chp = (Float) TestUtils.readField("criticalHeapPercentage", cfb);
Float ehp = (Float) TestUtils.readField("evictionHeapPercentage", cfb);
assertEquals(70, chp, 0.0001);
assertEquals(60, ehp, 0.0001);
assertTrue(context.containsBean("heap-tuned-cache"));
CacheFactoryBean cacheFactoryBean = context.getBean("&heap-tuned-cache", CacheFactoryBean.class);
Float criticalHeapPercentage = (Float) TestUtils.readField("criticalHeapPercentage", cacheFactoryBean);
Float evictionHeapPercentage = (Float) TestUtils.readField("evictionHeapPercentage", cacheFactoryBean);
assertEquals(70.0f, criticalHeapPercentage, 0.0001);
assertEquals(60.0f, evictionHeapPercentage, 0.0001);
}
public static class TestConflictResolver implements GatewayConflictResolver {
@Override
public void onEvent(TimestampedEntryEvent arg0, GatewayConflictHelper arg1) {
// TODO Auto-generated method stub
@Test(expected = IllegalArgumentException.class)
public void testNoBeanFactoryLocator() throws Exception {
assertTrue(context.containsBean("no-bean-factory-locator"));
CacheFactoryBean cacheFactoryBean = context.getBean("&no-bean-factory-locator", CacheFactoryBean.class);
assertThat(ReflectionTestUtils.getField(cacheFactoryBean, "factoryLocator"), is(nullValue()));
GemfireBeanFactoryLocator beanFactoryLocator = new GemfireBeanFactoryLocator();
try {
assertNotNull(beanFactoryLocator.useBeanFactory("cache-with-name"));
beanFactoryLocator.useBeanFactory("no-bean-factory-locator");
}
finally {
beanFactoryLocator.destroy();
}
}
@Test
public void testNamedClientCache() throws Exception {
assertTrue(context.containsBean("client-cache-with-name"));
ClientCacheFactoryBean clientCacheFactoryBean = context.getBean("&client-cache-with-name", ClientCacheFactoryBean.class);
assertNull(TestUtils.readField("cacheXml", clientCacheFactoryBean));
Properties gemfireProperties = clientCacheFactoryBean.getProperties();
assertNotNull(gemfireProperties);
assertTrue(gemfireProperties.isEmpty());
}
@Test
public void testClientCacheWithXml() throws Exception {
assertTrue(context.containsBean("client-cache-with-xml"));
ClientCacheFactoryBean clientCacheFactoryBean = context.getBean("&client-cache-with-xml", ClientCacheFactoryBean.class);
Resource cacheXmlResource = TestUtils.readField("cacheXml", clientCacheFactoryBean);
assertEquals("gemfire-client-cache.xml", cacheXmlResource.getFilename());
Properties gemfireProperties = clientCacheFactoryBean.getProperties();
assertNotNull(gemfireProperties);
assertTrue(gemfireProperties.isEmpty());
}
public static class TestGatewayConflictResolver implements GatewayConflictResolver {
@Override
public void onEvent(TimestampedEntryEvent arg0, GatewayConflictHelper arg1) {
throw new UnsupportedOperationException("Not Implemented!");
}
}
}

View File

@@ -37,14 +37,17 @@ public class MockCacheFactoryBean extends CacheFactoryBean {
this();
if (cacheFactoryBean != null) {
this.factoryLocator = cacheFactoryBean.getBeanFactoryLocator();
this.lazyInitialize = cacheFactoryBean.isLazyInitialize();
this.beanClassLoader = cacheFactoryBean.getBeanClassLoader();
this.beanFactory = cacheFactoryBean.getBeanFactory();
this.beanName = cacheFactoryBean.getBeanName();
this.beanClassLoader = cacheFactoryBean.getBeanClassLoader();
this.cacheXml = cacheFactoryBean.getCacheXml();
this.properties = cacheFactoryBean.getProperties();
this.copyOnRead = cacheFactoryBean.getCopyOnRead();
this.criticalHeapPercentage = cacheFactoryBean.getCriticalHeapPercentage();
this.dynamicRegionSupport = cacheFactoryBean.getDynamicRegionSupport();
this.evictionHeapPercentage = cacheFactoryBean.getEvictionHeapPercentage();
this.dynamicRegionSupport = cacheFactoryBean.getDynamicRegionSupport();
this.enableAutoReconnect = cacheFactoryBean.getEnableAutoReconnect();
this.gatewayConflictResolver = cacheFactoryBean.getGatewayConflictResolver();
this.jndiDataSources = cacheFactoryBean.getJndiDataSources();
this.lockLease = cacheFactoryBean.getLockLease();
@@ -55,23 +58,20 @@ public class MockCacheFactoryBean extends CacheFactoryBean {
this.pdxPersistent = cacheFactoryBean.getPdxPersistent();
this.pdxReadSerialized = cacheFactoryBean.getPdxReadSerialized();
this.pdxSerializer = cacheFactoryBean.getPdxSerializer();
this.properties = cacheFactoryBean.getProperties();
this.searchTimeout = cacheFactoryBean.getSearchTimeout();
this.transactionListeners = cacheFactoryBean.getTransactionListeners();
this.transactionWriter = cacheFactoryBean.getTransactionWriter();
this.properties = cacheFactoryBean.getProperties();
this.lazyInitialize = cacheFactoryBean.isLazyInitialize();
}
}
@Override
protected Object createFactory(Properties props) {
setProperties(props);
return new CacheFactory(props);
protected Object createFactory(Properties gemfireProperties) {
setProperties(gemfireProperties);
return new CacheFactory(gemfireProperties);
}
protected GemFireCache fetchCache() {
((StubCache)cache).setProperties(this.properties);
((StubCache) cache).setProperties(this.properties);
return cache;
}

View File

@@ -62,8 +62,8 @@ public class MockClientCacheFactoryBean extends ClientCacheFactoryBean {
}
@Override
protected Object createFactory(Properties props) {
((StubCache)cache).setProperties(props);
return new ClientCacheFactory(props);
protected Object createFactory(Properties gemfireProperties) {
((StubCache)cache).setProperties(gemfireProperties);
return new ClientCacheFactory(gemfireProperties);
}
}

View File

@@ -740,23 +740,29 @@ public class StubCache implements Cache {
}
DistributedSystem mockDistributedSystem() {
DistributedSystem ds = mock(DistributedSystem.class);
DistributedMember dm = mockDistributedMember();
when(ds.getName()).thenAnswer(new Answer<String>() {
DistributedSystem mockDistributedSystem = mock(DistributedSystem.class);
when(mockDistributedSystem.getName()).thenAnswer(new Answer<String>() {
@Override
public String answer(InvocationOnMock invocation) throws Throwable {
return getName();
}
}
});
when(ds.getDistributedMember()).thenReturn(dm);
return ds;
when(mockDistributedSystem.getProperties()).thenReturn(this.properties);
DistributedMember mockDistributedMember = mockDistributedMember();
when(mockDistributedSystem.getDistributedMember()).thenReturn(mockDistributedMember);
return mockDistributedSystem;
}
DistributedMember mockDistributedMember() {
DistributedMember dm = mock(DistributedMember.class);
when(dm.getHost()).thenReturn("mockDistributedMember.host");
when(dm.getName()).thenReturn("mockDistributedMember");
return dm;
DistributedMember mockDistributedMember = mock(DistributedMember.class);
when(mockDistributedMember.getHost()).thenReturn("mockDistributedMember.host");
when(mockDistributedMember.getName()).thenReturn("mockDistributedMember");
return mockDistributedMember;
}
CacheServer mockCacheServer() {
@@ -764,84 +770,89 @@ public class StubCache implements Cache {
}
GatewayHub mockGatewayHub() {
final Gateway gw = mock(Gateway.class);
final GatewayQueueAttributes queueAttributes= mock(GatewayQueueAttributes.class);
when(gw.getQueueAttributes()).thenReturn(queueAttributes);
GatewayHub gwh = mock(GatewayHub.class);
when(gwh.addGateway(anyString(),anyInt())).thenAnswer(new Answer<Gateway>() {
final Gateway gateway = mock(Gateway.class);
when(gateway.getQueueAttributes()).thenReturn(mock(GatewayQueueAttributes.class));
GatewayHub gatewayHub = mock(GatewayHub.class);
when(gatewayHub.addGateway(anyString(),anyInt())).thenAnswer(new Answer<Gateway>() {
@Override
public Gateway answer(InvocationOnMock invocation) throws Throwable {
// TODO Auto-generated method stub
return gw;
return gateway;
}
});
return gwh;
return gatewayHub;
}
QueryService mockQueryService() throws RegionNotFoundException, IndexInvalidException, IndexNameConflictException, IndexExistsException, UnsupportedOperationException {
QueryService qs = mock(QueryService.class);
when(qs.getIndexes()).thenReturn(new ArrayList<Index>());
when(qs.createIndex(anyString(), anyString(),anyString())).thenAnswer(new Answer<Index>(){
QueryService queryService = mock(QueryService.class);
when(queryService.getIndexes()).thenReturn(new ArrayList<Index>());
when(queryService.createIndex(anyString(), anyString(),anyString())).thenAnswer(new Answer<Index>() {
@Override
public Index answer(InvocationOnMock invocation) throws Throwable {
String indexName = (String)invocation.getArguments()[0];
String indexedExpression = (String)invocation.getArguments()[1];
String fromClause = (String)invocation.getArguments()[2];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.FUNCTIONAL, indexedExpression, fromClause, null);
String indexName = (String) invocation.getArguments()[0];
String indexedExpression = (String) invocation.getArguments()[1];
String fromClause = (String) invocation.getArguments()[2];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.FUNCTIONAL, indexedExpression,
fromClause, null);
}
});
when(qs.createIndex(anyString(), anyString(),anyString(),anyString())).thenAnswer(new Answer<Index>(){
when(queryService.createIndex(anyString(), anyString(),anyString(),anyString())).thenAnswer(new Answer<Index>() {
@Override
public Index answer(InvocationOnMock invocation) throws Throwable {
String indexName = (String)invocation.getArguments()[0];
String indexedExpression = (String)invocation.getArguments()[1];
String fromClause = (String)invocation.getArguments()[2];
String imports = (String)invocation.getArguments()[3];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.FUNCTIONAL, indexedExpression, fromClause, imports);
String indexName = (String) invocation.getArguments()[0];
String indexedExpression = (String) invocation.getArguments()[1];
String fromClause = (String) invocation.getArguments()[2];
String imports = (String) invocation.getArguments()[3];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.FUNCTIONAL, indexedExpression,
fromClause, imports);
}
});
when(qs.createKeyIndex(anyString(), anyString(),anyString())).thenAnswer(new Answer<Index>(){
when(queryService.createKeyIndex(anyString(), anyString(),anyString())).thenAnswer(new Answer<Index>() {
@Override
public Index answer(InvocationOnMock invocation) throws Throwable {
String indexName = (String)invocation.getArguments()[0];
String indexedExpression = (String)invocation.getArguments()[1];
String fromClause = (String)invocation.getArguments()[2];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.PRIMARY_KEY, indexedExpression, fromClause, null);
String indexName = (String) invocation.getArguments()[0];
String indexedExpression = (String) invocation.getArguments()[1];
String fromClause = (String) invocation.getArguments()[2];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.PRIMARY_KEY, indexedExpression,
fromClause, null);
}
});
when(qs.createHashIndex(anyString(), anyString(),anyString())).thenAnswer(new Answer<Index>(){
when(queryService.createHashIndex(anyString(), anyString(),anyString())).thenAnswer(new Answer<Index>() {
@Override
public Index answer(InvocationOnMock invocation) throws Throwable {
String indexName = (String)invocation.getArguments()[0];
String indexedExpression = (String)invocation.getArguments()[1];
String fromClause = (String)invocation.getArguments()[2];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.HASH, indexedExpression, fromClause, null);
String indexName = (String) invocation.getArguments()[0];
String indexedExpression = (String) invocation.getArguments()[1];
String fromClause = (String) invocation.getArguments()[2];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.HASH, indexedExpression,
fromClause, null);
}
});
when(qs.createHashIndex(anyString(), anyString(),anyString(),anyString())).thenAnswer(new Answer<Index>(){
when(queryService.createHashIndex(anyString(), anyString(),anyString(),anyString())).thenAnswer(new Answer<Index>() {
@Override
public Index answer(InvocationOnMock invocation) throws Throwable {
String indexName = (String)invocation.getArguments()[0];
String indexedExpression = (String)invocation.getArguments()[1];
String fromClause = (String)invocation.getArguments()[2];
String imports = (String)invocation.getArguments()[3];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.HASH, indexedExpression, fromClause, imports);
String indexName = (String) invocation.getArguments()[0];
String indexedExpression = (String) invocation.getArguments()[1];
String fromClause = (String) invocation.getArguments()[2];
String imports = (String) invocation.getArguments()[3];
return mockIndex(indexName, com.gemstone.gemfire.cache.query.IndexType.HASH, indexedExpression,
fromClause, imports);
}
});
return qs;
return queryService;
}
@SuppressWarnings({ "rawtypes", "unchecked", "unused" })
@@ -868,8 +879,8 @@ public class StubCache implements Cache {
return this.allRegions;
}
public void setProperties(Properties props) {
this.properties = props;
public void setProperties(Properties gemfireProperties) {
this.properties = gemfireProperties;
}
@Override
@@ -882,13 +893,13 @@ public class StubCache implements Cache {
return this;
}
@Override
public void stopReconnecting() {
}
@Override
public boolean waitUntilReconnected(final long l, final TimeUnit timeUnit) throws InterruptedException {
return false;
}
@Override
public void stopReconnecting() {
}
}

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<util:properties id="gemfirePeerCacheConfigurationSettings">
<prop key="name">CacheAutoReconnectIntegrationTests</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">config</prop>
</util:properties>
<gfe:cache properties-ref="gemfirePeerCacheConfigurationSettings" use-bean-factory-locator="false"
enable-auto-reconnect="false" lazy-init="false"/>
</beans>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
">
<util:properties id="gemfirePeerCacheConfigurationSettings">
<prop key="name">CacheAutoReconnectIntegrationTests</prop>
<prop key="mcast-port">0</prop>
<prop key="log-level">config</prop>
</util:properties>
<gfe:cache properties-ref="gemfirePeerCacheConfigurationSettings" use-bean-factory-locator="false"
enable-auto-reconnect="true" lazy-init="false"/>
</beans>

View File

@@ -1,43 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:p="http://www.springframework.org/schema/p"
default-lazy-init="true"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
xmlns:gfe="http://www.springframework.org/schema/gemfire"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
default-lazy-init="true"
xsi:schemaLocation="
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<!-- all beans are lazy to allow the same config to be used between multiple tests -->
<!-- as there can be only one cache per VM -->
<!-- as there can be only one GemFire cache per VM -->
<gfe:cache/>
<gfe:cache id="cache-with-name"/>
<gfe:cache id="cache-with-xml" cache-xml-location="classpath:gemfire-cache.xml" properties-ref="props" pdx-ignore-unread-fields="false" pdx-persistent="true"/>
<util:properties id="props">
<util:properties id="gemfireProperties">
<prop key="disable-tcp">false</prop>
</util:properties>
<gfe:cache id="no-bl" use-bean-factory-locator="false" />
<gfe:client-cache id="client-cache"/>
<gfe:cache id="cache-with-xml-and-props" cache-xml-location="classpath:gemfire-cache.xml" properties-ref="gemfireProperties"
pdx-read-serialized="true" pdx-ignore-unread-fields="false" pdx-persistent="true"/>
<gfe:cache id="cache-with-gateway-conflict-resolver">
<gfe:gateway-conflict-resolver>
<bean class="org.springframework.data.gemfire.config.CacheNamespaceTest.TestGatewayConflictResolver"/>
</gfe:gateway-conflict-resolver>
</gfe:cache>
<gfe:cache id="cache-with-auto-reconnect-disabled" enable-auto-reconnect="false"/>
<gfe:cache id="cache-with-auto-reconnect-enabled" enable-auto-reconnect="true"/>
<gfe:cache id="heap-tuned-cache" critical-heap-percentage="70.0" eviction-heap-percentage="60.0"/>
<gfe:cache id="no-bean-factory-locator" use-bean-factory-locator="false"/>
<gfe:client-cache id="client-cache-with-name"/>
<gfe:client-cache id="client-cache-with-xml" cache-xml-location="classpath:gemfire-client-cache.xml"/>
<gfe:pool>
<gfe:server host="localhost" port="1234"/>
</gfe:pool>
<gfe:cache id="heap-tuned-cache" critical-heap-percentage="70.0" eviction-heap-percentage="60.0"/>
<gfe:cache id="cache-with-conflict-resolver">
<gfe:gateway-conflict-resolver>
<bean class="org.springframework.data.gemfire.config.CacheNamespaceTest.TestConflictResolver"/>
</gfe:gateway-conflict-resolver>
</gfe:cache>
</beans>