You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by ag...@apache.org on 2017/05/23 17:24:57 UTC
geode git commit: GEODE-2918 Close cache when
ConflictingPersistentDataException is thrown.
Repository: geode
Updated Branches:
refs/heads/develop adbdf50f1 -> 3cbb6fcd0
GEODE-2918 Close cache when ConflictingPersistentDataException is thrown.
During disk recovery the ConflictingPersistentDataException is not handled
properly; it should have logged an error and closed the cache.
When it is handled incorrectly, the cache is in inconsistent state; causing
other operations to fail in unexpected ways.
Project: http://git-wip-us.apache.org/repos/asf/geode/repo
Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/3cbb6fcd
Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/3cbb6fcd
Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/3cbb6fcd
Branch: refs/heads/develop
Commit: 3cbb6fcd08272dc6a5219e9092b34ae29eed79f3
Parents: adbdf50
Author: Anil <ag...@pivotal.io>
Authored: Mon May 22 10:42:08 2017 -0700
Committer: Anil <ag...@pivotal.io>
Committed: Tue May 23 10:18:23 2017 -0700
----------------------------------------------------------------------
.../apache/geode/cache/DiskAccessException.java | 9 +
.../ConflictingPersistentDataException.java | 6 +-
.../geode/internal/cache/LocalRegion.java | 9 +-
.../geode/internal/cache/ProxyBucketRegion.java | 5 +-
.../persistence/PersistenceAdvisorImpl.java | 16 +-
.../PersistentPartitionedRegionDUnitTest.java | 169 ++++++++++++++++---
.../PersistentPartitionedRegionTestBase.java | 82 ++++++++-
7 files changed, 262 insertions(+), 34 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/geode/blob/3cbb6fcd/geode-core/src/main/java/org/apache/geode/cache/DiskAccessException.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/cache/DiskAccessException.java b/geode-core/src/main/java/org/apache/geode/cache/DiskAccessException.java
index fb640cd..51018a5 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/DiskAccessException.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/DiskAccessException.java
@@ -110,6 +110,15 @@ public class DiskAccessException extends CacheRuntimeException {
}
/**
+ * Constructs a new <code>DiskAccessException</code> with a message string.
+ *
+ * @param msg the message string
+ */
+ public DiskAccessException(String msg) {
+ super(msg);
+ }
+
+ /**
* Returns true if this exception originated from a remote node.
*/
public boolean isRemote() {
http://git-wip-us.apache.org/repos/asf/geode/blob/3cbb6fcd/geode-core/src/main/java/org/apache/geode/cache/persistence/ConflictingPersistentDataException.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/cache/persistence/ConflictingPersistentDataException.java b/geode-core/src/main/java/org/apache/geode/cache/persistence/ConflictingPersistentDataException.java
index 9bf7234..3ea7c3e 100644
--- a/geode-core/src/main/java/org/apache/geode/cache/persistence/ConflictingPersistentDataException.java
+++ b/geode-core/src/main/java/org/apache/geode/cache/persistence/ConflictingPersistentDataException.java
@@ -15,7 +15,7 @@
package org.apache.geode.cache.persistence;
import org.apache.geode.GemFireException;
-import org.apache.geode.admin.AdminDistributedSystem;
+import org.apache.geode.cache.DiskAccessException;
/**
* Thrown when a member with persistence is recovering, and it discovers that the data it has on
@@ -28,7 +28,7 @@ import org.apache.geode.admin.AdminDistributedSystem;
*
* @since GemFire 6.5
*/
-public class ConflictingPersistentDataException extends GemFireException {
+public class ConflictingPersistentDataException extends DiskAccessException {
private static final long serialVersionUID = -2629287782021455875L;
@@ -48,6 +48,4 @@ public class ConflictingPersistentDataException extends GemFireException {
super(cause);
}
-
-
}
http://git-wip-us.apache.org/repos/asf/geode/blob/3cbb6fcd/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
index 8e7ec68..4446d48 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/LocalRegion.java
@@ -81,6 +81,7 @@ import org.apache.geode.cache.control.ResourceManager;
import org.apache.geode.cache.execute.Function;
import org.apache.geode.cache.execute.ResultCollector;
import org.apache.geode.cache.partition.PartitionRegionHelper;
+import org.apache.geode.cache.persistence.ConflictingPersistentDataException;
import org.apache.geode.cache.query.FunctionDomainException;
import org.apache.geode.cache.query.Index;
import org.apache.geode.cache.query.IndexMaintenanceException;
@@ -6595,8 +6596,12 @@ public class LocalRegion extends AbstractRegion implements LoaderHelperFactory,
* @see InitialImageOperation#processChunk
*/
public void handleDiskAccessException(DiskAccessException dae, boolean duringInitialization) {
- // these will rethrow the originating exception
- if (duringInitialization || causedByRDE(dae)) {
+
+ if (duringInitialization && !(dae instanceof ConflictingPersistentDataException)) {
+ return;
+ }
+
+ if (causedByRDE(dae)) {
return;
}
http://git-wip-us.apache.org/repos/asf/geode/blob/3cbb6fcd/geode-core/src/main/java/org/apache/geode/internal/cache/ProxyBucketRegion.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/ProxyBucketRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/ProxyBucketRegion.java
index ab90a05..7e60e6a 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/ProxyBucketRegion.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/ProxyBucketRegion.java
@@ -23,9 +23,9 @@ import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import org.apache.logging.log4j.Logger;
-
import org.apache.geode.CancelCriterion;
import org.apache.geode.InternalGemFireError;
+import org.apache.geode.cache.DiskAccessException;
import org.apache.geode.cache.EvictionAttributes;
import org.apache.geode.cache.Region;
import org.apache.geode.cache.RegionAttributes;
@@ -472,6 +472,9 @@ public class ProxyBucketRegion implements Bucket {
}
persistenceAdvisor.initializeMembershipView();
+ } catch (DiskAccessException dae) {
+ this.partitionedRegion.handleDiskAccessException(dae);
+ throw dae;
} catch (RuntimeException e) {
exception = e;
throw e;
http://git-wip-us.apache.org/repos/asf/geode/blob/3cbb6fcd/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistenceAdvisorImpl.java
----------------------------------------------------------------------
diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistenceAdvisorImpl.java b/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistenceAdvisorImpl.java
index fc95f0b..f4a0da9 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistenceAdvisorImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/cache/persistence/PersistenceAdvisorImpl.java
@@ -66,6 +66,7 @@ public class PersistenceAdvisorImpl implements PersistenceAdvisor {
private volatile Set<PersistentMemberID> allMembersWaitingFor;
private volatile Set<PersistentMemberID> offlineMembersWaitingFor;
protected final Object lock;
+ private static PersistenceAdvisorObserver observer = null;
private static final int PERSISTENT_VIEW_RETRY =
Integer.getInteger(DistributionConfig.GEMFIRE_PREFIX + "PERSISTENT_VIEW_RETRY", 5);
@@ -716,6 +717,11 @@ public class PersistenceAdvisorImpl implements PersistenceAdvisor {
throws ReplyException {
PersistentStateQueryResults remoteStates = getMyStateOnMembers(replicates);
boolean equal = false;
+
+ if (observer != null) {
+ observer.observe(regionPath);
+ }
+
for (Map.Entry<InternalDistributedMember, PersistentMemberState> entry : remoteStates.stateOnPeers
.entrySet()) {
InternalDistributedMember member = entry.getKey();
@@ -730,12 +736,12 @@ public class PersistenceAdvisorImpl implements PersistenceAdvisor {
.toLocalizedString(myId));
}
-
if (myId != null && stateOnPeer == null) {
String message = LocalizedStrings.CreatePersistentRegionProcessor_SPLIT_DISTRIBUTED_SYSTEM
.toLocalizedString(regionPath, member, remoteId, myId);
throw new ConflictingPersistentDataException(message);
}
+
if (myId != null && stateOnPeer == PersistentMemberState.EQUAL) {
equal = true;
}
@@ -1338,4 +1344,12 @@ public class PersistenceAdvisorImpl implements PersistenceAdvisor {
public boolean isOnline() {
return online;
}
+
+ public static interface PersistenceAdvisorObserver {
+ default public void observe(String regionPath) {}
+ }
+
+ public static void setPersistenceAdvisorObserver(PersistenceAdvisorObserver o) {
+ observer = o;
+ }
}
http://git-wip-us.apache.org/repos/asf/geode/blob/3cbb6fcd/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDUnitTest.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDUnitTest.java
index 3ee5cf0..edd86e7 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionDUnitTest.java
@@ -19,7 +19,6 @@ import static org.awaitility.Awaitility.*;
import static java.util.concurrent.TimeUnit.*;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.*;
-import static org.junit.Assert.fail;
import java.io.DataInput;
import java.io.DataOutput;
@@ -32,11 +31,12 @@ import java.util.HashSet;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;
-
import org.apache.geode.DataSerializable;
import org.apache.geode.cache.AttributesFactory;
import org.apache.geode.cache.Cache;
@@ -49,6 +49,7 @@ import org.apache.geode.cache.EvictionAction;
import org.apache.geode.cache.EvictionAttributes;
import org.apache.geode.cache.ExpirationAction;
import org.apache.geode.cache.ExpirationAttributes;
+import org.apache.geode.cache.PartitionAttributes;
import org.apache.geode.cache.PartitionAttributesFactory;
import org.apache.geode.cache.PartitionedRegionStorageException;
import org.apache.geode.cache.Region;
@@ -75,6 +76,8 @@ import org.apache.geode.distributed.internal.DistributionMessageObserver;
import org.apache.geode.distributed.internal.ReplyException;
import org.apache.geode.internal.AvailablePort;
import org.apache.geode.internal.cache.GemFireCacheImpl;
+import org.apache.geode.internal.cache.PartitionedRegion;
+import org.apache.geode.internal.cache.PartitionedRegionTestHelper;
import org.apache.geode.internal.cache.InitialImageOperation.RequestImageMessage;
import org.apache.geode.internal.cache.control.InternalResourceManager;
import org.apache.geode.internal.cache.partitioned.ManageBucketMessage.ManageBucketReplyMessage;
@@ -93,6 +96,7 @@ import org.apache.geode.test.dunit.Wait;
import org.apache.geode.test.dunit.WaitCriterion;
import org.apache.geode.test.junit.categories.DistributedTest;
import org.apache.geode.test.junit.categories.FlakyTest;
+import org.awaitility.Awaitility;
/**
* Tests the basic use cases for PR persistence.
@@ -2007,50 +2011,59 @@ public class PersistentPartitionedRegionDUnitTest extends PersistentPartitionedR
Host host = Host.getHost(0);
VM vm0 = host.getVM(0);
VM vm1 = host.getVM(1);
+
createPR(vm0, 0);
// create some buckets
createData(vm0, 0, 2, "a");
closePR(vm0);
+
createPR(vm1, 0);
// create an overlapping bucket
-
-
- // TODO - this test hangs if vm1 has some buckets that vm0
- // does not have. The problem is that when vm0 starts up and gets a conflict
- // on some buckets, it updates it's view for other buckets.
- // createData(vm1, 1, 3, "a");
createData(vm1, 1, 2, "a");
- // this should throw a conflicting data exception.
- IgnoredException expect =
- IgnoredException.addIgnoredException("ConflictingPersistentDataException", vm0);
+ IgnoredException[] expectVm0 =
+ {IgnoredException.addIgnoredException("ConflictingPersistentDataException", vm0),
+ IgnoredException.addIgnoredException("CacheClosedException", vm0)};
+
try {
+ // This results in ConflictingPersistentDataException. As part of
+ // GEODE-2918, the cache is closed, when ConflictingPersistentDataException
+ // is encountered.
createPR(vm0, 0);
fail("should have seen a conflicting data exception");
- } catch (Exception e) {
- if (!(e.getCause() instanceof ConflictingPersistentDataException)) {
- throw e;
+ } catch (Exception ex) {
+ boolean expectedException = false;
+ if (ex.getCause() instanceof CacheClosedException) {
+ CacheClosedException cce = (CacheClosedException) ex.getCause();
+ if (cce.getCause() instanceof ConflictingPersistentDataException) {
+ expectedException = true;
+ }
+ }
+ if (!expectedException) {
+ throw ex;
}
} finally {
- expect.remove();
+ for (IgnoredException ie : expectVm0) {
+ ie.remove();
+ }
}
- // This will hang, if this test fails.
- // TODO - DAN - I'm not even sure what this means here?
- // It seems like if anything, vm1 should not have updated it's persistent
- // view from vm0 because vm0 was in conflict!
- // In fact, this is a bit of a problem, because now vm1 is dependent
- // on vm vm0.
- expect = IgnoredException.addIgnoredException("PartitionOfflineException", vm1);
+ IgnoredException expectVm1 =
+ IgnoredException.addIgnoredException("PartitionOfflineException", vm1);
try {
createData(vm1, 0, 1, "a");
- fail("Should have seen a PartitionOfflineException for bucket 0");
} catch (Exception e) {
+ // This could happen due to a race in bucket-region creation.
+ // When vm0 was started, it could so happen that it successfully
+ // created bucket0 before it encountered ConflictingPersistentDataException
+ // with bucket1. This is a problem, the vm1 is dependent on vm0 for
+ // bucket0. We need to fix that. The workaround is to stop vm1 and then
+ // restart.
if (!(e.getCause() instanceof PartitionOfflineException)) {
throw e;
}
} finally {
- expect.remove();
+ expectVm1.remove();
}
closePR(vm1);
@@ -2062,6 +2075,102 @@ public class PersistentPartitionedRegionDUnitTest extends PersistentPartitionedR
checkData(vm0, 2, 3, null);
}
+ @Test
+ public void testDiskConflictWithRedundancy() throws Exception {
+ Host host = Host.getHost(0);
+ VM vm0 = host.getVM(0);
+ VM vm1 = host.getVM(1);
+
+ createPR(vm0, 1);
+ // create some buckets
+ createData(vm0, 0, 2, "a");
+ closePR(vm0);
+
+ createPR(vm1, 1);
+ // create an overlapping bucket
+ createData(vm1, 1, 2, "a");
+
+ IgnoredException[] expectVm0 =
+ {IgnoredException.addIgnoredException("ConflictingPersistentDataException", vm0),
+ IgnoredException.addIgnoredException("CacheClosedException", vm0)};
+
+ try {
+ createPR(vm0, 1);
+ fail("should have seen a conflicting data exception");
+ } catch (Exception ex) {
+ boolean expectedException = false;
+ if (ex.getCause() instanceof CacheClosedException) {
+ CacheClosedException cce = (CacheClosedException) ex.getCause();
+ if (cce.getCause() instanceof ConflictingPersistentDataException) {
+ expectedException = true;
+ }
+ }
+ if (!expectedException) {
+ throw ex;
+ }
+ } finally {
+ for (IgnoredException ie : expectVm0) {
+ ie.remove();
+ }
+ }
+
+ closePR(vm1);
+ }
+
+ @Test
+ public void testDiskConflictWithCoLocation() throws Exception {
+ Host host = Host.getHost(0);
+ VM vm0 = host.getVM(0);
+ VM vm1 = host.getVM(1);
+
+ // createPR(vm0, 1);
+ createCoLocatedPR(vm0, 1, false);
+
+ // create some buckets
+ createData(vm0, 0, 2, "a");
+ createData(vm0, 0, 2, "a", PR_CHILD_REGION_NAME);
+ closePR(vm0, PR_CHILD_REGION_NAME);
+ closePR(vm0);
+
+ // createPR(vm1, 1);
+ createCoLocatedPR(vm1, 1, false);
+ // create an overlapping bucket
+ createData(vm1, 2, 4, "a");
+ createData(vm1, 2, 4, "a", PR_CHILD_REGION_NAME);
+
+ IgnoredException[] expectVm0 =
+ {IgnoredException.addIgnoredException("ConflictingPersistentDataException", vm0),
+ IgnoredException.addIgnoredException("CacheClosedException", vm0)};
+
+ try {
+ createCoLocatedPR(vm0, 1, true);
+ // Cache should have closed due to ConflictingPersistentDataException
+ vm0.invoke(() -> {
+ Awaitility.await().atMost(MAX_WAIT, TimeUnit.MILLISECONDS)
+ .until(() -> basicGetCache().isClosed());
+ basicGetCache().getCancelCriterion();
+ });
+ } catch (Exception ex) {
+ boolean expectedException = false;
+ if (ex.getCause() instanceof CacheClosedException) {
+ CacheClosedException cce = (CacheClosedException) ex.getCause();
+ if (cce.getCause() instanceof ConflictingPersistentDataException) {
+ expectedException = true;
+ }
+ }
+ if (!expectedException) {
+ throw ex;
+ }
+ } finally {
+ for (IgnoredException ie : expectVm0) {
+ ie.remove();
+ }
+ }
+
+ closePR(vm1, PR_CHILD_REGION_NAME);
+ closePR(vm1);
+ }
+
/**
* Test to make sure that primaries are rebalanced after recovering from disk.
*/
@@ -2238,7 +2347,17 @@ public class PersistentPartitionedRegionDUnitTest extends PersistentPartitionedR
vm3.invoke(createPersistentReplicate);
}
- private static class RecoveryObserver extends InternalResourceManager.ResourceObserverAdapter {
+ private void createChildPR(VM vm) {
+ vm.invoke(() -> {
+ PartitionAttributes PRatts =
+ new PartitionAttributesFactory().setColocatedWith(PR_REGION_NAME).create();
+ PartitionedRegion child =
+ (PartitionedRegion) PartitionedRegionTestHelper.createPartionedRegion("CHILD", PRatts);
+ });
+ }
+
+ private static final class RecoveryObserver
+ extends InternalResourceManager.ResourceObserverAdapter {
final CountDownLatch recoveryDone = new CountDownLatch(1);
@Override
http://git-wip-us.apache.org/repos/asf/geode/blob/3cbb6fcd/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionTestBase.java
----------------------------------------------------------------------
diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionTestBase.java b/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionTestBase.java
index ccdd38d..ec0ec4c 100644
--- a/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionTestBase.java
+++ b/geode-core/src/test/java/org/apache/geode/internal/cache/partitioned/PersistentPartitionedRegionTestBase.java
@@ -34,6 +34,7 @@ import org.apache.geode.cache.RegionAttributes;
import org.apache.geode.cache.control.RebalanceFactory;
import org.apache.geode.cache.partition.PartitionRegionHelper;
import org.apache.geode.cache.partition.PartitionRegionInfo;
+import org.apache.geode.cache.persistence.ConflictingPersistentDataException;
import org.apache.geode.cache.persistence.PersistentID;
import org.apache.geode.distributed.internal.membership.InternalDistributedMember;
import org.apache.geode.internal.cache.DiskRegion;
@@ -43,6 +44,7 @@ import org.apache.geode.internal.cache.PartitionedRegionDataStore;
import org.apache.geode.internal.cache.control.InternalResourceManager;
import org.apache.geode.internal.cache.control.InternalResourceManager.ResourceObserver;
import org.apache.geode.internal.cache.persistence.PersistenceAdvisor;
+import org.apache.geode.internal.cache.persistence.PersistenceAdvisorImpl;
import org.apache.geode.internal.cache.persistence.PersistentMemberID;
import org.apache.geode.test.dunit.Assert;
import org.apache.geode.test.dunit.AsyncInvocation;
@@ -54,6 +56,7 @@ import org.apache.geode.test.dunit.VM;
import org.apache.geode.test.dunit.Wait;
import org.apache.geode.test.dunit.WaitCriterion;
import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase;
+import org.awaitility.Awaitility;
import java.io.BufferedReader;
import java.io.File;
@@ -70,6 +73,7 @@ import java.util.concurrent.TimeUnit;
public abstract class PersistentPartitionedRegionTestBase extends JUnit4CacheTestCase {
public static String PR_REGION_NAME = "region";
+ public static String PR_CHILD_REGION_NAME = "childRegion";
// This must be bigger than the dunit ack-wait-threshold for the revoke
// tests. The command line is setting the ack-wait-threshold to be
// 60 seconds.
@@ -205,7 +209,7 @@ public abstract class PersistentPartitionedRegionTestBase extends JUnit4CacheTes
public void run() {
Cache cache = getCache();
- LogWriterUtils.getLogWriter().info("creating data in " + regionName);
+ cache.getLogger().info("creating data in " + regionName);
Region region = cache.getRegion(regionName);
for (int i = startKey; i < endKey; i++) {
@@ -380,6 +384,82 @@ public abstract class PersistentPartitionedRegionTestBase extends JUnit4CacheTes
return createPR;
}
+ protected void createCoLocatedPR(VM vm, int setRedundantCopies,
+ boolean setPersistenceAdvisorObserver) {
+ vm.invoke(() -> {
+ Cache cache = getCache();
+
+ // Wait for both nested PRs to be created
+ final CountDownLatch recoveryDone = new CountDownLatch(2);
+ ResourceObserver observer = new InternalResourceManager.ResourceObserverAdapter() {
+ @Override
+ public void recoveryFinished(Region region) {
+ recoveryDone.countDown();
+ }
+ };
+ InternalResourceManager.setResourceObserver(observer);
+
+ // Wait for parent and child region to be created.
+ // And throw exception while region is getting initialized.
+ final CountDownLatch childRegionCreated = new CountDownLatch(1);
+ if (setPersistenceAdvisorObserver) {
+ PersistenceAdvisorImpl
+ .setPersistenceAdvisorObserver(new PersistenceAdvisorImpl.PersistenceAdvisorObserver() {
+ public void observe(String regionPath) {
+ if (regionPath.contains(PR_CHILD_REGION_NAME)) {
+ try {
+ childRegionCreated.await(MAX_WAIT, TimeUnit.MILLISECONDS);
+ } catch (Exception e) {
+ Assert.fail("Exception", e);
+ }
+ throw new ConflictingPersistentDataException(
+ "Testing Cache Close with ConflictingPersistentDataException for region."
+ + regionPath);
+ }
+ }
+ });
+ }
+
+ // Create region.
+ try {
+ DiskStore ds = cache.findDiskStore("disk");
+ if (ds == null) {
+ ds = cache.createDiskStoreFactory().setDiskDirs(getDiskDirs()).create("disk");
+ }
+
+ // Parent Region
+ PartitionAttributesFactory paf =
+ new PartitionAttributesFactory().setRedundantCopies(setRedundantCopies);
+ AttributesFactory af = new AttributesFactory();
+ af.setPartitionAttributes(paf.create());
+ af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
+ af.setDiskStoreName("disk");
+ cache.createRegion(PR_REGION_NAME, af.create());
+
+ // Colocated region
+ paf = (new PartitionAttributesFactory()).setRedundantCopies(setRedundantCopies)
+ .setColocatedWith(PR_REGION_NAME);
+ af = new AttributesFactory();
+ af.setPartitionAttributes(paf.create());
+ af.setDataPolicy(DataPolicy.PERSISTENT_PARTITION);
+ af.setDiskStoreName("disk");
+ cache.createRegion(PR_CHILD_REGION_NAME, af.create());
+
+ // Count down on region create.
+ childRegionCreated.countDown();
+
+ try {
+ recoveryDone.await(MAX_WAIT, TimeUnit.MILLISECONDS);
+ } catch (InterruptedException e) {
+ Assert.fail("interrupted", e);
+ }
+
+ } finally {
+ PersistenceAdvisorImpl.setPersistenceAdvisorObserver(null);
+ }
+ });
+ }
+
private SerializableRunnable getCreatePRRunnable(final int redundancy, final int recoveryDelay) {
return getCreatePRRunnable(redundancy, recoveryDelay, 113);
}