From 664d53447f982d2ec97d98321181b2b0b4b8fbfc Mon Sep 17 00:00:00 2001 From: John Blum Date: Tue, 7 Oct 2014 15:35:08 -0700 Subject: [PATCH] SGF-338 - Both and SDG XML namespace elements allow for more than one 'CustomExpiry' bean to be set in the Region Expiration Attributes although GemFire only allows one! --- .../data/gemfire/config/ParsingUtils.java | 4 +- .../gemfire/config/spring-gemfire-2.0.xsd | 28 +-- ...gionExpirationAttributesNamespaceTest.java | 74 +++++++ ...RegionEvictionAttributesNamespaceTest.java | 13 +- ...gionExpirationAttributesNamespaceTest.java | 186 ++++++++++++++++++ ...irationAttributesNamespaceTest-context.xml | 30 +++ ...ictionAttributesNamespaceTest-context.xml} | 0 ...irationAttributesNamespaceTest-context.xml | 56 ++++++ 8 files changed, 367 insertions(+), 24 deletions(-) create mode 100644 src/test/java/org/springframework/data/gemfire/config/InvalidRegionExpirationAttributesNamespaceTest.java create mode 100644 src/test/java/org/springframework/data/gemfire/config/RegionExpirationAttributesNamespaceTest.java create mode 100644 src/test/resources/org/springframework/data/gemfire/config/InvalidRegionExpirationAttributesNamespaceTest-context.xml rename src/test/resources/org/springframework/data/gemfire/config/{regions-with-eviction-attributes-ns.xml => RegionEvictionAttributesNamespaceTest-context.xml} (100%) create mode 100644 src/test/resources/org/springframework/data/gemfire/config/RegionExpirationAttributesNamespaceTest-context.xml diff --git a/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java b/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java index b2a29c11..17f17c99 100644 --- a/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java +++ b/src/main/java/org/springframework/data/gemfire/config/ParsingUtils.java @@ -276,9 +276,9 @@ abstract class ParsingUtils { result |= parseExpiration(element, "region-tti", "regionIdleTimeout", regionAttributesBuilder); result |= parseExpiration(element, "entry-ttl", "entryTimeToLive", regionAttributesBuilder); result |= parseExpiration(element, "entry-tti", "entryIdleTimeout", regionAttributesBuilder); - result |= parseCustomExpiration(element, parserContext, "custom-entry-ttl","customEntryTimeToLive", + result |= parseCustomExpiration(element, parserContext, "custom-entry-ttl", "customEntryTimeToLive", regionAttributesBuilder); - result |= parseCustomExpiration(element, parserContext, "custom-entry-tti","customEntryIdleTimeout", + result |= parseCustomExpiration(element, parserContext, "custom-entry-tti", "customEntryIdleTimeout", regionAttributesBuilder); if (result) { diff --git a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-2.0.xsd b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-2.0.xsd index 52ff7416..dc01405e 100644 --- a/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-2.0.xsd +++ b/src/main/resources/org/springframework/data/gemfire/config/spring-gemfire-2.0.xsd @@ -510,8 +510,7 @@ The name of the region definition.]]> - + - + - + - + - + - + @@ -595,7 +589,7 @@ Time to live configuration for the region entries. Default: no expiration. @@ -609,8 +603,7 @@ Time to idle (or idle timeout) configuration for the region entries. Default: no ]]> - + @@ -618,7 +611,7 @@ Time to idle (or idle timeout) configuration for the region entries. Default: no @@ -1614,8 +1607,7 @@ When the region or cached object expires, it is destroyed locally only. Not supp - + replicateExample; + + @Resource(name = "PreloadedExample") + private Region preloadedExample; + + @Resource(name = "PartitionExample") + private Region partitionExample; + + @Resource(name = "LocalExample") + private Region localExample; + + protected void assertRegionMetaData(final Region region, final String regionName, final DataPolicy dataPolicy) { + assertRegionMetaData(region, regionName, Region.SEPARATOR + regionName, dataPolicy); + } + + protected void assertRegionMetaData(final Region region, final String regionName, final String regionFullPath, + final DataPolicy dataPolicy) { + assertNotNull(String.format("The '%1$s' Region was not properly configured and initialized!", regionName), region); + assertEquals(regionName, region.getName()); + assertEquals(regionFullPath, region.getFullPath()); + assertNotNull(region.getAttributes()); + assertEquals(dataPolicy, region.getAttributes().getDataPolicy()); + } + + protected void assertNoExpiration(final ExpirationAttributes expirationAttributes) { + if (expirationAttributes != null) { + //assertEquals(ExpirationAction.INVALIDATE, expirationAttributes.getAction()); + assertEquals(0, expirationAttributes.getTimeout()); + } + } + + protected void assertExpirationAttributes(final ExpirationAttributes expirationAttributes, + final int timeout, final ExpirationAction action) { + assertNotNull(expirationAttributes); + assertEquals(timeout, expirationAttributes.getTimeout()); + assertEquals(action, expirationAttributes.getAction()); + } + + @SuppressWarnings("unchecked") + protected void assertCustomExpiry(final CustomExpiry customExpiry, final String name, + final int timeout, final ExpirationAction action) { + assertNotNull(customExpiry); + assertEquals(name, customExpiry.toString()); + assertExpirationAttributes(customExpiry.getExpiry(mock(Region.Entry.class)), timeout, action); + } + + @Test + public void testReplicateExampleExpirationAttributes() { + assertRegionMetaData(replicateExample, "ReplicateExample", DataPolicy.REPLICATE); + assertExpirationAttributes(replicateExample.getAttributes().getEntryTimeToLive(), + 600, ExpirationAction.DESTROY); + assertExpirationAttributes(replicateExample.getAttributes().getEntryIdleTimeout(), + 300, ExpirationAction.INVALIDATE); + assertNull(replicateExample.getAttributes().getCustomEntryTimeToLive()); + assertNull(replicateExample.getAttributes().getCustomEntryIdleTimeout()); + } + + @Test + public void testPreloadedExampleExpirationAttributes() { + assertRegionMetaData(preloadedExample, "PreloadedExample", DataPolicy.PRELOADED); + assertExpirationAttributes(preloadedExample.getAttributes().getEntryTimeToLive(), + 120, ExpirationAction.LOCAL_DESTROY); + assertNoExpiration(preloadedExample.getAttributes().getEntryIdleTimeout()); + assertNull(preloadedExample.getAttributes().getCustomEntryTimeToLive()); + assertNull(preloadedExample.getAttributes().getCustomEntryIdleTimeout()); + } + + @Test + public void testPartitionExampleExpirationAttributes() { + assertRegionMetaData(partitionExample, "PartitionExample", DataPolicy.PARTITION); + assertExpirationAttributes(partitionExample.getAttributes().getEntryTimeToLive(), + 300, ExpirationAction.DESTROY); + assertNoExpiration(partitionExample.getAttributes().getEntryIdleTimeout()); + assertNull(partitionExample.getAttributes().getCustomEntryTimeToLive()); + assertCustomExpiry(partitionExample.getAttributes().getCustomEntryIdleTimeout(), "PartitionCustomExpiry", + 120, ExpirationAction.INVALIDATE); + } + + @Test + public void testLocalExampleExpirationAttributes() { + assertRegionMetaData(localExample, "LocalExample", DataPolicy.NORMAL); + assertNoExpiration(localExample.getAttributes().getEntryTimeToLive()); + assertNoExpiration(localExample.getAttributes().getEntryIdleTimeout()); + assertCustomExpiry(localExample.getAttributes().getCustomEntryTimeToLive(), "LocalTtlCustomExpiry", + 180, ExpirationAction.LOCAL_DESTROY); + assertCustomExpiry(localExample.getAttributes().getCustomEntryIdleTimeout(), "LocalTtiCustomExpiry", + 60, ExpirationAction.LOCAL_INVALIDATE); + } + + public static class TestCustomExpiry implements CustomExpiry { + + private ExpirationAction action; + + private Integer timeout; + + private String name; + + @Override + public ExpirationAttributes getExpiry(final Region.Entry kvEntry) { + Assert.state(timeout != null, "The expiration 'timeout' must be specified!"); + Assert.state(action != null, "The expiration 'action' must be specified!"); + return new ExpirationAttributes(timeout, action); + } + + public void setAction(final ExpirationAction action) { + this.action = action; + } + + public void setName(final String name) { + this.name = name; + } + + public void setTimeout(final Integer timeout) { + this.timeout = timeout; + } + + @Override + public void close() { + } + + @Override + public String toString() { + return this.name; + } + } + +} diff --git a/src/test/resources/org/springframework/data/gemfire/config/InvalidRegionExpirationAttributesNamespaceTest-context.xml b/src/test/resources/org/springframework/data/gemfire/config/InvalidRegionExpirationAttributesNamespaceTest-context.xml new file mode 100644 index 00000000..92d4c3e9 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/config/InvalidRegionExpirationAttributesNamespaceTest-context.xml @@ -0,0 +1,30 @@ + + + + + InvalidRegionExpirationAttributesNamespaceTest + 0 + config + + + + + + + + + + + + diff --git a/src/test/resources/org/springframework/data/gemfire/config/regions-with-eviction-attributes-ns.xml b/src/test/resources/org/springframework/data/gemfire/config/RegionEvictionAttributesNamespaceTest-context.xml similarity index 100% rename from src/test/resources/org/springframework/data/gemfire/config/regions-with-eviction-attributes-ns.xml rename to src/test/resources/org/springframework/data/gemfire/config/RegionEvictionAttributesNamespaceTest-context.xml diff --git a/src/test/resources/org/springframework/data/gemfire/config/RegionExpirationAttributesNamespaceTest-context.xml b/src/test/resources/org/springframework/data/gemfire/config/RegionExpirationAttributesNamespaceTest-context.xml new file mode 100644 index 00000000..29fa02f3 --- /dev/null +++ b/src/test/resources/org/springframework/data/gemfire/config/RegionExpirationAttributesNamespaceTest-context.xml @@ -0,0 +1,56 @@ + + + + + RegionExpirationAttributesNamespaceTest + 0 + config + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +