Implements JIRA feature request SGF-227 adding support for GemFire 8.0's auto-reconnect functionality on forced disconnects.
This commit is contained in:
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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 <dynamic-region-factory>
|
||||
* 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 <dynamic-region-factory>
|
||||
* 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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")));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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!");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user