Implements SGF-204 changing the default behavior or Region lookups.

This commit is contained in:
John Blum
2014-03-24 13:48:26 -07:00
26 changed files with 811 additions and 83 deletions

View File

@@ -40,6 +40,8 @@ public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>,
protected final Log log = LogFactory.getLog(getClass());
private Boolean lookupEnabled = Boolean.TRUE;
private GemFireCache cache;
private Region<?, ?> parent;
@@ -59,11 +61,13 @@ public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>,
synchronized (cache) {
//region = (getParent() != null ? getParent().getSubregion(regionName) : cache.getRegion(regionName));
if (getParent() != null) {
region = getParent().getSubregion(regionName);
}
else {
region = cache.getRegion(regionName);
if (isLookupEnabled()) {
if (getParent() != null) {
region = getParent().getSubregion(regionName);
}
else {
region = cache.getRegion(regionName);
}
}
if (region != null) {
@@ -166,6 +170,18 @@ public class RegionLookupFactoryBean<K, V> implements FactoryBean<Region<K, V>>,
this.regionName = regionName;
}
private boolean isLookupEnabled() {
return Boolean.TRUE.equals(getLookupEnabled());
}
public Boolean getLookupEnabled() {
return lookupEnabled;
}
public void setLookupEnabled(Boolean lookupEnabled) {
this.lookupEnabled = lookupEnabled;
}
protected Region<K, V> getRegion() {
return region;
}

View File

@@ -75,8 +75,6 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
private Interest<K>[] interests;
private Region<?, ?> parent;
private RegionAttributes<K, V> attributes;
private Resource snapshot;
@@ -91,6 +89,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
}
@Override
@SuppressWarnings("deprecation")
protected Region<K, V> lookupFallback(GemFireCache cache, String regionName) throws Exception {
Assert.isTrue(cache instanceof ClientCache, String.format("Unable to create regions from %1$s", cache));
@@ -145,13 +144,13 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
factory.setDiskStoreName(diskStoreName);
}
Region<K, V> clientRegion = (this.parent != null ? factory.createSubregion(parent, regionName)
Region<K, V> clientRegion = (getParent() != null ? factory.createSubregion(getParent(), regionName)
: factory.create(regionName));
if (log.isInfoEnabled()) {
if (parent != null) {
if (getParent() != null) {
log.info(String.format("Created new Client Cache sub-Region [%1$s] under parent Region [%2$s].",
regionName, parent.getName()));
regionName, getParent().getName()));
}
else {
log.info(String.format("Created new Client Cache Region [%1$s].", regionName));
@@ -237,15 +236,13 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
* @see com.gemstone.gemfire.cache.DataPolicy
*/
protected void assertDataPolicyAndPersistentAttributeAreCompatible(final DataPolicy resolvedDataPolicy) {
final boolean persistentNotSpecified = (this.persistent == null);
if (resolvedDataPolicy.withPersistence()) {
Assert.isTrue(persistentNotSpecified || isPersistent(), String.format(
Assert.isTrue(isPersistentUnspecified() || isPersistent(), String.format(
"Data Policy '%1$s' is invalid when persistent is false.", resolvedDataPolicy));
}
else {
// NOTE otherwise, the Data Policy is without persistence, so...
Assert.isTrue(persistentNotSpecified || isNotPersistent(), String.format(
Assert.isTrue(isPersistentUnspecified() || isNotPersistent(), String.format(
"Data Policy '%1$s' is invalid when persistent is true.", resolvedDataPolicy));
}
}
@@ -380,7 +377,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
/**
* Sets the pool used by this client.
*
* @param pool
* @param pool the GemFire client pool.
*/
public void setPool(Pool pool) {
Assert.notNull(pool, "pool cannot be null");
@@ -390,7 +387,7 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
/**
* Sets the pool name used by this client.
*
* @param poolName
* @param poolName a String specify the name of the GemFire client pool.
*/
public void setPoolName(String poolName) {
Assert.hasText(poolName, "pool name is required");
@@ -474,7 +471,8 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
/**
* Sets the name of disk store to use for overflow and persistence
* @param diskStoreName
* <p/>
* @param diskStoreName a String specifying the 'name' of the client Region Disk Store.
*/
public void setDiskStoreName(String diskStoreName) {
this.diskStoreName = diskStoreName;
@@ -494,8 +492,8 @@ public class ClientRegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V>
setDataPolicy(resolvedDataPolicy);
}
public void setParent(Region<?, ?> parent) {
this.parent = parent;
protected boolean isPersistentUnspecified() {
return (persistent == null);
}
protected boolean isPersistent() {

View File

@@ -78,6 +78,7 @@ abstract class AbstractRegionParser extends AbstractSingleBeanDefinitionParser {
}
ParsingUtils.setPropertyValue(element, builder, "name");
ParsingUtils.setPropertyValue(element, builder, "ignore-if-exists", "lookupEnabled");
ParsingUtils.setPropertyValue(element, builder, "data-policy");
ParsingUtils.setPropertyValue(element, builder, "persistent");
ParsingUtils.setPropertyValue(element, builder, "shortcut");

View File

@@ -59,8 +59,9 @@ class ClientRegionParser extends AbstractRegionParser {
ParsingUtils.setPropertyValue(element, builder, "destroy");
}
ParsingUtils.setPropertyValue(element, builder, "data-policy", "dataPolicyName");
ParsingUtils.setPropertyValue(element, builder, "name");
ParsingUtils.setPropertyValue(element, builder, "data-policy", "dataPolicyName");
ParsingUtils.setPropertyValue(element, builder, "ignore-if-exists", "lookupEnabled");
ParsingUtils.setPropertyValue(element, builder, "persistent");
ParsingUtils.setPropertyValue(element, builder, "pool-name");
ParsingUtils.setPropertyValue(element, builder, "shortcut");

View File

@@ -548,6 +548,29 @@ CustomExpiry Time to idle (or idle timeout) configuration for the region entries
</xsd:element>
</xsd:choice>
</xsd:sequence>
<xsd:attribute name="ignore-if-exists" type="xsd:string" default="false">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the Region bean definition should perform a "lookup" first, using any existing Region already defined
with the same name in the Cache (thus, reverting to pre-1.4.0 behavior, e.g. 1.3.x), before attempting to create
the Region
The default is false, meaning the default behavior is always attempt to "create" the Region first.
Prior to 1.4.0, the default behavior was to perform a "lookup" first and then try to "create" the Region.
This functionality is useful in situations where multiple Spring context configuration files exists and 1 or more
define the same Region with the same semantics, such that the application dynamically loads configuration files,
or creates new Spring contexts as needed and application components (e.g. application DAOs) have runtime dependencies
on those Regions.
WARNING...
It is recommended that this feature be used carefully as the first bean definition to create the Region wins.
So if there are multiple, conflicting bean definitions (with difference semantics for evictions/expiration, etc)
for the "same" Region (by name), then this can cause confusion or have unexpected consequences for the application.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="persistent" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[