GEODE-520: GFSH Alter Region entry-time-to-live-expiration causes subsequent server restart to fail.
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/919d6369 Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/919d6369 Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/919d6369 Branch: refs/heads/feature/GEODE-77 Commit: 919d6369f096dc363653f59d434abe486e9ff8aa Parents: e9aa18b Author: Jens Deppe <[email protected]> Authored: Fri Oct 30 14:00:31 2015 -0700 Committer: Jens Deppe <[email protected]> Committed: Fri Oct 30 14:00:31 2015 -0700 ---------------------------------------------------------------------- .../gemfire/cache/AttributesFactory.java | 18 ++---------- .../gemfire/internal/cache/AbstractRegion.java | 25 ++++++++++++---- .../internal/cache/PartitionedRegion.java | 27 +++++++++++++----- .../gemfire/cache30/RegionTestCase.java | 30 ++++++++++++-------- 4 files changed, 59 insertions(+), 41 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/919d6369/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java index 6af21b1..8c715dc 100644 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/cache/AttributesFactory.java @@ -1509,22 +1509,8 @@ public class AttributesFactory<K,V> { ((PartitionAttributesImpl)pa).validateWhenAllAttributesAreSet(attrs instanceof RegionAttributesCreation); ExpirationAttributes regionIdleTimeout = attrs.getRegionIdleTimeout(); ExpirationAttributes regionTimeToLive = attrs.getRegionTimeToLive(); - if ((regionIdleTimeout.getAction().isInvalidate() && regionIdleTimeout.getTimeout() > 0) - || (regionIdleTimeout.getAction().isLocalInvalidate() && regionIdleTimeout.getTimeout() > 0) - || (regionTimeToLive.getAction().isInvalidate() && regionTimeToLive.getTimeout() > 0) - || (regionTimeToLive.getAction().isLocalInvalidate()) && regionTimeToLive.getTimeout() > 0 ) { - throw new IllegalStateException( - LocalizedStrings.AttributesFactory_INVALIDATE_REGION_NOT_SUPPORTED_FOR_PR.toLocalizedString()); - } - - if ((regionIdleTimeout.getAction().isDestroy() && regionIdleTimeout.getTimeout() > 0) - || (regionIdleTimeout.getAction().isLocalDestroy() && regionIdleTimeout.getTimeout() > 0) - || (regionTimeToLive.getAction().isDestroy() && regionTimeToLive.getTimeout() > 0) - || (regionTimeToLive.getAction().isLocalDestroy() && regionTimeToLive.getTimeout() > 0)) { - throw new IllegalStateException( - LocalizedStrings.AttributesFactory_DESTROY_REGION_NOT_SUPPORTED_FOR_PR - .toLocalizedString()); - } + AbstractRegion.validatePRRegionExpirationAttributes(regionIdleTimeout); + AbstractRegion.validatePRRegionExpirationAttributes(regionTimeToLive); ExpirationAttributes entryIdleTimeout = attrs.getEntryIdleTimeout(); ExpirationAttributes entryTimeToLive = attrs.getEntryTimeToLive(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/919d6369/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java index ed5a390..45adbd6 100644 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/AbstractRegion.java @@ -1300,13 +1300,25 @@ public abstract class AbstractRegion implements Region, RegionAttributes, return old; } - public ExpirationAttributes setRegionIdleTimeout( - ExpirationAttributes idleTimeout) - { + public static void validatePRRegionExpirationAttributes(ExpirationAttributes expAtts) { + if (expAtts.getTimeout() > 0) { + ExpirationAction expAction = expAtts.getAction(); + if (expAction.isInvalidate() || expAction.isLocalInvalidate()) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_INVALIDATE_REGION_NOT_SUPPORTED_FOR_PR.toLocalizedString()); + } else if (expAction.isDestroy() || expAction.isLocalDestroy()) { + throw new IllegalStateException(LocalizedStrings.AttributesFactory_DESTROY_REGION_NOT_SUPPORTED_FOR_PR.toLocalizedString()); + } + } + } + + public ExpirationAttributes setRegionIdleTimeout(ExpirationAttributes idleTimeout) { checkReadiness(); if (idleTimeout == null) { throw new IllegalArgumentException(LocalizedStrings.AbstractRegion_IDLETIMEOUT_MUST_NOT_BE_NULL.toLocalizedString()); } + if (this.getAttributes().getDataPolicy().withPartitioning()) { + validatePRRegionExpirationAttributes(idleTimeout); + } if (idleTimeout.getAction() == ExpirationAction.LOCAL_INVALIDATE && this.dataPolicy.withReplication()) { throw new IllegalArgumentException(LocalizedStrings.AbstractRegion_0_ACTION_IS_INCOMPATIBLE_WITH_THIS_REGIONS_DATA_POLICY.toLocalizedString("idleTimeout")); @@ -1322,13 +1334,14 @@ public abstract class AbstractRegion implements Region, RegionAttributes, return oldAttrs; } - public ExpirationAttributes setRegionTimeToLive( - ExpirationAttributes timeToLive) - { + public ExpirationAttributes setRegionTimeToLive(ExpirationAttributes timeToLive) { checkReadiness(); if (timeToLive == null) { throw new IllegalArgumentException(LocalizedStrings.AbstractRegion_TIMETOLIVE_MUST_NOT_BE_NULL.toLocalizedString()); } + if (this.getAttributes().getDataPolicy().withPartitioning()) { + validatePRRegionExpirationAttributes(timeToLive); + } if (timeToLive.getAction() == ExpirationAction.LOCAL_INVALIDATE && this.dataPolicy.withReplication()) { throw new IllegalArgumentException(LocalizedStrings.AbstractRegion_0_ACTION_IS_INCOMPATIBLE_WITH_THIS_REGIONS_DATA_POLICY.toLocalizedString("timeToLive")); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/919d6369/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java index ce50c52..29137fc 100644 --- a/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java +++ b/gemfire-core/src/main/java/com/gemstone/gemfire/internal/cache/PartitionedRegion.java @@ -100,7 +100,6 @@ import com.gemstone.gemfire.cache.execute.FunctionContext; import com.gemstone.gemfire.cache.execute.FunctionException; import com.gemstone.gemfire.cache.execute.FunctionService; import com.gemstone.gemfire.cache.execute.ResultCollector; -import com.gemstone.gemfire.cache.hdfs.internal.HDFSEntriesSet.HDFSIterator; import com.gemstone.gemfire.cache.hdfs.internal.HDFSStoreFactoryImpl; import com.gemstone.gemfire.cache.hdfs.internal.hoplog.CompactionStatus; import com.gemstone.gemfire.cache.hdfs.internal.hoplog.HDFSFlushQueueFunction; @@ -166,7 +165,6 @@ import com.gemstone.gemfire.internal.Version; import com.gemstone.gemfire.internal.cache.BucketAdvisor.ServerBucketProfile; import com.gemstone.gemfire.internal.cache.CacheDistributionAdvisor.CacheProfile; import com.gemstone.gemfire.internal.cache.DestroyPartitionedRegionMessage.DestroyPartitionedRegionResponse; -import com.gemstone.gemfire.internal.cache.DistributedRegion.DiskPage; import com.gemstone.gemfire.internal.cache.PutAllPartialResultException.PutAllPartialResult; import com.gemstone.gemfire.internal.cache.control.HeapMemoryMonitor; import com.gemstone.gemfire.internal.cache.control.InternalResourceManager; @@ -177,7 +175,6 @@ import com.gemstone.gemfire.internal.cache.execute.AbstractExecution; import com.gemstone.gemfire.internal.cache.execute.FunctionExecutionNodePruner; import com.gemstone.gemfire.internal.cache.execute.FunctionRemoteContext; import com.gemstone.gemfire.internal.cache.execute.InternalFunctionInvocationTargetException; -import com.gemstone.gemfire.internal.cache.execute.InternalRegionFunctionContext; import com.gemstone.gemfire.internal.cache.execute.LocalResultCollector; import com.gemstone.gemfire.internal.cache.execute.PartitionedRegionFunctionExecutor; import com.gemstone.gemfire.internal.cache.execute.PartitionedRegionFunctionResultSender; @@ -215,13 +212,10 @@ import com.gemstone.gemfire.internal.cache.partitioned.InterestEventMessage; import com.gemstone.gemfire.internal.cache.partitioned.InterestEventMessage.InterestEventResponse; import com.gemstone.gemfire.internal.cache.partitioned.InvalidateMessage; import com.gemstone.gemfire.internal.cache.partitioned.InvalidateMessage.InvalidateResponse; -import com.gemstone.gemfire.internal.cache.partitioned.Bucket; import com.gemstone.gemfire.internal.cache.partitioned.PREntriesIterator; import com.gemstone.gemfire.internal.cache.partitioned.PRLocallyDestroyedException; import com.gemstone.gemfire.internal.cache.partitioned.PRSanityCheckMessage; import com.gemstone.gemfire.internal.cache.partitioned.PRUpdateEntryVersionMessage; -import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor.BucketVisitor; -import com.gemstone.gemfire.internal.cache.partitioned.RemoveAllPRMessage; import com.gemstone.gemfire.internal.cache.partitioned.PRUpdateEntryVersionMessage.UpdateEntryVersionResponse; import com.gemstone.gemfire.internal.cache.partitioned.PartitionMessage.PartitionResponse; import com.gemstone.gemfire.internal.cache.partitioned.PartitionedRegionObserver; @@ -232,11 +226,11 @@ import com.gemstone.gemfire.internal.cache.partitioned.PutMessage.PutResult; import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor; import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor.BucketVisitor; import com.gemstone.gemfire.internal.cache.partitioned.RegionAdvisor.PartitionProfile; +import com.gemstone.gemfire.internal.cache.partitioned.RemoveAllPRMessage; import com.gemstone.gemfire.internal.cache.partitioned.RemoveIndexesMessage; import com.gemstone.gemfire.internal.cache.partitioned.SizeMessage; import com.gemstone.gemfire.internal.cache.partitioned.SizeMessage.SizeResponse; import com.gemstone.gemfire.internal.cache.persistence.PRPersistentConfig; -import com.gemstone.gemfire.internal.cache.persistence.query.CloseableIterator; import com.gemstone.gemfire.internal.cache.tier.InterestType; import com.gemstone.gemfire.internal.cache.tier.sockets.BaseCommand; import com.gemstone.gemfire.internal.cache.tier.sockets.ClientProxyMembershipID; @@ -10279,9 +10273,27 @@ public class PartitionedRegion extends LocalRegion implements bucketRegion.getAttributesMutator().setEntryTimeToLive(timeToLive); } } + updatePRConfig(getPRConfigWithLatestExpirationAttributes(), false); return attr; } + private PartitionRegionConfig getPRConfigWithLatestExpirationAttributes(){ + PartitionRegionConfig prConfig = this.prRoot.get(getRegionIdentifier()); + PartitionRegionConfig newConfig = new PartitionRegionConfig( + prConfig.getPRId(), + prConfig.getFullPath(), + prConfig.getPartitionAttrs(), + prConfig.getScope(), + prConfig.getEvictionAttributes(), + this.getRegionIdleTimeout(), + this.getRegionTimeToLive(), + this.getEntryIdleTimeout(), + this.getEntryTimeToLive(), + prConfig.getGatewaySenderIds()); + + return newConfig; + } + /** * Changes the custom timeToLive for values in this region * @@ -10333,6 +10345,7 @@ public class PartitionedRegion extends LocalRegion implements bucketRegion.getAttributesMutator().setEntryIdleTimeout(idleTimeout); } } + updatePRConfig(getPRConfigWithLatestExpirationAttributes(), false); return attr; } http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/919d6369/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/RegionTestCase.java ---------------------------------------------------------------------- diff --git a/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/RegionTestCase.java b/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/RegionTestCase.java index f5b4ab2..35be2d0 100644 --- a/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/RegionTestCase.java +++ b/gemfire-core/src/test/java/com/gemstone/gemfire/cache30/RegionTestCase.java @@ -3750,11 +3750,14 @@ public abstract class RegionTestCase extends CacheTestCase { public void testRegionExpirationAfterMutate() throws CacheException, InterruptedException { + if (getRegionAttributes().getPartitionAttributes() != null) { + return; + } + final String name = this.getUniqueName(); - ; final Object key = "KEY"; final Object value = "VALUE"; - + AttributesFactory factory = new AttributesFactory(getRegionAttributes()); factory.setStatisticsEnabled(true); RegionAttributes attrs = factory.create(); @@ -3768,30 +3771,33 @@ public abstract class RegionTestCase extends CacheTestCase { // Now go from no timeout to a timeout Region.Entry entry = region.getEntry(key); assertEquals(value, entry.getValue()); - region.getAttributesMutator().setRegionIdleTimeout(new ExpirationAttributes(12000/*ms*/, ExpirationAction.INVALIDATE)); + region.getAttributesMutator().setRegionIdleTimeout( + new ExpirationAttributes(12000/*ms*/, ExpirationAction.INVALIDATE)); region.put(key, value); long tilt = System.currentTimeMillis(); ExpiryTask expiryTask = region.getRegionIdleExpiryTask(); long mediumExpiryTime = expiryTask.getExpirationTime(); - region.getAttributesMutator().setRegionIdleTimeout(new ExpirationAttributes(999000/*ms*/, ExpirationAction.INVALIDATE)); + region.getAttributesMutator().setRegionIdleTimeout( + new ExpirationAttributes(999000/*ms*/, ExpirationAction.INVALIDATE)); expiryTask = region.getRegionIdleExpiryTask(); long hugeExpiryTime = expiryTask.getExpirationTime(); ExpiryTask.suspendExpiration(); long shortExpiryTime; try { - region.getAttributesMutator().setRegionIdleTimeout(new ExpirationAttributes(20/*ms*/, ExpirationAction.INVALIDATE)); + region.getAttributesMutator().setRegionIdleTimeout( + new ExpirationAttributes(20/*ms*/, ExpirationAction.INVALIDATE)); expiryTask = region.getRegionIdleExpiryTask(); shortExpiryTime = expiryTask.getExpirationTime(); - } - finally { + } finally { ExpiryTask.permitExpiration(); } - waitForInvalidate(entry, tilt+20, 10); - assertTrue("expected hugeExpiryTime=" + hugeExpiryTime + " to be > than mediumExpiryTime=" + mediumExpiryTime, (hugeExpiryTime - mediumExpiryTime) > 0); - assertTrue("expected mediumExpiryTime=" + mediumExpiryTime + " to be > than shortExpiryTime=" + shortExpiryTime, (mediumExpiryTime - shortExpiryTime) > 0); - } - finally { + waitForInvalidate(entry, tilt + 20, 10); + assertTrue("expected hugeExpiryTime=" + hugeExpiryTime + " to be > than mediumExpiryTime=" + mediumExpiryTime, + (hugeExpiryTime - mediumExpiryTime) > 0); + assertTrue("expected mediumExpiryTime=" + mediumExpiryTime + " to be > than shortExpiryTime=" + shortExpiryTime, + (mediumExpiryTime - shortExpiryTime) > 0); + } finally { System.getProperties().remove(LocalRegion.EXPIRY_MS_PROPERTY); } }
