Implements JIRA improvement SGF-281 involving the addition of logic in SDG to avoid setting the Disk Store Name on the RegionAttributes used to a create a Region in the RegionFactoryBean when the Region is neither 'persistent' nor has an Eviction policy of Overflow To Disk. GemFire erroneously throws an IllegalStateException when the Region references a Disk Store but is not configured with persistence or overflow, which should not matter. Also fixed JIRA issues SGF-282 where the Eviction 'action' is ignored for PARTITION Regions when the 'threshold' is not set.

This commit is contained in:
John Blum
2014-04-28 15:55:05 -07:00
parent 0c25e14be9
commit 426c110187
11 changed files with 743 additions and 485 deletions

View File

@@ -44,16 +44,23 @@ public class LocalRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
if (dataPolicy == null || DataPolicy.NORMAL.equals(dataPolicy)) {
// NOTE this is safe since a LOCAL Scoped NORMAL Region requiring persistence can be satisfied with
// PERSISTENT_REPLICATE, per the RegionShortcut.LOCAL_PERSISTENT
regionFactory.setDataPolicy(isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.NORMAL);
DataPolicy resolvedDataPolicy = (isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.NORMAL);
regionFactory.setDataPolicy(resolvedDataPolicy);
setDataPolicy(resolvedDataPolicy);
}
else if (DataPolicy.PRELOADED.equals(dataPolicy)) {
// NOTE this is safe since a LOCAL Scoped PRELOADED Region requiring persistence can be satisfied with
// PERSISTENT_REPLICATE, per the RegionShortcut.LOCAL_PERSISTENT
regionFactory.setDataPolicy(isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.PRELOADED);
DataPolicy resolvedDataPolicy = (isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.PRELOADED);
regionFactory.setDataPolicy(resolvedDataPolicy);
setDataPolicy(resolvedDataPolicy);
}
else if (DataPolicy.PERSISTENT_REPLICATE.equals(dataPolicy)
&& RegionShortcutWrapper.valueOf(getShortcut()).isPersistent()) {
regionFactory.setDataPolicy(dataPolicy);
setDataPolicy(dataPolicy);
}
else {
throw new IllegalArgumentException(String.format("Data Policy '%1$s' is not supported for Local Regions.",

View File

@@ -48,6 +48,7 @@ public class PartitionedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V>
assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy);
regionFactory.setDataPolicy(dataPolicy);
setDataPolicy(dataPolicy);
}
@Override

View File

@@ -34,6 +34,7 @@ import com.gemstone.gemfire.cache.CacheListener;
import com.gemstone.gemfire.cache.CacheLoader;
import com.gemstone.gemfire.cache.CacheWriter;
import com.gemstone.gemfire.cache.DataPolicy;
import com.gemstone.gemfire.cache.EvictionAction;
import com.gemstone.gemfire.cache.GemFireCache;
import com.gemstone.gemfire.cache.PartitionAttributes;
import com.gemstone.gemfire.cache.PartitionAttributesFactory;
@@ -153,7 +154,7 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
resolveDataPolicy(regionFactory, persistent, dataPolicy);
if (diskStoreName != null) {
if (isDiskStoreConfigurationAllowed()) {
regionFactory.setDiskStoreName(diskStoreName);
}
@@ -192,6 +193,16 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
return region;
}
private boolean isDiskStoreConfigurationAllowed() {
boolean allow = (diskStoreName != null);
allow &= (getDataPolicy().withPersistence() || (getAttributes() != null
&& getAttributes().getEvictionAttributes() != null
&& EvictionAction.OVERFLOW_TO_DISK.equals(attributes.getEvictionAttributes().getAction())));
return allow;
}
/**
* Validates that the settings for Data Policy and the 'persistent' attribute in &lt;gfe:*-region&gt; elements
* are compatible.
@@ -453,6 +464,7 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
if (dataPolicy != null) {
assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy);
regionFactory.setDataPolicy(dataPolicy);
setDataPolicy(dataPolicy);
}
else {
resolveDataPolicy(regionFactory, persistent, (String) null);
@@ -477,9 +489,13 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
assertDataPolicyAndPersistentAttributesAreCompatible(resolvedDataPolicy);
regionFactory.setDataPolicy(resolvedDataPolicy);
setDataPolicy(resolvedDataPolicy);
}
else {
regionFactory.setDataPolicy(isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.DEFAULT);
DataPolicy resolvedDataPolicy = (isPersistent() ? DataPolicy.PERSISTENT_REPLICATE : DataPolicy.DEFAULT);
regionFactory.setDataPolicy(resolvedDataPolicy);
setDataPolicy(resolvedDataPolicy);
}
}
@@ -522,6 +538,17 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
this.attributes = attributes;
}
/**
* Returns the attributes used to configure the Region created by this factory as set in the SDG XML namespace
* configuration meta-data, or as set with the setAttributes(:Attributes) method.
*
* @return the RegionAttributes used to configure the Region created by this factory.
* @see com.gemstone.gemfire.cache.RegionAttributes
*/
public RegionAttributes getAttributes() {
return (getRegion() != null ? getRegion().getAttributes() : attributes);
}
/**
* Sets the cache listeners used for the region used by this factory. Used
* only when a new region is created.Overrides the settings specified
@@ -592,6 +619,18 @@ public class RegionFactoryBean<K, V> extends RegionLookupFactoryBean<K, V> imple
this.dataPolicy = new DataPolicyConverter().convert(dataPolicyName);
}
/**
* Gets the "resolved" Data Policy as determined by this RegionFactory when configuring the attributes
* of the Region to be created.
*
* @return the "resolved" Data Policy to be used to create the Region.
* @see com.gemstone.gemfire.cache.DataPolicy
*/
public DataPolicy getDataPolicy() {
Assert.state(dataPolicy != null, "The Data Policy has not been properly resolved yet!");
return dataPolicy;
}
/**
* Sets the name of Disk Store used for either overflow or persistence, or both.
*

View File

@@ -45,6 +45,7 @@ public class ReplicatedRegionFactoryBean<K, V> extends RegionFactoryBean<K, V> {
assertDataPolicyAndPersistentAttributesAreCompatible(dataPolicy);
regionFactory.setDataPolicy(dataPolicy);
setDataPolicy(dataPolicy);
}
@Override

View File

@@ -22,6 +22,8 @@ import org.springframework.beans.factory.InitializingBean;
import com.gemstone.gemfire.cache.EvictionAction;
import com.gemstone.gemfire.cache.EvictionAttributes;
import com.gemstone.gemfire.cache.util.ObjectSizer;
import com.gemstone.gemfire.internal.cache.lru.LRUCapacityController;
import com.gemstone.gemfire.internal.cache.lru.MemLRUCapacityController;
/**
* Simple utility class used for defining nested factory-method like definitions w/o polluting the container with useless beans.
@@ -36,6 +38,11 @@ import com.gemstone.gemfire.cache.util.ObjectSizer;
@SuppressWarnings("unused")
class EvictionAttributesFactoryBean implements FactoryBean<EvictionAttributes>, InitializingBean {
// TODO remove this reference to the GemFire internal class when the Gem team fixes the EvictionAttributes bug!!!
protected static final int DEFAULT_LRU_MAXIMUM_ENTRIES = LRUCapacityController.DEFAULT_MAXIMUM_ENTRIES;
protected static final int DEFAULT_MEMORY_MAXIMUM_SIZE = MemLRUCapacityController.DEFAULT_MAXIMUM_MEGABYTES;
private EvictionAction action = null;
private EvictionAttributes evictionAttributes;
@@ -60,16 +67,12 @@ class EvictionAttributesFactoryBean implements FactoryBean<EvictionAttributes>,
}
return EvictionAttributes.createLRUHeapAttributes(objectSizer, action);
case MEMORY_SIZE:
if (threshold != null) {
return EvictionAttributes.createLRUMemoryAttributes(threshold, objectSizer, action);
}
return EvictionAttributes.createLRUMemoryAttributes(objectSizer, action);
return (threshold != null ? EvictionAttributes.createLRUMemoryAttributes(threshold, objectSizer, action)
: EvictionAttributes.createLRUMemoryAttributes(objectSizer, action));
case ENTRY_COUNT:
default:
if (threshold != null) {
return EvictionAttributes.createLRUEntryAttributes(threshold, action);
}
return EvictionAttributes.createLRUEntryAttributes();
return (threshold != null ? EvictionAttributes.createLRUEntryAttributes(threshold, action)
: EvictionAttributes.createLRUEntryAttributes(DEFAULT_LRU_MAXIMUM_ENTRIES, action));
}
}