Fixes bug SGF-225 involving GemFire SubRegion bean definition inconsistencies when data-policy is specified along with SGF-242 that involves the use of membership-attributes configuration on a GemFire Region.
This commit is contained in:
@@ -77,6 +77,8 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
private Object[] asyncEventQueues;
|
||||
private Object[] gatewaySenders;
|
||||
|
||||
private Region<?, ?> parent;
|
||||
|
||||
private RegionAttributes<K, V> attributes;
|
||||
|
||||
private Resource snapshot;
|
||||
@@ -103,11 +105,11 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
AttributesFactory.validateAttributes(attributes);
|
||||
}
|
||||
|
||||
final RegionFactory<K, V> regionFactory = (attributes != null ? cache.createRegionFactory(attributes) :
|
||||
cache.<K, V> createRegionFactory());
|
||||
RegionFactory<K, V> regionFactory = (attributes != null ? cache.createRegionFactory(attributes)
|
||||
: cache.<K, V>createRegionFactory());
|
||||
|
||||
if (hubId != null) {
|
||||
enableGateway = enableGateway == null ? true : enableGateway;
|
||||
enableGateway = (enableGateway == null || enableGateway);
|
||||
Assert.isTrue(enableGateway, "hubId requires the enableGateway property to be true");
|
||||
|
||||
regionFactory.setGatewayHubId(hubId);
|
||||
@@ -115,20 +117,15 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
|
||||
if (enableGateway != null) {
|
||||
if (enableGateway) {
|
||||
Assert.notNull(hubId, "enableGateway requires the hubId property to be true");
|
||||
Assert.notNull(hubId, "The 'enableGateway' property requires the 'hubId' property to be set.");
|
||||
}
|
||||
regionFactory.setEnableGateway(enableGateway);
|
||||
}
|
||||
|
||||
if (!ObjectUtils.isEmpty(cacheListeners)) {
|
||||
for (CacheListener<K, V> listener : cacheListeners) {
|
||||
regionFactory.addCacheListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ObjectUtils.isEmpty(gatewaySenders)) {
|
||||
Assert.isTrue(hubId == null, "It is invalid to configure a region with both a hubId and gatewaySenders."
|
||||
+ " Note that the enableGateway and hubId properties are deprecated since Gemfire 7.0");
|
||||
|
||||
for (Object gatewaySender : gatewaySenders) {
|
||||
regionFactory.addGatewaySenderId(((GatewaySender) gatewaySender).getId());
|
||||
}
|
||||
@@ -140,6 +137,12 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
}
|
||||
}
|
||||
|
||||
if (!ObjectUtils.isEmpty(cacheListeners)) {
|
||||
for (CacheListener<K, V> listener : cacheListeners) {
|
||||
regionFactory.addCacheListener(listener);
|
||||
}
|
||||
}
|
||||
|
||||
if (cacheLoader != null) {
|
||||
regionFactory.setCacheLoader(cacheLoader);
|
||||
}
|
||||
@@ -164,10 +167,20 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
}
|
||||
|
||||
// get underlying AttributesFactory
|
||||
postProcess(findAttrFactory(regionFactory));
|
||||
postProcess(findAttributesFactory(regionFactory));
|
||||
|
||||
Region<K, V> region = regionFactory.create(regionName);
|
||||
log.info("Created new cache region [" + regionName + "]");
|
||||
Region<K, V> region = (this.parent != null ? regionFactory.createSubregion(parent, regionName)
|
||||
: regionFactory.create(regionName));
|
||||
|
||||
if (log.isInfoEnabled()) {
|
||||
if (parent != null) {
|
||||
log.info(String.format("Created new Cache sub-Region [%1$s] under parent Region [%2$s].",
|
||||
regionName, parent.getName()));
|
||||
}
|
||||
else {
|
||||
log.info(String.format("Created new Cache Region [%1$s].", regionName));
|
||||
}
|
||||
}
|
||||
|
||||
if (snapshot != null) {
|
||||
region.loadSnapshot(snapshot.getInputStream());
|
||||
@@ -205,7 +218,7 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private AttributesFactory<K, V> findAttrFactory(RegionFactory<K, V> regionFactory) {
|
||||
private AttributesFactory<K, V> findAttributesFactory(RegionFactory<K, V> regionFactory) {
|
||||
Field attrsFactoryField = ReflectionUtils.findField(RegionFactory.class, "attrsFactory",
|
||||
AttributesFactory.class);
|
||||
ReflectionUtils.makeAccessible(attrsFactoryField);
|
||||
@@ -218,12 +231,13 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
* already initialized and configured by the factory bean before this method
|
||||
* is invoked.
|
||||
*
|
||||
* @param attrFactory attribute factory
|
||||
* @param attributesFactory attribute factory
|
||||
* @deprecated as of GemFire 6.5, the use of {@link AttributesFactory} has
|
||||
* been deprecated
|
||||
*/
|
||||
@Deprecated
|
||||
protected void postProcess(AttributesFactory<K, V> attrFactory) {
|
||||
@SuppressWarnings("unused")
|
||||
protected void postProcess(AttributesFactory<K, V> attributesFactory) {
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -233,6 +247,7 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
*
|
||||
* @param region
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
protected void postProcess(Region<K, V> region) {
|
||||
|
||||
}
|
||||
@@ -244,17 +259,38 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
if (!getRegion().getRegionService().isClosed()) {
|
||||
try {
|
||||
getRegion().close();
|
||||
} catch (Exception cce) {
|
||||
// nothing to see folks, move on.
|
||||
}
|
||||
catch (Exception ignore) {
|
||||
}
|
||||
}
|
||||
|
||||
} if (destroy) {
|
||||
}
|
||||
if (destroy) {
|
||||
getRegion().destroyRegion();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param asyncEventQueues defined as Object for backward compatibility with
|
||||
* Gemfire 6
|
||||
*/
|
||||
public void setAsyncEventQueues(Object[] asyncEventQueues) {
|
||||
this.asyncEventQueues = asyncEventQueues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the region attributes used for the region used by this factory.
|
||||
* Allows maximum control in specifying the region settings. Used only when
|
||||
* a new region is created.
|
||||
*
|
||||
* @param attributes the attributes to set on a newly created region
|
||||
*/
|
||||
public void setAttributes(RegionAttributes<K, V> attributes) {
|
||||
this.attributes = attributes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the region referred by this factory bean, will be
|
||||
* closed on shutdown (default true).
|
||||
@@ -263,26 +299,6 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
this.close = close;
|
||||
}
|
||||
|
||||
/**
|
||||
* Indicates whether the region referred by this factory bean, will be
|
||||
* destroyed on shutdown (default false).
|
||||
*/
|
||||
public void setDestroy(boolean destroy) {
|
||||
this.destroy = destroy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the snapshots used for loading a newly <i>created</i> region. That
|
||||
* is, the snapshot will be used <i>only</i> when a new region is created -
|
||||
* if the region already exists, no loading will be performed.
|
||||
*
|
||||
* @see #setName(String)
|
||||
* @param snapshot the snapshot to set
|
||||
*/
|
||||
public void setSnapshot(Resource snapshot) {
|
||||
this.snapshot = snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache listeners used for the region used by this factory. Used
|
||||
* only when a new region is created.Overrides the settings specified
|
||||
@@ -317,18 +333,11 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the region scope. Used only when a new region is created. Overrides
|
||||
* the settings specified through {@link #setAttributes(RegionAttributes)}.
|
||||
*
|
||||
* @see Scope
|
||||
* @param scope the region scope
|
||||
* Indicates whether the region referred by this factory bean, will be
|
||||
* destroyed on shutdown (default false).
|
||||
*/
|
||||
public void setScope(Scope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
public void setPersistent(boolean persistent) {
|
||||
this.persistent = persistent;
|
||||
public void setDestroy(boolean destroy) {
|
||||
this.destroy = destroy;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -348,6 +357,10 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
this.diskStoreName = diskStoreName;
|
||||
}
|
||||
|
||||
public void setEnableGateway(boolean enableGateway) {
|
||||
this.enableGateway = enableGateway;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param gatewaySenders defined as Object for backward compatibility with
|
||||
@@ -357,32 +370,39 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
|
||||
this.gatewaySenders = gatewaySenders;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param asyncEventQueues defined as Object for backward compatibility with
|
||||
* Gemfire 6
|
||||
*/
|
||||
public void setAsyncEventQueues(Object[] asyncEventQueues) {
|
||||
this.asyncEventQueues = asyncEventQueues;
|
||||
}
|
||||
|
||||
public void setEnableGateway(boolean enableGateway) {
|
||||
this.enableGateway = enableGateway;
|
||||
}
|
||||
|
||||
public void setHubId(String hubId) {
|
||||
this.hubId = hubId;
|
||||
}
|
||||
|
||||
public void setParent(Region<?, ?> parent) {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setPersistent(boolean persistent) {
|
||||
this.persistent = persistent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the region attributes used for the region used by this factory.
|
||||
* Allows maximum control in specifying the region settings. Used only when
|
||||
* a new region is created.
|
||||
* Sets the region scope. Used only when a new region is created. Overrides
|
||||
* the settings specified through {@link #setAttributes(RegionAttributes)}.
|
||||
*
|
||||
* @param attributes the attributes to set on a newly created region
|
||||
* @see Scope
|
||||
* @param scope the region scope
|
||||
*/
|
||||
public void setAttributes(RegionAttributes<K, V> attributes) {
|
||||
this.attributes = attributes;
|
||||
public void setScope(Scope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the snapshots used for loading a newly <i>created</i> region. That
|
||||
* is, the snapshot will be used <i>only</i> when a new region is created -
|
||||
* if the region already exists, no loading will be performed.
|
||||
*
|
||||
* @see #setName(String)
|
||||
* @param snapshot the snapshot to set
|
||||
*/
|
||||
public void setSnapshot(Resource snapshot) {
|
||||
this.snapshot = snapshot;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -29,11 +29,11 @@ import com.gemstone.gemfire.cache.GemFireCache;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
|
||||
/**
|
||||
* Simple FactoryBean for retrieving generic GemFire {@link Region}s. If the region doesn't exist, an exception is thrown.
|
||||
*
|
||||
* For declaring and configuring new regions, see {@link RegionFactoryBean}.
|
||||
*
|
||||
* Simple FactoryBean for retrieving generic GemFire {@link Region}s. If the Region does not exist,
|
||||
* an exception is thrown. For declaring and configuring new regions, see {@link RegionFactoryBean}.
|
||||
* <p/>
|
||||
* @author Costin Leau
|
||||
* @author John Blum
|
||||
*/
|
||||
public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>, InitializingBean, BeanNameAware {
|
||||
|
||||
@@ -45,21 +45,24 @@ public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>,
|
||||
|
||||
private String beanName;
|
||||
private String name;
|
||||
private String regionName;
|
||||
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
Assert.notNull(cache, "Cache property must be set");
|
||||
Assert.notNull(cache, "The 'cache' property must be set.");
|
||||
|
||||
name = (StringUtils.hasText(name) ? name : beanName);
|
||||
Assert.hasText(name, "The 'name' or 'beanName' property must be set.");
|
||||
String regionName = (StringUtils.hasText(this.regionName) ? this.regionName
|
||||
: (StringUtils.hasText(name) ? name : beanName));
|
||||
|
||||
Assert.hasText(regionName, "The 'regionName', 'name' or 'beanName' property must be set.");
|
||||
|
||||
synchronized (cache) {
|
||||
region = cache.getRegion(name);
|
||||
region = cache.getRegion(regionName);
|
||||
|
||||
if (region != null) {
|
||||
log.info(String.format("Retrieved region [%1$s] from cache [%2$s].", name, cache.getName()));
|
||||
log.info(String.format("Retrieved Region [%1$s] from Cache [%2$s].", regionName, cache.getName()));
|
||||
}
|
||||
else {
|
||||
region = lookupFallback(cache, name);
|
||||
region = lookupFallback(cache, regionName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,7 +76,8 @@ public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>,
|
||||
* @throws Exception
|
||||
*/
|
||||
protected Region<K, V> lookupFallback(GemFireCache cache, String regionName) throws Exception {
|
||||
throw new BeanInitializationException("Cannot find region [" + regionName + "] in cache " + cache);
|
||||
throw new BeanInitializationException(String.format("Cannot find Region [%1$s] in Cache [%2$s].",
|
||||
regionName, cache));
|
||||
}
|
||||
|
||||
public Region<K, V> getObject() throws Exception {
|
||||
@@ -88,34 +92,52 @@ public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>,
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the Cache Region based on the bean 'id' attribute. If no Region is found for the given name,
|
||||
* a new one will be created.
|
||||
* <p/>
|
||||
* @param name the name of this bean (Region) in the application context (bean factory).
|
||||
* @see org.springframework.beans.factory.BeanNameAware#setBeanName(String)
|
||||
*/
|
||||
public void setBeanName(String name) {
|
||||
this.beanName = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cache used for creating the region.
|
||||
*
|
||||
* Sets a reference to the Cache used to create the Region.
|
||||
* <p/>
|
||||
* @param cache a reference to the Cache.
|
||||
* @see org.springframework.data.gemfire.CacheFactoryBean
|
||||
* @param cache the cache to set
|
||||
* @see com.gemstone.gemfire.cache.GemFireCache
|
||||
*/
|
||||
public void setCache(GemFireCache cache) {
|
||||
this.cache = cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the cache region. If no cache is found under
|
||||
* the given name, a new one will be created.
|
||||
* If no name is given, the beanName will be used.
|
||||
*
|
||||
* @see com.gemstone.gemfire.cache.Region#getFullPath()
|
||||
* @see #setBeanName(String)
|
||||
*
|
||||
* Sets the name of the Cache Region based on the bean 'name' attribute. If no Region is found with the given name,
|
||||
* a new one will be created. If no name is given, the value of the 'beanName' property will be used.
|
||||
* <p/>
|
||||
* @param name the region name
|
||||
* @see #setBeanName(String)
|
||||
* @see com.gemstone.gemfire.cache.Region#getFullPath()
|
||||
*/
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the Cache Region as expected by GemFire. If no Region is found with the given name, a new one
|
||||
* will be created. If no name is given, the value of the 'name' property will be used.
|
||||
* <p/>
|
||||
* @param regionName a String indicating the name of the Region in GemFire.
|
||||
* @see #setName(String)
|
||||
* @see com.gemstone.gemfire.cache.Region#getName()
|
||||
*/
|
||||
public void setRegionName(String regionName) {
|
||||
this.regionName = regionName;
|
||||
}
|
||||
|
||||
protected Region<K, V> getRegion() {
|
||||
return region;
|
||||
}
|
||||
|
||||
@@ -33,19 +33,19 @@ public class ReplicatedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
|
||||
|
||||
Assert.notNull(resolvedDataPolicy, String.format("Data Policy '%1$s' is invalid.", dataPolicy));
|
||||
|
||||
// Validate that the data-policy and persistent attributes are compatible when specified!
|
||||
assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy);
|
||||
|
||||
if (DataPolicy.EMPTY.equals(resolvedDataPolicy)) {
|
||||
resolvedDataPolicy = DataPolicy.EMPTY;
|
||||
}
|
||||
else {
|
||||
// Validate that the user-defined Data Policy matches the appropriate Spring GemFire XML namespace
|
||||
// configuration meta-data element for Region (i.e. <gfe:replicated-region .../>)!
|
||||
Assert.isTrue(resolvedDataPolicy.withReplication(), String.format("" +
|
||||
Assert.isTrue(resolvedDataPolicy.withReplication(), String.format(
|
||||
"Data Policy '%1$s' is not supported in Replicated Regions.", resolvedDataPolicy));
|
||||
}
|
||||
|
||||
// Validate that the data-policy and persistent attributes are compatible when specified!
|
||||
assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy);
|
||||
|
||||
regionFactory.setDataPolicy(resolvedDataPolicy);
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -29,16 +29,18 @@ import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue;
|
||||
import com.gemstone.gemfire.cache.wan.GatewaySender;
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
/**
|
||||
* FactoryBean for creating a Gemfire Region as a sub-Region.
|
||||
* FactoryBean for creating a Gemfire sub-Regions.
|
||||
* <p/>
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @param <K> - Region Key Type
|
||||
* @param <V> - Region Value Type
|
||||
* @param <K> Region Key Type
|
||||
* @param <V> Region Value Type
|
||||
* @deprecated as Spring Data GemFire 1.4.0. Use Region type specific FactoryBeans
|
||||
* (e.g. ReplicatedRegionFactoryBean) instead.
|
||||
*/
|
||||
// TODO why does this class extend the com.gemstone.gemfire.cache.AttributesFactory class? AttributesFactory is deprecated!
|
||||
@Deprecated
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SubRegionFactoryBean<K, V> extends AttributesFactory<K, V> implements FactoryBean<Region<K, V>>,
|
||||
InitializingBean {
|
||||
|
||||
|
||||
@@ -29,7 +29,6 @@ import org.springframework.beans.factory.support.ManagedArray;
|
||||
import org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser;
|
||||
import org.springframework.beans.factory.xml.ParserContext;
|
||||
import org.springframework.data.gemfire.GemfireUtils;
|
||||
import org.springframework.data.gemfire.SubRegionFactoryBean;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.xml.DomUtils;
|
||||
@@ -46,7 +45,7 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
|
||||
@Override
|
||||
protected Class<?> getBeanClass(Element element) {
|
||||
return (isSubRegion(element) ? SubRegionFactoryBean.class : getRegionFactoryClass());
|
||||
return getRegionFactoryClass();
|
||||
}
|
||||
|
||||
protected abstract Class<?> getRegionFactoryClass();
|
||||
@@ -67,45 +66,45 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
boolean subRegion);
|
||||
|
||||
protected void doParseCommonRegionConfiguration(Element element, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder, BeanDefinitionBuilder attrBuilder, boolean subRegion) {
|
||||
BeanDefinitionBuilder builder, BeanDefinitionBuilder regionAttributesBuilder, boolean subRegion) {
|
||||
|
||||
String cacheRef = element.getAttribute("cache-ref");
|
||||
String resolvedCacheRef = (StringUtils.hasText(cacheRef) ? cacheRef
|
||||
: GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME);
|
||||
|
||||
if (!subRegion) {
|
||||
String cacheRef = element.getAttribute("cache-ref");
|
||||
// add cache reference (fallback to default if nothing is specified)
|
||||
builder.addPropertyReference("cache", (StringUtils.hasText(cacheRef) ? cacheRef : GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME));
|
||||
builder.addPropertyReference("cache", resolvedCacheRef);
|
||||
ParsingUtils.setPropertyValue(element, builder, "close");
|
||||
ParsingUtils.setPropertyValue(element, builder, "destroy");
|
||||
}
|
||||
// add attributes
|
||||
ParsingUtils.setPropertyValue(element, builder, "name");
|
||||
|
||||
ParsingUtils.parseOptionalRegionAttributes(parserContext, element, attrBuilder);
|
||||
ParsingUtils.parseStatistics(element, attrBuilder);
|
||||
ParsingUtils.setPropertyValue(element, attrBuilder, "publisher");
|
||||
if (!isSubRegion(element)) {
|
||||
ParsingUtils.setPropertyValue(element, builder, "persistent");
|
||||
}
|
||||
// set the data policy
|
||||
ParsingUtils.setPropertyValue(element, builder, "name");
|
||||
ParsingUtils.setPropertyValue(element, builder, "data-policy");
|
||||
ParsingUtils.setPropertyValue(element, builder, "persistent");
|
||||
ParsingUtils.setPropertyValue(element, regionAttributesBuilder, "publisher");
|
||||
|
||||
if (StringUtils.hasText(element.getAttribute("disk-store-ref"))) {
|
||||
ParsingUtils.setPropertyValue(element, builder, "disk-store-ref", "diskStoreName");
|
||||
builder.addDependsOn(element.getAttribute("disk-store-ref"));
|
||||
}
|
||||
|
||||
ParsingUtils.parseExpiration(parserContext, element, attrBuilder);
|
||||
ParsingUtils.parseSubscription(parserContext, element, attrBuilder);
|
||||
ParsingUtils.parseEviction(parserContext, element, attrBuilder);
|
||||
ParsingUtils.parseMembershipAttributes(parserContext, element, attrBuilder);
|
||||
ParsingUtils.parseOptionalRegionAttributes(parserContext, element, regionAttributesBuilder);
|
||||
ParsingUtils.parseStatistics(element, regionAttributesBuilder);
|
||||
ParsingUtils.parseExpiration(parserContext, element, regionAttributesBuilder);
|
||||
ParsingUtils.parseSubscription(parserContext, element, regionAttributesBuilder);
|
||||
ParsingUtils.parseEviction(parserContext, element, regionAttributesBuilder);
|
||||
ParsingUtils.parseMembershipAttributes(parserContext, element, regionAttributesBuilder);
|
||||
|
||||
String enableGateway = element.getAttribute("enable-gateway");
|
||||
String hubId = element.getAttribute("hub-id");
|
||||
|
||||
// Factory will enable gateway if it is not set and hub-id is set.
|
||||
if (StringUtils.hasText(enableGateway)) {
|
||||
if (GemfireUtils.isGemfireVersion7OrAbove()) {
|
||||
log.warn("'enable-gateway' is deprecated since Gemfire 7.0");
|
||||
}
|
||||
}
|
||||
|
||||
ParsingUtils.setPropertyValue(element, builder, "enable-gateway");
|
||||
|
||||
if (StringUtils.hasText(hubId)) {
|
||||
@@ -117,16 +116,16 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
element);
|
||||
}
|
||||
}
|
||||
|
||||
ParsingUtils.setPropertyValue(element, builder, "hub-id");
|
||||
|
||||
// Parse child elements
|
||||
|
||||
parseCollectionOfCustomSubElements(parserContext, element, builder,
|
||||
"com.gemstone.gemfire.cache.wan.GatewaySender", "gateway-sender","gatewaySenders");
|
||||
parseCollectionOfCustomSubElements(parserContext, element, builder,
|
||||
"com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue", "async-event-queue", "asyncEventQueues");
|
||||
parseCollectionOfCustomSubElements(element, parserContext, builder,
|
||||
"com.gemstone.gemfire.cache.asyncqueue.AsyncEventQueue", "async-event-queue", "asyncEventQueues");
|
||||
parseCollectionOfCustomSubElements(element, parserContext, builder,
|
||||
"com.gemstone.gemfire.cache.wan.GatewaySender", "gateway-sender","gatewaySenders");
|
||||
|
||||
List<Element> subElements = DomUtils.getChildElements(element);
|
||||
|
||||
for (Element subElement : subElements) {
|
||||
if (subElement.getLocalName().equals("cache-listener")) {
|
||||
builder.addPropertyValue("cacheListeners",
|
||||
@@ -143,43 +142,47 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
}
|
||||
|
||||
if (!subRegion) {
|
||||
Map<String, Element> allSubRegionElements = new HashMap<String, Element>();
|
||||
findSubregionElements(element, getRegionNameFromElement(element), allSubRegionElements);
|
||||
if (!CollectionUtils.isEmpty(allSubRegionElements)) {
|
||||
for (Map.Entry<String, Element> entry : allSubRegionElements.entrySet()) {
|
||||
parseSubRegion(entry.getValue(), parserContext, entry.getKey());
|
||||
}
|
||||
}
|
||||
parseSubRegions(element, parserContext, resolvedCacheRef);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void parseCollectionOfCustomSubElements(ParserContext parserContext, Element element,
|
||||
BeanDefinitionBuilder builder, String className, String subElementName, String propertyName) {
|
||||
List<Element> subElements = DomUtils.getChildElementsByTagName(element, new String[] { subElementName,
|
||||
subElementName + "-ref" });
|
||||
if (!CollectionUtils.isEmpty(subElements)) {
|
||||
private void parseSubRegions(Element element, ParserContext parserContext, String resolvedCacheRef) {
|
||||
Map<String, Element> allSubRegionElements = new HashMap<String, Element>();
|
||||
|
||||
findSubRegionElements(element, getRegionNameFromElement(element), allSubRegionElements);
|
||||
|
||||
if (!CollectionUtils.isEmpty(allSubRegionElements)) {
|
||||
for (Map.Entry<String, Element> entry : allSubRegionElements.entrySet()) {
|
||||
parseSubRegion(entry.getValue(), parserContext, entry.getKey(), resolvedCacheRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void parseCollectionOfCustomSubElements(Element element, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder, String className, String subElementName, String propertyName) {
|
||||
List<Element> subElements = DomUtils.getChildElementsByTagName(element,
|
||||
new String[] { subElementName, subElementName + "-ref" });
|
||||
|
||||
if (!CollectionUtils.isEmpty(subElements)) {
|
||||
ManagedArray array = new ManagedArray(className, subElements.size());
|
||||
|
||||
for (Element subElement : subElements) {
|
||||
array.add(ParsingUtils.parseRefOrNestedCustomElement(parserContext, subElement, builder));
|
||||
}
|
||||
|
||||
builder.addPropertyValue(propertyName, array);
|
||||
}
|
||||
}
|
||||
|
||||
private BeanDefinition parseSubRegion(Element element, ParserContext parserContext, String regionPath) {
|
||||
String parentBeanName = getParentPathForSubRegion(regionPath);
|
||||
String regionName = getRegionNameFromElement(element); // do before 'renaming' the element, below
|
||||
|
||||
element.setAttribute("id", regionPath);
|
||||
element.setAttribute("name", regionPath);
|
||||
|
||||
BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element);
|
||||
beanDefinition.getPropertyValues().add("parent", new RuntimeBeanReference(parentBeanName));
|
||||
beanDefinition.getPropertyValues().add("regionName", regionName);
|
||||
|
||||
return beanDefinition;
|
||||
private void findSubRegionElements(Element parent, String parentPath, Map<String, Element> allSubRegionElements) {
|
||||
for (Element element : DomUtils.getChildElements(parent)) {
|
||||
if (element.getLocalName().endsWith("region")) {
|
||||
String subRegionName = getRegionNameFromElement(element);
|
||||
String subRegionPath = buildSubRegionPath(parentPath, subRegionName);
|
||||
allSubRegionElements.put(subRegionPath, element);
|
||||
findSubRegionElements(element, subRegionPath, allSubRegionElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getRegionNameFromElement(Element element) {
|
||||
@@ -187,15 +190,33 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
return (StringUtils.hasText(name) ? name : element.getAttribute(ID_ATTRIBUTE));
|
||||
}
|
||||
|
||||
private String buildPathForSubRegion(String parentName, String regionName) {
|
||||
String regionPath = StringUtils.arrayToDelimitedString(new String[] { parentName, regionName }, "/");
|
||||
if (!regionPath.startsWith("/")) {
|
||||
regionPath = "/" + regionPath;
|
||||
}
|
||||
return regionPath;
|
||||
}
|
||||
private String buildSubRegionPath(String parentName, String regionName) {
|
||||
String regionPath = StringUtils.arrayToDelimitedString(new String[] { parentName, regionName }, "/");
|
||||
if (!regionPath.startsWith("/")) {
|
||||
regionPath = "/" + regionPath;
|
||||
}
|
||||
return regionPath;
|
||||
}
|
||||
|
||||
private String getParentPathForSubRegion(String regionPath) {
|
||||
private BeanDefinition parseSubRegion(Element element, ParserContext parserContext, String subRegionPath,
|
||||
String cacheRef) {
|
||||
|
||||
String parentBeanName = getParentRegionPathFrom(subRegionPath);
|
||||
String regionName = getRegionNameFromElement(element); // do before 'renaming' the element below
|
||||
|
||||
element.setAttribute("id", subRegionPath);
|
||||
element.setAttribute("name", subRegionPath);
|
||||
|
||||
BeanDefinition beanDefinition = parserContext.getDelegate().parseCustomElement(element);
|
||||
|
||||
beanDefinition.getPropertyValues().add("cache", new RuntimeBeanReference(cacheRef));
|
||||
beanDefinition.getPropertyValues().add("parent", new RuntimeBeanReference(parentBeanName));
|
||||
beanDefinition.getPropertyValues().add("regionName", regionName);
|
||||
|
||||
return beanDefinition;
|
||||
}
|
||||
|
||||
private String getParentRegionPathFrom(String regionPath) {
|
||||
int index = regionPath.lastIndexOf("/");
|
||||
String parentPath = regionPath.substring(0, index);
|
||||
if (parentPath.lastIndexOf("/") == 0) {
|
||||
@@ -204,14 +225,4 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
|
||||
return parentPath;
|
||||
}
|
||||
|
||||
private void findSubregionElements(Element parent, String parentPath, Map<String, Element> allSubregionElements) {
|
||||
for (Element element : DomUtils.getChildElements(parent)) {
|
||||
if (element.getLocalName().endsWith("region")) {
|
||||
String regionPath = buildPathForSubRegion(parentPath, getRegionNameFromElement(element));
|
||||
allSubregionElements.put(regionPath, element);
|
||||
findSubregionElements(element, regionPath, allSubregionElements);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -78,6 +78,7 @@ class ClientRegionParser extends AbstractRegionParser {
|
||||
builder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition());
|
||||
|
||||
List<Element> subElements = DomUtils.getChildElements(element);
|
||||
|
||||
ManagedList<Object> interests = new ManagedList<Object>();
|
||||
|
||||
for (Element subElement : subElements) {
|
||||
@@ -110,7 +111,7 @@ class ClientRegionParser extends AbstractRegionParser {
|
||||
|
||||
@Override
|
||||
protected void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
|
||||
boolean subRegion) {
|
||||
boolean subRegion) {
|
||||
throw new UnsupportedOperationException(String.format(
|
||||
"doParseRegion(:Element, :ParserContext, :BeanDefinitionBuilder, :boolean) is not supported on %1$s",
|
||||
getClass().getName()));
|
||||
|
||||
@@ -31,12 +31,12 @@ import org.w3c.dom.Element;
|
||||
* @author David Turanski
|
||||
*/
|
||||
class GemfireNamespaceHandler extends NamespaceHandlerSupport {
|
||||
static final List<String> GEMFIRE7_ELEMENTS = Arrays.asList("async-event-queue", "gateway-sender",
|
||||
"gateway-receiver");
|
||||
|
||||
protected static final List<String> GEMFIRE7_ELEMENTS = Arrays.asList("async-event-queue", "gateway-sender",
|
||||
"gateway-receiver");
|
||||
|
||||
@Override
|
||||
public BeanDefinition parse(Element element, ParserContext parserContext) {
|
||||
|
||||
boolean v7ElementsPresent = GEMFIRE7_ELEMENTS.contains(element.getLocalName());
|
||||
|
||||
if (v7ElementsPresent) {
|
||||
@@ -49,24 +49,23 @@ class GemfireNamespaceHandler extends NamespaceHandlerSupport {
|
||||
@Override
|
||||
public void init() {
|
||||
registerBeanDefinitionParser("cache", new CacheParser());
|
||||
registerBeanDefinitionParser("client-cache", new ClientCacheParser());
|
||||
registerBeanDefinitionParser("lookup-region", new LookupRegionParser());
|
||||
registerBeanDefinitionParser("replicated-region", new ReplicatedRegionParser());
|
||||
registerBeanDefinitionParser("partitioned-region", new PartitionedRegionParser());
|
||||
registerBeanDefinitionParser("local-region", new LocalRegionParser());
|
||||
registerBeanDefinitionParser("client-region", new ClientRegionParser());
|
||||
registerBeanDefinitionParser("pool", new PoolParser());
|
||||
registerBeanDefinitionParser("index", new IndexParser());
|
||||
registerBeanDefinitionParser("disk-store", new DiskStoreParser());
|
||||
registerBeanDefinitionParser("cache-server", new CacheServerParser());
|
||||
registerBeanDefinitionParser("transaction-manager", new TransactionManagerParser());
|
||||
registerBeanDefinitionParser("cq-listener-container", new GemfireListenerContainerParser());
|
||||
registerBeanDefinitionParser("client-cache", new ClientCacheParser());
|
||||
registerBeanDefinitionParser("client-region", new ClientRegionParser());
|
||||
registerBeanDefinitionParser("lookup-region", new LookupRegionParser());
|
||||
registerBeanDefinitionParser("local-region", new LocalRegionParser());
|
||||
registerBeanDefinitionParser("partitioned-region", new PartitionedRegionParser());
|
||||
registerBeanDefinitionParser("replicated-region", new ReplicatedRegionParser());
|
||||
registerBeanDefinitionParser("async-event-queue", new AsyncEventQueueParser());
|
||||
registerBeanDefinitionParser("gateway-sender", new GatewaySenderParser());
|
||||
registerBeanDefinitionParser("gateway-receiver", new GatewayReceiverParser());
|
||||
registerBeanDefinitionParser("function-service", new FunctionServiceParser());
|
||||
// V6 WAN parsers
|
||||
registerBeanDefinitionParser("disk-store", new DiskStoreParser());
|
||||
registerBeanDefinitionParser("gateway-hub", new GatewayHubParser());
|
||||
registerBeanDefinitionParser("gateway-receiver", new GatewayReceiverParser());
|
||||
registerBeanDefinitionParser("gateway-sender", new GatewaySenderParser());
|
||||
registerBeanDefinitionParser("index", new IndexParser());
|
||||
registerBeanDefinitionParser("pool", new PoolParser());
|
||||
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
|
||||
registerBeanDefinitionParser("cq-listener-container", new GemfireListenerContainerParser());
|
||||
registerBeanDefinitionParser("function-service", new FunctionServiceParser());
|
||||
registerBeanDefinitionParser("transaction-manager", new TransactionManagerParser());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,27 +23,28 @@ import org.springframework.data.gemfire.RegionAttributesFactoryBean;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <local-region;gt; definitions.
|
||||
*
|
||||
* Parser for <local-region;gt; bean definitions.
|
||||
* <p/>
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
*/
|
||||
class LocalRegionParser extends AbstractRegionParser {
|
||||
@Override
|
||||
protected void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
|
||||
boolean subRegion) {
|
||||
|
||||
BeanDefinitionBuilder attrBuilder = subRegion ? builder : BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RegionAttributesFactoryBean.class);
|
||||
|
||||
super.doParseCommonRegionConfiguration(element, parserContext, builder, attrBuilder, subRegion);
|
||||
if (!subRegion) {
|
||||
builder.addPropertyValue("attributes", attrBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Class<?> getRegionFactoryClass() {
|
||||
return LocalRegionFactoryBean.class;
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
protected void doParseRegion(Element element, ParserContext parserContext, BeanDefinitionBuilder builder,
|
||||
boolean subRegion) {
|
||||
|
||||
BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
RegionAttributesFactoryBean.class);
|
||||
|
||||
super.doParseCommonRegionConfiguration(element, parserContext, builder, regionAttributesBuilder, subRegion);
|
||||
|
||||
builder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,9 +24,10 @@ import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <lookup-region;gt; definitions.
|
||||
*
|
||||
* <p/>
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
*/
|
||||
class LookupRegionParser extends AbstractRegionParser {
|
||||
|
||||
@@ -43,9 +44,9 @@ class LookupRegionParser extends AbstractRegionParser {
|
||||
ParsingUtils.setPropertyValue(element, builder, "name", "name");
|
||||
|
||||
if (!subRegion) {
|
||||
String attr = element.getAttribute("cache-ref");
|
||||
// add cache reference (fallback to default if nothing is specified)
|
||||
builder.addPropertyReference("cache", (StringUtils.hasText(attr) ? attr : GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME));
|
||||
String cacheRef = element.getAttribute("cache-ref");
|
||||
builder.addPropertyReference("cache", (StringUtils.hasText(cacheRef) ? cacheRef
|
||||
: GemfireConstants.DEFAULT_GEMFIRE_CACHE_NAME));
|
||||
}
|
||||
else {
|
||||
builder.addPropertyValue("lookupOnly", true);
|
||||
|
||||
@@ -183,10 +183,12 @@ abstract class ParsingUtils {
|
||||
* <p/>
|
||||
* @param parserContext the context used for parsing the XML document.
|
||||
* @param element the XML elements being parsed.
|
||||
* @param attributesBuilder the Region Attributes builder.
|
||||
* @param regionAttributesBuilder the Region Attributes builder.
|
||||
* @return true if parsing actually occurred, false otherwise.
|
||||
*/
|
||||
static boolean parseEviction(ParserContext parserContext, Element element, BeanDefinitionBuilder attributesBuilder) {
|
||||
static boolean parseEviction(ParserContext parserContext, Element element,
|
||||
BeanDefinitionBuilder regionAttributesBuilder) {
|
||||
|
||||
Element evictionElement = DomUtils.getChildElementByTagName(element, "eviction");
|
||||
|
||||
if (evictionElement != null) {
|
||||
@@ -210,7 +212,7 @@ abstract class ParsingUtils {
|
||||
evictionAttributesBuilder.addPropertyValue("ObjectSizer", sizer);
|
||||
}
|
||||
|
||||
attributesBuilder.addPropertyValue("evictionAttributes", evictionAttributesBuilder.getBeanDefinition());
|
||||
regionAttributesBuilder.addPropertyValue("evictionAttributes", evictionAttributesBuilder.getBeanDefinition());
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -223,27 +225,32 @@ abstract class ParsingUtils {
|
||||
* <p/>
|
||||
* @param parserContext the context used while parsing the XML document.
|
||||
* @param element the XML element being parsed.
|
||||
* @param attrBuilder the Region Attributes builder.
|
||||
* @param regionAttributesBuilder the Region Attributes builder.
|
||||
* @return true if parsing actually occurred, false otherwise.
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
static boolean parseSubscription(ParserContext parserContext, Element element, BeanDefinitionBuilder attrBuilder) {
|
||||
static boolean parseSubscription(ParserContext parserContext, Element element,
|
||||
BeanDefinitionBuilder regionAttributesBuilder) {
|
||||
|
||||
Element subscriptionElement = DomUtils.getChildElementByTagName(element, "subscription");
|
||||
|
||||
if (subscriptionElement == null)
|
||||
return false;
|
||||
if (subscriptionElement != null) {
|
||||
BeanDefinitionBuilder subscriptionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
SubscriptionAttributesFactoryBean.class);
|
||||
|
||||
BeanDefinitionBuilder subscriptionDefBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(SubscriptionAttributesFactoryBean.class);
|
||||
// do manual conversion since the enum is not public
|
||||
String type = subscriptionElement.getAttribute("type");
|
||||
|
||||
// do manual conversion since the enum is not public
|
||||
String attr = subscriptionElement.getAttribute("type");
|
||||
if (StringUtils.hasText(attr)) {
|
||||
subscriptionDefBuilder.addPropertyValue("type", SubscriptionType.valueOf(attr.toUpperCase()));
|
||||
if (StringUtils.hasText(type)) {
|
||||
subscriptionAttributesBuilder.addPropertyValue("type", SubscriptionType.valueOf(type.toUpperCase()));
|
||||
}
|
||||
|
||||
regionAttributesBuilder.addPropertyValue("subscriptionAttributes", subscriptionAttributesBuilder.getBeanDefinition());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
attrBuilder.addPropertyValue("subscriptionAttributes", subscriptionDefBuilder.getBeanDefinition());
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -284,85 +291,90 @@ abstract class ParsingUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void parseOptionalRegionAttributes(ParserContext parserContext, Element element,
|
||||
BeanDefinitionBuilder attrBuilder) {
|
||||
BeanDefinitionBuilder regionAttributesBuilder) {
|
||||
|
||||
if (!("partitioned-region".equals(element.getLocalName()))) {
|
||||
setPropertyValue(element, attrBuilder, "persistent", "persistBackup");
|
||||
setPropertyValue(element, regionAttributesBuilder, "persistent", "persistBackup");
|
||||
}
|
||||
setPropertyValue(element, attrBuilder, "ignore-jta", "ignoreJTA");
|
||||
setPropertyValue(element, attrBuilder, "key-constraint");
|
||||
setPropertyValue(element, attrBuilder, "value-constraint");
|
||||
setPropertyValue(element, attrBuilder, "is-lock-grantor", "lockGrantor");
|
||||
setPropertyValue(element, attrBuilder, "enable-subscription-conflation");
|
||||
setPropertyValue(element, attrBuilder, "enable-async-conflation");
|
||||
setPropertyValue(element, attrBuilder, "initial-capacity");
|
||||
setPropertyValue(element, attrBuilder, "load-factor");
|
||||
setPropertyValue(element, attrBuilder, "cloning-enabled");
|
||||
setPropertyValue(element, attrBuilder, "concurrency-level");
|
||||
setPropertyValue(element, attrBuilder, "multicast-enabled");
|
||||
|
||||
setPropertyValue(element, regionAttributesBuilder, "cloning-enabled");
|
||||
setPropertyValue(element, regionAttributesBuilder, "concurrency-level");
|
||||
setPropertyValue(element, regionAttributesBuilder, "enable-async-conflation");
|
||||
setPropertyValue(element, regionAttributesBuilder, "enable-subscription-conflation");
|
||||
setPropertyValue(element, regionAttributesBuilder, "ignore-jta", "ignoreJTA");
|
||||
setPropertyValue(element, regionAttributesBuilder, "initial-capacity");
|
||||
setPropertyValue(element, regionAttributesBuilder, "is-lock-grantor", "lockGrantor");
|
||||
setPropertyValue(element, regionAttributesBuilder, "key-constraint");
|
||||
setPropertyValue(element, regionAttributesBuilder, "load-factor");
|
||||
setPropertyValue(element, regionAttributesBuilder, "multicast-enabled");
|
||||
setPropertyValue(element, regionAttributesBuilder, "value-constraint");
|
||||
|
||||
String indexUpdateType = element.getAttribute("index-update-type");
|
||||
|
||||
if (StringUtils.hasText(indexUpdateType)) {
|
||||
attrBuilder.addPropertyValue("indexMaintenanceSynchronous", "synchronous".equals(indexUpdateType));
|
||||
regionAttributesBuilder.addPropertyValue("indexMaintenanceSynchronous", "synchronous".equals(indexUpdateType));
|
||||
}
|
||||
|
||||
|
||||
String concurrencyChecksEnabled = element.getAttribute("concurrency-checks-enabled");
|
||||
|
||||
if (StringUtils.hasText(concurrencyChecksEnabled)) {
|
||||
if (!GemfireUtils.isGemfireVersion7OrAbove()) {
|
||||
log.warn("'concurrency-checks-enabled' is only available in Gemfire 7.0 or above");
|
||||
} else {
|
||||
ParsingUtils.setPropertyValue(element, attrBuilder, "concurrency-checks-enabled");
|
||||
log.warn("Setting 'concurrency-checks-enabled' is only available in Gemfire 7.0 or above");
|
||||
}
|
||||
else {
|
||||
ParsingUtils.setPropertyValue(element, regionAttributesBuilder, "concurrency-checks-enabled");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
static void parseMembershipAttributes(ParserContext parserContext, Element element,
|
||||
BeanDefinitionBuilder attrBuilder) {
|
||||
BeanDefinitionBuilder regionAttributesBuilder) {
|
||||
|
||||
Element membershipAttributes = DomUtils.getChildElementByTagName(element, "membership-attributes");
|
||||
|
||||
if (membershipAttributes != null) {
|
||||
String requiredRoles[] = StringUtils.commaDelimitedListToStringArray(membershipAttributes
|
||||
.getAttribute("required-roles"));
|
||||
String lossActionAttr = membershipAttributes.getAttribute("loss-action");
|
||||
LossAction lossAction = StringUtils.hasText(lossActionAttr) ? LossAction.fromName(lossActionAttr
|
||||
.toUpperCase().replace("-", "_")) : null;
|
||||
String resumptionActionAttr = membershipAttributes.getAttribute("resumption-action");
|
||||
ResumptionAction resumptionAction = StringUtils.hasText(resumptionActionAttr) ? ResumptionAction
|
||||
.fromName(resumptionActionAttr.toUpperCase().replace("-", "_")) : null;
|
||||
String[] requiredRoles = StringUtils.commaDelimitedListToStringArray(
|
||||
membershipAttributes.getAttribute("required-roles"));
|
||||
|
||||
ManagedArray requiredRolesArray = new ManagedArray("java.lang.String", requiredRoles.length);
|
||||
for (int i = 0; i < requiredRoles.length; i++) {
|
||||
requiredRolesArray.add(requiredRoles[i]);
|
||||
}
|
||||
BeanDefinitionBuilder membershipAttributesBuilder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(MembershipAttributes.class);
|
||||
membershipAttributesBuilder.addConstructorArgValue(requiredRolesArray);
|
||||
membershipAttributesBuilder.addConstructorArgValue(lossAction);
|
||||
membershipAttributesBuilder.addConstructorArgValue(resumptionAction);
|
||||
String lossActionValue = membershipAttributes.getAttribute("loss-action");
|
||||
|
||||
attrBuilder.addPropertyValue("membershipAttributes", membershipAttributesBuilder.getRawBeanDefinition());
|
||||
LossAction lossAction = (StringUtils.hasText(lossActionValue)
|
||||
? LossAction.fromName(lossActionValue.toUpperCase().replace("-", "_"))
|
||||
: LossAction.NO_ACCESS);
|
||||
|
||||
String resumptionActionValue = membershipAttributes.getAttribute("resumption-action");
|
||||
|
||||
ResumptionAction resumptionAction = (StringUtils.hasText(resumptionActionValue)
|
||||
? ResumptionAction.fromName(resumptionActionValue.toUpperCase().replace("-", "_"))
|
||||
: ResumptionAction.REINITIALIZE);
|
||||
|
||||
regionAttributesBuilder.addPropertyValue("membershipAttributes",
|
||||
new MembershipAttributes(requiredRoles, lossAction, resumptionAction));
|
||||
}
|
||||
}
|
||||
|
||||
static void throwExceptionIfNotGemfireV7(String elementName, String attributeName, ParserContext parserContext) {
|
||||
if (!GemfireUtils.isGemfireVersion7OrAbove()) {
|
||||
String messagePrefix = (attributeName == null) ? "element '" + elementName + "'" : "attribute '"
|
||||
+ attributeName + " of element '" + elementName + "'";
|
||||
String messagePrefix = (attributeName != null)
|
||||
? String.format("Attribute '%1$s' of element '%2$s'", attributeName, elementName)
|
||||
: String.format("Element '%1$s'", elementName);
|
||||
parserContext.getReaderContext().error(
|
||||
messagePrefix + " requires Gemfire version 7 or later. The current version is " + GemfireUtils.GEMFIRE_VERSION,
|
||||
null);
|
||||
String.format("%1$s requires GemFire version 7 or later. The current version is %2$s.",
|
||||
messagePrefix, GemfireUtils.GEMFIRE_VERSION), null);
|
||||
}
|
||||
}
|
||||
|
||||
static void parseScope(Element element, BeanDefinitionBuilder builder) {
|
||||
String scope = element.getAttribute("scope");
|
||||
if (StringUtils.hasText(scope)) {
|
||||
builder.addPropertyValue("scope", Scope.fromString(scope.toUpperCase().replace("-", "_")));
|
||||
}
|
||||
else {
|
||||
builder.addPropertyValue("scope", Scope.DISTRIBUTED_ACK);
|
||||
}
|
||||
String scopeAttributeValue = element.getAttribute("scope");
|
||||
|
||||
Scope scope = (StringUtils.hasText(scopeAttributeValue)
|
||||
? Scope.fromString(scopeAttributeValue.toUpperCase().replace("-", "_"))
|
||||
: Scope.DISTRIBUTED_ACK);
|
||||
|
||||
builder.addPropertyValue("scope", scope);
|
||||
}
|
||||
|
||||
private static boolean parseExpiration(Element rootElement, String elementName, String propertyName,
|
||||
|
||||
@@ -31,11 +31,10 @@ import org.springframework.util.xml.DomUtils;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <partitioned-region;gt; definitions.
|
||||
*
|
||||
* To avoid eager evaluations, the region attributes are declared as a nested
|
||||
* definition.
|
||||
*
|
||||
* Parser for <partitioned-region;gt; bean definitions.
|
||||
* <p/>
|
||||
* To avoid eager evaluations, the region attributes are declared as a nested definition.
|
||||
* <p/>
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
@@ -53,58 +52,57 @@ class PartitionedRegionParser extends AbstractRegionParser {
|
||||
boolean subRegion) {
|
||||
super.doParse(element, builder);
|
||||
|
||||
BeanDefinitionBuilder regionAttributesBuilder = (subRegion ? builder
|
||||
: BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class));
|
||||
BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
RegionAttributesFactoryBean.class);
|
||||
|
||||
super.doParseCommonRegionConfiguration(element, parserContext, builder, regionAttributesBuilder, subRegion);
|
||||
|
||||
builder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition());
|
||||
|
||||
BeanDefinitionBuilder partitionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
PartitionAttributesFactoryBean.class);
|
||||
|
||||
parseColocatedWith(element, builder, partitionAttributesBuilder, "colocated-with");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "local-max-memory");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "copies","redundantCopies");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "local-max-memory");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "recovery-delay");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "startup-recovery-delay");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "total-max-memory");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "total-buckets","totalNumBuckets");
|
||||
ParsingUtils.setPropertyValue(element, partitionAttributesBuilder, "total-max-memory");
|
||||
|
||||
Element subElement = DomUtils.getChildElementByTagName(element, "partition-resolver");
|
||||
// parse nested partition resolver element
|
||||
if (subElement != null) {
|
||||
Element partitionResolverSubElement = DomUtils.getChildElementByTagName(element, "partition-resolver");
|
||||
|
||||
if (partitionResolverSubElement != null) {
|
||||
partitionAttributesBuilder.addPropertyValue("partitionResolver",
|
||||
parsePartitionResolver(parserContext, subElement, builder));
|
||||
parsePartitionResolver(partitionResolverSubElement, parserContext, builder));
|
||||
}
|
||||
|
||||
subElement = DomUtils.getChildElementByTagName(element, "partition-listener");
|
||||
// parse nested partition listener element
|
||||
if (subElement != null) {
|
||||
Element partitionListenerSubElement = DomUtils.getChildElementByTagName(element, "partition-listener");
|
||||
|
||||
if (partitionListenerSubElement != null) {
|
||||
partitionAttributesBuilder.addPropertyValue("partitionListeners",
|
||||
parsePartitionListeners(parserContext, subElement, builder));
|
||||
parsePartitionListeners(partitionListenerSubElement, parserContext, builder));
|
||||
}
|
||||
|
||||
List<Element> fixedPartitions = DomUtils.getChildElementsByTagName(element, "fixed-partition");
|
||||
List<Element> fixedPartitionSubElements = DomUtils.getChildElementsByTagName(element, "fixed-partition");
|
||||
|
||||
if (!CollectionUtils.isEmpty(fixedPartitions)){
|
||||
if (!CollectionUtils.isEmpty(fixedPartitionSubElements)){
|
||||
@SuppressWarnings("rawtypes")
|
||||
ManagedList fixedPartitionAttributes = new ManagedList();
|
||||
for (Element fp: fixedPartitions) {
|
||||
BeanDefinitionBuilder fpaBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
|
||||
for (Element fixedPartition : fixedPartitionSubElements) {
|
||||
BeanDefinitionBuilder fixedPartitionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
FixedPartitionAttributesFactoryBean.class);
|
||||
ParsingUtils.setPropertyValue(fp, fpaBuilder, "partition-name");
|
||||
ParsingUtils.setPropertyValue(fp, fpaBuilder, "num-buckets");
|
||||
ParsingUtils.setPropertyValue(fp, fpaBuilder, "primary");
|
||||
fixedPartitionAttributes.add(fpaBuilder.getBeanDefinition());
|
||||
ParsingUtils.setPropertyValue(fixedPartition, fixedPartitionAttributesBuilder, "partition-name");
|
||||
ParsingUtils.setPropertyValue(fixedPartition, fixedPartitionAttributesBuilder, "num-buckets");
|
||||
ParsingUtils.setPropertyValue(fixedPartition, fixedPartitionAttributesBuilder, "primary");
|
||||
fixedPartitionAttributes.add(fixedPartitionAttributesBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
partitionAttributesBuilder.addPropertyValue("fixedPartitionAttributes", fixedPartitionAttributes);
|
||||
}
|
||||
|
||||
// add partition attributes to region attributes
|
||||
regionAttributesBuilder.addPropertyValue("partitionAttributes", partitionAttributesBuilder.getBeanDefinition());
|
||||
// add partition/overflow settings as attributes to Region (via PartitionRegionFactoryBean -> RegionFactoryBean)
|
||||
if (!subRegion) {
|
||||
builder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
private void parseColocatedWith(Element element, BeanDefinitionBuilder regionBuilder,
|
||||
@@ -124,12 +122,12 @@ class PartitionedRegionParser extends AbstractRegionParser {
|
||||
}
|
||||
}
|
||||
|
||||
private Object parsePartitionResolver(ParserContext parserContext, Element subElement,
|
||||
private Object parsePartitionResolver(Element subElement, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder) {
|
||||
return ParsingUtils.parseRefOrSingleNestedBeanDeclaration(parserContext, subElement, builder);
|
||||
}
|
||||
|
||||
private Object parsePartitionListeners(ParserContext parserContext, Element subElement,
|
||||
private Object parsePartitionListeners(Element subElement, ParserContext parserContext,
|
||||
BeanDefinitionBuilder builder) {
|
||||
return ParsingUtils.parseRefOrNestedBeanDeclaration(parserContext, subElement, builder);
|
||||
}
|
||||
|
||||
@@ -24,9 +24,10 @@ import org.w3c.dom.Element;
|
||||
|
||||
/**
|
||||
* Parser for <replicated-region;gt; definitions.
|
||||
*
|
||||
* <p/>
|
||||
* @author Costin Leau
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
*/
|
||||
class ReplicatedRegionParser extends AbstractRegionParser {
|
||||
|
||||
@@ -41,15 +42,13 @@ class ReplicatedRegionParser extends AbstractRegionParser {
|
||||
|
||||
ParsingUtils.parseScope(element, builder);
|
||||
|
||||
BeanDefinitionBuilder regionAttributesFactoryBuilder = (subRegion ? builder
|
||||
: BeanDefinitionBuilder.genericBeanDefinition(RegionAttributesFactoryBean.class));
|
||||
BeanDefinitionBuilder regionAttributesBuilder = BeanDefinitionBuilder.genericBeanDefinition(
|
||||
RegionAttributesFactoryBean.class);
|
||||
|
||||
super.doParseCommonRegionConfiguration(element, parserContext, builder, regionAttributesFactoryBuilder,
|
||||
super.doParseCommonRegionConfiguration(element, parserContext, builder, regionAttributesBuilder,
|
||||
subRegion);
|
||||
|
||||
if (!subRegion) {
|
||||
builder.addPropertyValue("attributes", regionAttributesFactoryBuilder.getBeanDefinition());
|
||||
}
|
||||
builder.addPropertyValue("attributes", regionAttributesBuilder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -733,37 +733,33 @@ arbitrarily pick one.
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="membership-attributes" minOccurs="0"
|
||||
maxOccurs="1">
|
||||
<xsd:element name="membership-attributes" minOccurs="0" maxOccurs="1">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Configures a Region to require one or more membership roles to be present in the system for reliable access to the Region
|
||||
]]></xsd:documentation>
|
||||
Establishes reliability requirements and behavior for a region. Use this to configure the region to require one or more membership roles to be running in the system for reliable access to the region.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="required-roles" type="xsd:string"
|
||||
use="required">
|
||||
<xsd:attribute name="required-roles" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
A comma delimited list of required role names
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="loss-action" type="xsd:string"
|
||||
use="optional">
|
||||
<xsd:attribute name="loss-action" type="xsd:string" default="no-access">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies the behavior when one or more required roles are missing:
|
||||
(full-access, limited-access, no-access, or reconnect)
|
||||
Set one of the following values to specify how access to the region is affected when one or more required roles are lost:
|
||||
(full-access, limited-access, no-access, or reconnect).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="resumption-action" type="xsd:string"
|
||||
use="optional">
|
||||
<xsd:attribute name="resumption-action" type="xsd:string" default="reinitialize">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Specifies how the region is affected by resumption of reliability
|
||||
when one or more missing required roles is restored to the distributed membership (none or reinitialize)
|
||||
Specifies how the region is affected by resumption of reliability when one or more missing required roles return to the distributed membership:
|
||||
(none or reinitialize).
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/*
|
||||
* 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.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import static org.junit.Assert.assertSame;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.DataPolicy;
|
||||
import com.gemstone.gemfire.cache.EvictionAction;
|
||||
import com.gemstone.gemfire.cache.EvictionAttributes;
|
||||
import com.gemstone.gemfire.cache.InterestPolicy;
|
||||
import com.gemstone.gemfire.cache.LossAction;
|
||||
import com.gemstone.gemfire.cache.MembershipAttributes;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.RegionAttributes;
|
||||
import com.gemstone.gemfire.cache.ResumptionAction;
|
||||
import com.gemstone.gemfire.cache.Scope;
|
||||
import com.gemstone.gemfire.cache.SubscriptionAttributes;
|
||||
|
||||
/**
|
||||
* The SubRegionIntegrationTest class is a test suite of test cases testing the functionality of SubRegions in GemFire
|
||||
* configured with Spring Data GemFire's XML namespace configuration meta-data. This test class tests a complex
|
||||
* SubRegion configuration in order to ensure functional completeness.
|
||||
* <p/>
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @since 1.4.0
|
||||
* @since 7.0.1 (GemFire)
|
||||
*/
|
||||
@ContextConfiguration("complex-subregion.xml")
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
public class SubRegionIntegrationTest {
|
||||
|
||||
@Autowired
|
||||
private Cache cache;
|
||||
|
||||
@Resource(name = "Customers")
|
||||
private Region customers;
|
||||
|
||||
@Resource(name = "/Customers/Accounts")
|
||||
private Region accounts;
|
||||
|
||||
@Test
|
||||
public void testGemFireAccountsSubRegionCreation() {
|
||||
assertNotNull("The GemFire Cache was not properly initialized!", cache);
|
||||
|
||||
Region customers = cache.getRegion("Customers");
|
||||
|
||||
assertNotNull(customers);
|
||||
assertEquals("Customers", customers.getName());
|
||||
assertEquals("/Customers", customers.getFullPath());
|
||||
|
||||
Region accounts = customers.getSubregion("Accounts");
|
||||
|
||||
assertNotNull(accounts);
|
||||
assertEquals("Accounts", accounts.getName());
|
||||
assertEquals("/Customers/Accounts", accounts.getFullPath());
|
||||
|
||||
Region cacheAccounts = cache.getRegion("/Customers/Accounts");
|
||||
|
||||
assertSame(accounts, cacheAccounts);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSpringSubRegionConfiguration() {
|
||||
assertNotNull("The /Customers/Accounts SubRegion was not properly initialized!", accounts);
|
||||
assertEquals("Accounts", accounts.getName());
|
||||
assertEquals("/Customers/Accounts", accounts.getFullPath());
|
||||
|
||||
RegionAttributes regionAttributes = accounts.getAttributes();
|
||||
|
||||
assertNotNull(regionAttributes);
|
||||
assertEquals(DataPolicy.PERSISTENT_REPLICATE, regionAttributes.getDataPolicy());
|
||||
assertEquals(20, regionAttributes.getConcurrencyLevel());
|
||||
assertTrue(regionAttributes.isDiskSynchronous());
|
||||
assertTrue(regionAttributes.getIgnoreJTA());
|
||||
assertFalse(regionAttributes.getIndexMaintenanceSynchronous());
|
||||
assertEquals(1000, regionAttributes.getInitialCapacity());
|
||||
assertEquals(Long.class, regionAttributes.getKeyConstraint());
|
||||
assertEquals(Scope.DISTRIBUTED_ACK, regionAttributes.getScope());
|
||||
assertTrue(regionAttributes.getStatisticsEnabled());
|
||||
assertEquals(String.class, regionAttributes.getValueConstraint());
|
||||
assertNotNull(regionAttributes.getCacheListeners());
|
||||
assertEquals(1, regionAttributes.getCacheListeners().length);
|
||||
assertTrue(regionAttributes.getCacheListeners()[0] instanceof SimpleCacheListener);
|
||||
assertTrue(regionAttributes.getCacheLoader() instanceof SimpleCacheLoader);
|
||||
assertTrue(regionAttributes.getCacheWriter() instanceof SimpleCacheWriter);
|
||||
|
||||
EvictionAttributes evictionAttributes = regionAttributes.getEvictionAttributes();
|
||||
|
||||
assertNotNull(evictionAttributes);
|
||||
assertEquals(EvictionAction.OVERFLOW_TO_DISK, evictionAttributes.getAction());
|
||||
assertEquals(10000, evictionAttributes.getMaximum());
|
||||
|
||||
MembershipAttributes membershipAttributes = regionAttributes.getMembershipAttributes();
|
||||
|
||||
assertNotNull(membershipAttributes);
|
||||
assertNotNull(membershipAttributes.getRequiredRoles());
|
||||
assertEquals(1, membershipAttributes.getRequiredRoles().size());
|
||||
assertTrue(membershipAttributes.getRequiredRoles().iterator().next().getName().equalsIgnoreCase("TEST"));
|
||||
assertEquals(LossAction.LIMITED_ACCESS, membershipAttributes.getLossAction());
|
||||
assertEquals(ResumptionAction.REINITIALIZE, membershipAttributes.getResumptionAction());
|
||||
|
||||
SubscriptionAttributes subscriptionAttributes = regionAttributes.getSubscriptionAttributes();
|
||||
|
||||
assertNotNull(subscriptionAttributes);
|
||||
assertEquals(InterestPolicy.CACHE_CONTENT, subscriptionAttributes.getInterestPolicy());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.data.gemfire.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
@@ -28,7 +27,7 @@ import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
* bean definition with both data-policy and shortcut specified.
|
||||
* <p/>
|
||||
* @author John Blum
|
||||
* @see org.junit.Assert
|
||||
* @see org.junit.Test
|
||||
* @since 1.3.3
|
||||
*/
|
||||
public class ClientRegionUsingDataPolicyAndShortcutTest {
|
||||
|
||||
@@ -24,24 +24,31 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.data.gemfire.SubRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.ReplicatedRegionFactoryBean;
|
||||
import org.springframework.data.gemfire.TestUtils;
|
||||
import org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer;
|
||||
import org.springframework.test.context.ContextConfiguration;
|
||||
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
|
||||
|
||||
import com.gemstone.gemfire.cache.AttributesFactory;
|
||||
import com.gemstone.gemfire.cache.Cache;
|
||||
import com.gemstone.gemfire.cache.CacheLoader;
|
||||
import com.gemstone.gemfire.cache.Region;
|
||||
import com.gemstone.gemfire.cache.RegionAttributes;
|
||||
|
||||
/**
|
||||
* The SubRegionNamespaceTest class is a test suite of test cases testing the contract and functionality of
|
||||
* Region/SubRegion creation in a GemFire Cache.
|
||||
* <p/>
|
||||
* @author David Turanski
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.junit.runner.RunWith
|
||||
* @see org.springframework.data.gemfire.test.GemfireTestApplicationContextInitializer
|
||||
* @see org.springframework.test.context.ContextConfiguration
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@ContextConfiguration(locations = "subregion-ns.xml", initializers = GemfireTestApplicationContextInitializer.class)
|
||||
@RunWith(SpringJUnit4ClassRunner.class)
|
||||
@ContextConfiguration(locations="subregion-ns.xml",
|
||||
initializers=GemfireTestApplicationContextInitializer.class)
|
||||
@SuppressWarnings("deprecation")
|
||||
public class SubRegionNamespaceTest {
|
||||
|
||||
@Autowired
|
||||
@@ -51,6 +58,7 @@ public class SubRegionNamespaceTest {
|
||||
@Test
|
||||
public void testNestedRegionsCreated() {
|
||||
Cache cache = context.getBean(Cache.class);
|
||||
|
||||
assertNotNull(cache.getRegion("parent"));
|
||||
assertNotNull(cache.getRegion("/parent/child"));
|
||||
assertNotNull(cache.getRegion("/parent/child/grandchild"));
|
||||
@@ -59,35 +67,31 @@ public class SubRegionNamespaceTest {
|
||||
@SuppressWarnings("rawtypes")
|
||||
@Test
|
||||
public void testNestedReplicatedRegions() {
|
||||
Region parent = null;
|
||||
parent = context.getBean("parent", Region.class);
|
||||
Cache cache = context.getBean(Cache.class);
|
||||
Region parent = context.getBean("parent", Region.class);
|
||||
Region child = context.getBean("/parent/child", Region.class);
|
||||
Region grandchild = context.getBean("/parent/child/grandchild", Region.class);
|
||||
|
||||
assertNotNull(child);
|
||||
assertEquals("/parent/child", child.getFullPath());
|
||||
assertSame(child, parent.getSubregion("child"));
|
||||
|
||||
assertNotNull(grandchild);
|
||||
assertEquals("/parent/child/grandchild", grandchild.getFullPath());
|
||||
assertSame(grandchild, child.getSubregion("grandchild"));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unused", "rawtypes", "unchecked" })
|
||||
@SuppressWarnings({ "rawtypes", "unchecked" })
|
||||
@Test
|
||||
public void testMixedNestedRegions() {
|
||||
Cache cache = context.getBean(Cache.class);
|
||||
|
||||
Region parent = context.getBean("replicatedParent", Region.class);
|
||||
|
||||
Region child = context.getBean("/replicatedParent/replicatedChild", Region.class);
|
||||
Region grandchild = context.getBean("/replicatedParent/replicatedChild/partitionedGrandchild", Region.class);
|
||||
|
||||
assertNotNull(child);
|
||||
assertEquals("/replicatedParent/replicatedChild", child.getFullPath());
|
||||
|
||||
assertEquals(child, parent.getSubregion("replicatedChild"));
|
||||
assertNotNull(grandchild);
|
||||
assertEquals("/replicatedParent/replicatedChild/partitionedGrandchild", grandchild.getFullPath());
|
||||
assertSame(grandchild, child.getSubregion("partitionedGrandchild"));
|
||||
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
@@ -100,25 +104,29 @@ public class SubRegionNamespaceTest {
|
||||
assertEquals("/parentWithSiblings/child2", child2.getFullPath());
|
||||
assertSame(child1, parent.getSubregion("child1"));
|
||||
assertSame(child2, parent.getSubregion("child2"));
|
||||
|
||||
Region grandchild1 = context.getBean("/parentWithSiblings/child1/grandChild11", Region.class);
|
||||
assertEquals("/parentWithSiblings/child1/grandChild11", grandchild1.getFullPath());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unused", "rawtypes" })
|
||||
@SuppressWarnings({ "rawtypes", "unused" })
|
||||
@Test
|
||||
public void testComplexNestedRegions() throws Exception {
|
||||
Region parent = context.getBean("complexNested", Region.class);
|
||||
Region child1 = context.getBean("/complexNested/child1", Region.class);
|
||||
Region child2 = context.getBean("/complexNested/child2", Region.class);
|
||||
Region grandchild1 = context.getBean("/complexNested/child1/grandChild11", Region.class);
|
||||
Region grandchild11 = context.getBean("/complexNested/child1/grandChild11", Region.class);
|
||||
|
||||
SubRegionFactoryBean grandchild1fb = context.getBean("&/complexNested/child1/grandChild11",
|
||||
SubRegionFactoryBean.class);
|
||||
assertNotNull(grandchild1fb);
|
||||
RegionAttributes attr = grandchild1fb.create();
|
||||
assertNotNull(attr);
|
||||
CacheLoader cl = attr.getCacheLoader();
|
||||
assertNotNull(cl);
|
||||
ReplicatedRegionFactoryBean grandchild11FactoryBean = context.getBean("&/complexNested/child1/grandChild11",
|
||||
ReplicatedRegionFactoryBean.class);
|
||||
|
||||
assertNotNull(grandchild11FactoryBean);
|
||||
|
||||
CacheLoader expectedCacheLoader = TestUtils.readField("cacheLoader", grandchild11FactoryBean);
|
||||
|
||||
assertNotNull(expectedCacheLoader);
|
||||
|
||||
CacheLoader actualCacheLoader = grandchild11.getAttributes().getCacheLoader();
|
||||
|
||||
assertSame(expectedCacheLoader, actualCacheLoader);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
* 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.config;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.springframework.beans.factory.BeanCreationException;
|
||||
import org.springframework.context.support.ClassPathXmlApplicationContext;
|
||||
|
||||
/**
|
||||
* The SubRegionWithInvalidDataPolicyTest class is a test suite of test cases testing the data-policy and persistent
|
||||
* attributes settings are consistent for GemFire SubRegion bean definitions.
|
||||
* <p/>
|
||||
* @author John Blum
|
||||
* @see org.junit.Test
|
||||
* @see org.springframework.test.context.junit4.SpringJUnit4ClassRunner
|
||||
* @since GemFire 7.0.1
|
||||
* @since Spring Data GemFire 1.4.0
|
||||
*/
|
||||
public class SubRegionWithInvalidDataPolicyTest {
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testSubRegionBeanDefinitionWithInconsistentDataPolicy() {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("/org/springframework/data/gemfire/config/subregion-with-invalid-datapolicy.xml");
|
||||
}
|
||||
catch (BeanCreationException expected) {
|
||||
//expected.printStackTrace(System.err);
|
||||
assertTrue(expected.getMessage().contains("Error creating bean with name '/Parent/Child'"));
|
||||
assertTrue(expected.getCause() instanceof IllegalArgumentException);
|
||||
assertEquals("Data Policy 'PERSISTENT_PARTITION' is not supported in Replicated Regions.",
|
||||
expected.getCause().getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
@Test(expected = BeanCreationException.class)
|
||||
public void testSubRegionBeanDefinitionWithInvalidDataPolicyPersistentSettings() {
|
||||
try {
|
||||
new ClassPathXmlApplicationContext("/org/springframework/data/gemfire/config/subregion-with-inconsistent-datapolicy-persistent-settings.xml");
|
||||
}
|
||||
catch (BeanCreationException expected) {
|
||||
//expected.printStackTrace(System.err);
|
||||
assertTrue(expected.getMessage().contains("Error creating bean with name '/Parent/Child'"));
|
||||
assertTrue(expected.getCause() instanceof IllegalArgumentException);
|
||||
assertEquals("Data Policy 'REPLICATE' is invalid when persistent is true.",
|
||||
expected.getCause().getMessage());
|
||||
throw expected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -42,19 +42,19 @@ import com.gemstone.gemfire.cache.RegionService;
|
||||
import com.gemstone.gemfire.cache.Scope;
|
||||
import com.gemstone.gemfire.cache.SubscriptionAttributes;
|
||||
import com.gemstone.gemfire.cache.query.QueryService;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
*
|
||||
* @author John Blum
|
||||
*/
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public class MockRegionFactory<K,V> {
|
||||
|
||||
|
||||
private static QueryService queryService = mock(QueryService.class);
|
||||
private static RegionService regionService = mock(RegionService.class);
|
||||
|
||||
|
||||
private AttributesFactory<K,V> attributesFactory;
|
||||
|
||||
|
||||
private final StubCache cache;
|
||||
|
||||
public MockRegionFactory(StubCache cache) {
|
||||
@@ -64,50 +64,55 @@ public class MockRegionFactory<K,V> {
|
||||
public RegionFactory<K, V> createMockRegionFactory() {
|
||||
return createMockRegionFactory(null);
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public RegionFactory<K, V> createMockRegionFactory(RegionAttributes<K,V> attributes) {
|
||||
attributesFactory = attributes == null?
|
||||
new AttributesFactory<K,V>() :
|
||||
new AttributesFactory<K,V>(attributes) ;
|
||||
//Workaround for GemFire bug
|
||||
if(attributes !=null) {
|
||||
attributesFactory.setLockGrantor(attributes.isLockGrantor());
|
||||
}
|
||||
|
||||
final RegionFactory<K, V> regionFactory = mock(RegionFactory.class);
|
||||
|
||||
when(regionFactory.create(anyString())).thenAnswer(new Answer<Region>() {
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public RegionFactory<K, V> createMockRegionFactory(RegionAttributes<K,V> attributes) {
|
||||
attributesFactory = (attributes != null ? new AttributesFactory<K,V>(attributes)
|
||||
: new AttributesFactory<K,V>());
|
||||
|
||||
//Workaround for GemFire bug
|
||||
if (attributes !=null) {
|
||||
attributesFactory.setLockGrantor(attributes.isLockGrantor());
|
||||
}
|
||||
|
||||
final RegionFactory<K, V> regionFactory = mock(RegionFactory.class);
|
||||
|
||||
when(regionFactory.create(anyString())).thenAnswer(new Answer<Region>() {
|
||||
@Override
|
||||
public Region answer(InvocationOnMock invocation) throws Throwable {
|
||||
String name = (String)invocation.getArguments()[0];
|
||||
String name = (String) invocation.getArguments()[0];
|
||||
Region region = mockRegion(name);
|
||||
cache.allRegions().put(name, region);
|
||||
return region;
|
||||
}});
|
||||
|
||||
|
||||
when(regionFactory.createSubregion(any(Region.class),anyString())).thenAnswer(new Answer<Region>() {
|
||||
}
|
||||
});
|
||||
|
||||
when(regionFactory.createSubregion(any(Region.class),anyString())).thenAnswer(new Answer<Region>() {
|
||||
@Override
|
||||
public Region answer(InvocationOnMock invocation) throws Throwable {
|
||||
Region parent = (Region)invocation.getArguments()[0];
|
||||
String name = (String)invocation.getArguments()[1];
|
||||
|
||||
String parentName = null;
|
||||
Region parent = (Region) invocation.getArguments()[0];
|
||||
String name = (String) invocation.getArguments()[1];
|
||||
String parentRegionName = null;
|
||||
|
||||
for (String key: cache.allRegions().keySet()) {
|
||||
if (cache.allRegions().get(key).equals(parent)) {
|
||||
parentName = key;
|
||||
parentRegionName = key;
|
||||
}
|
||||
}
|
||||
String regionName = parentName.startsWith("/") ? parentName+"/"+name : "/"+parentName+"/"+ name;
|
||||
Region subRegion = mockRegion(regionName);
|
||||
cache.allRegions().put(regionName, subRegion);
|
||||
|
||||
assert parentRegionName != null : "The parent Region name was null!";
|
||||
|
||||
String subRegionName = (parentRegionName.startsWith("/") ? parentRegionName+"/"+name
|
||||
: "/"+parentRegionName+"/"+ name);
|
||||
|
||||
Region subRegion = mockRegion(subRegionName);
|
||||
|
||||
cache.allRegions().put(subRegionName, subRegion);
|
||||
|
||||
return subRegion;
|
||||
}});
|
||||
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
when(regionFactory.setCacheLoader(any(CacheLoader.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -116,7 +121,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setCacheWriter(any(CacheWriter.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -125,8 +130,8 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
when(regionFactory.addAsyncEventQueueId(anyString())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -135,7 +140,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.addCacheListener(any(CacheListener.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -144,7 +149,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setEvictionAttributes(any(EvictionAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -153,7 +158,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setEntryIdleTimeout(any(ExpirationAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -171,7 +176,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setEntryTimeToLive(any(ExpirationAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -189,7 +194,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setRegionIdleTimeout(any(ExpirationAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -198,7 +203,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setRegionTimeToLive(any(ExpirationAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -207,7 +212,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setScope(any(Scope.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -216,7 +221,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setDataPolicy(any(DataPolicy.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -225,7 +230,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setEarlyAck(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -234,7 +239,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setMulticastEnabled(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -243,7 +248,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setPoolName(anyString())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -252,7 +257,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setEnableGateway(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -261,7 +266,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setEnableAsyncConflation(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -270,7 +275,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setEnableSubscriptionConflation(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -279,7 +284,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setKeyConstraint(any(Class.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -288,7 +293,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setValueConstraint(any(Class.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -297,7 +302,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setInitialCapacity(anyInt())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -307,7 +312,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setLoadFactor(anyInt())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -316,7 +321,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setConcurrencyLevel(anyInt())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -325,7 +330,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setConcurrencyChecksEnabled(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -334,7 +339,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setDiskWriteAttributes(any(DiskWriteAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -343,7 +348,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setDiskStoreName(anyString())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -352,7 +357,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setDiskSynchronous(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -361,7 +366,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setDiskDirs(any(File[].class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -370,7 +375,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setDiskDirsAndSizes(any(File[].class),any(int[].class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -380,7 +385,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setPartitionAttributes(any(PartitionAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -389,7 +394,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setMembershipAttributes(any(MembershipAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -398,7 +403,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setIndexMaintenanceSynchronous(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -407,7 +412,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setStatisticsEnabled(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -416,7 +421,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setIgnoreJTA(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -425,7 +430,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setLockGrantor(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -435,7 +440,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setSubscriptionAttributes(any(SubscriptionAttributes.class))).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -444,7 +449,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setGatewayHubId(anyString())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -453,7 +458,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.setCloningEnabled(anyBoolean())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -462,7 +467,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.addGatewaySenderId(anyString())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -471,7 +476,7 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
when(regionFactory.addAsyncEventQueueId(anyString())).thenAnswer(new Answer<RegionFactory>(){
|
||||
@Override
|
||||
public RegionFactory answer(InvocationOnMock invocation) throws Throwable {
|
||||
@@ -480,82 +485,80 @@ public class MockRegionFactory<K,V> {
|
||||
return regionFactory;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
return regionFactory;
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
RegionFactory createRegionFactory() {
|
||||
return createMockRegionFactory();
|
||||
}
|
||||
|
||||
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
public Region mockRegion(String name) {
|
||||
RegionService regionService = mockRegionService();
|
||||
Region region = mock(Region.class);
|
||||
when(region.getRegionService()).thenReturn(regionService);
|
||||
|
||||
when(region.getAttributes()).thenAnswer(new Answer<RegionAttributes>() {
|
||||
|
||||
when(region.getRegionService()).thenReturn(regionService);
|
||||
|
||||
when(region.getAttributes()).thenAnswer(new Answer<RegionAttributes>() {
|
||||
@Override
|
||||
public RegionAttributes answer(InvocationOnMock invocation) throws Throwable {
|
||||
|
||||
RegionAttributes attributes = attributesFactory.create();
|
||||
|
||||
return attributes;
|
||||
}
|
||||
|
||||
});
|
||||
when(region.getName()).thenReturn(name);
|
||||
|
||||
when(region.getSubregion(anyString())).thenAnswer(new Answer<Region>() {
|
||||
|
||||
when(region.getFullPath()).thenReturn(name);
|
||||
when(region.getName()).thenReturn(name);
|
||||
|
||||
when(region.getSubregion(anyString())).thenAnswer(new Answer<Region>() {
|
||||
@Override
|
||||
public Region answer(InvocationOnMock invocation) throws Throwable {
|
||||
Region parent = (Region) invocation.getMock();
|
||||
|
||||
String parentRegionName = parent.getName();
|
||||
String subRegionName = (String) invocation.getArguments()[0];
|
||||
String subRegionPath = (parentRegionName.startsWith("/") ? parentRegionName+"/"+subRegionName
|
||||
: "/"+parentRegionName+"/"+subRegionName);
|
||||
|
||||
Region region = cache.getRegion(subRegionPath);
|
||||
|
||||
return region;
|
||||
}
|
||||
});
|
||||
|
||||
when(region.createSubregion(anyString(), any(RegionAttributes.class))).thenAnswer(new Answer<Region>() {
|
||||
@Override
|
||||
public Region answer(InvocationOnMock invocation) throws Throwable {
|
||||
String name = (String) invocation.getArguments()[0];
|
||||
Region parent = (Region)invocation.getMock();
|
||||
String parentName = parent.getName();
|
||||
String regionName = parentName.startsWith("/") ? parentName+"/"+ name :
|
||||
"/"+parentName+"/"+ name;
|
||||
RegionAttributes attributes = (RegionAttributes) invocation.getArguments()[1];
|
||||
|
||||
Region region = cache.getRegion(regionName);
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
when(region.createSubregion(anyString(),any(RegionAttributes.class))).thenAnswer(new Answer<Region>() {
|
||||
|
||||
@Override
|
||||
public Region answer(InvocationOnMock invocation) throws Throwable {
|
||||
String name = (String)invocation.getArguments()[0];
|
||||
RegionAttributes attributes = (RegionAttributes)invocation.getArguments()[1];
|
||||
|
||||
Region parent = (Region)invocation.getMock();
|
||||
Region parent = (Region) invocation.getMock();
|
||||
String parentName = parent.getName();
|
||||
String regionName = parentName.startsWith("/") ? parentName+"/"+name : "/"+parentName+"/"+ name;
|
||||
|
||||
|
||||
Region subRegion = new MockRegionFactory(cache).createMockRegionFactory(attributes).create(regionName);
|
||||
when(subRegion.getFullPath()).thenReturn(regionName);
|
||||
|
||||
|
||||
cache.allRegions().put(regionName, subRegion);
|
||||
|
||||
return subRegion;
|
||||
}});
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
return region;
|
||||
}
|
||||
|
||||
|
||||
public static RegionService mockRegionService() {
|
||||
|
||||
when(regionService.getQueryService()).thenReturn(queryService);
|
||||
return regionService;
|
||||
}
|
||||
|
||||
|
||||
public static QueryService mockQueryService() {
|
||||
return queryService;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
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-3.0.xsd
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire-1.3.xsd">
|
||||
|
||||
<gfe:cache/>
|
||||
|
||||
<gfe:replicated-region id="Customers" persistent="false">
|
||||
<gfe:replicated-region name="Accounts"
|
||||
concurrency-level="20"
|
||||
destroy="true"
|
||||
disk-synchronous="true"
|
||||
ignore-jta="true"
|
||||
index-update-type="asynchronous"
|
||||
initial-capacity="1000"
|
||||
key-constraint="java.lang.Long"
|
||||
persistent="true"
|
||||
scope="distributed-ack"
|
||||
statistics="true"
|
||||
value-constraint="java.lang.String">
|
||||
<!-- NOTE Async Event Queue and Gateway Sender tests are covered in the subregionsubelement-ns.xml and associated test class -->
|
||||
<gfe:cache-listener>
|
||||
<bean class="org.springframework.data.gemfire.SimpleCacheListener"/>
|
||||
</gfe:cache-listener>
|
||||
<gfe:cache-loader>
|
||||
<bean class="org.springframework.data.gemfire.SimpleCacheLoader"/>
|
||||
</gfe:cache-loader>
|
||||
<gfe:cache-writer>
|
||||
<bean class="org.springframework.data.gemfire.SimpleCacheWriter"/>
|
||||
</gfe:cache-writer>
|
||||
<gfe:membership-attributes loss-action="limited-access" required-roles="TEST" resumption-action="reinitialize"/>
|
||||
<gfe:subscription type="CACHE_CONTENT"/>
|
||||
<gfe:eviction action="OVERFLOW_TO_DISK" threshold="10000"/>
|
||||
</gfe:replicated-region>
|
||||
</gfe:replicated-region>
|
||||
|
||||
</beans>
|
||||
@@ -7,6 +7,8 @@
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
">
|
||||
|
||||
<bean class="org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor"/>
|
||||
|
||||
<gfe:pool>
|
||||
<gfe:locator host="localhost" port="10334"/>
|
||||
</gfe:pool>
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<?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"
|
||||
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: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/util http://www.springframework.org/schema/util/spring-util.xsd" >
|
||||
<gfe:cache />
|
||||
http://www.springframework.org/schema/gemfire http://www.springframework.org/schema/gemfire/spring-gemfire.xsd
|
||||
">
|
||||
|
||||
<gfe:cache/>
|
||||
|
||||
<gfe:replicated-region id="parent">
|
||||
<gfe:replicated-region name="child">
|
||||
@@ -15,36 +15,35 @@
|
||||
</gfe:replicated-region>
|
||||
</gfe:replicated-region>
|
||||
|
||||
|
||||
<gfe:replicated-region id="replicatedParent">
|
||||
<gfe:replicated-region id="replicatedParent">
|
||||
<gfe:replicated-region name="replicatedChild">
|
||||
<gfe:partitioned-region name="partitionedGrandchild"/>
|
||||
</gfe:replicated-region>
|
||||
</gfe:replicated-region>
|
||||
|
||||
<gfe:replicated-region id="parentWithSiblings">
|
||||
<gfe:replicated-region id="parentWithSiblings">
|
||||
<gfe:replicated-region name="child1">
|
||||
<gfe:replicated-region name="grandChild11"/>
|
||||
<gfe:replicated-region name="grandChild12"/>
|
||||
<gfe:replicated-region name="grandChild12"/>
|
||||
</gfe:replicated-region>
|
||||
<gfe:replicated-region name="child2"/>
|
||||
</gfe:replicated-region>
|
||||
|
||||
<gfe:replicated-region id="complexNested">
|
||||
<gfe:cache-listener ref="c-listener"/>
|
||||
<gfe:replicated-region name="child1">
|
||||
<gfe:replicated-region name="grandChild11">
|
||||
<gfe:cache-loader ref="c-loader"/>
|
||||
</gfe:replicated-region>
|
||||
<gfe:replicated-region name="grandChild12"/>
|
||||
</gfe:replicated-region>
|
||||
<gfe:replicated-region name="child2">
|
||||
<gfe:cache-writer ref="c-writer"/>
|
||||
</gfe:replicated-region>
|
||||
</gfe:replicated-region>
|
||||
<gfe:replicated-region id="complexNested">
|
||||
<gfe:cache-listener ref="c-listener"/>
|
||||
<gfe:replicated-region name="child1">
|
||||
<gfe:replicated-region name="grandChild11">
|
||||
<gfe:cache-loader ref="c-loader"/>
|
||||
</gfe:replicated-region>
|
||||
<gfe:replicated-region name="grandChild12"/>
|
||||
</gfe:replicated-region>
|
||||
<gfe:replicated-region name="child2">
|
||||
<gfe:cache-writer ref="c-writer"/>
|
||||
</gfe:replicated-region>
|
||||
</gfe:replicated-region>
|
||||
|
||||
<bean id="c-listener" class="org.springframework.data.gemfire.SimpleCacheListener"/>
|
||||
<bean id="c-listener" class="org.springframework.data.gemfire.SimpleCacheListener"/>
|
||||
<bean id="c-loader" class="org.springframework.data.gemfire.SimpleCacheLoader"/>
|
||||
<bean id="c-writer" class="org.springframework.data.gemfire.SimpleCacheWriter"/>
|
||||
|
||||
</beans>
|
||||
</beans>
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
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
|
||||
">
|
||||
|
||||
<bean class="org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor"/>
|
||||
|
||||
<gfe:cache/>
|
||||
|
||||
<gfe:replicated-region id="Parent" persistent="false" destroy="true">
|
||||
<gfe:replicated-region name="Child" data-policy="REPLICATE" persistent="true"/>
|
||||
</gfe:replicated-region>
|
||||
|
||||
</beans>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<beans xmlns="http://www.springframework.org/schema/beans"
|
||||
xmlns:gfe="http://www.springframework.org/schema/gemfire"
|
||||
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
|
||||
">
|
||||
|
||||
<bean class="org.springframework.data.gemfire.test.GemfireTestBeanPostProcessor"/>
|
||||
|
||||
<gfe:cache/>
|
||||
|
||||
<gfe:replicated-region id="Parent" persistent="false" destroy="true">
|
||||
<gfe:replicated-region name="Child" data-policy="PERSISTENT_PARTITION"/>
|
||||
</gfe:replicated-region>
|
||||
|
||||
</beans>
|
||||
Reference in New Issue
Block a user