Repository: geode Updated Branches: refs/heads/develop 284bed968 -> 341a359e0
GEODE-2216: Throwing an exception if index creation fails. Making sure index creation always throws an exception and cleans up the index if the index creation fails. Adding a test that causes index creation failure by failing to deserialize entries. Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/83121963 Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/83121963 Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/83121963 Branch: refs/heads/develop Commit: 831219635b66da79acdbd4849f921104e004ac96 Parents: 284bed9 Author: Dan Smith <upthewatersp...@apache.org> Authored: Wed Dec 14 16:59:51 2016 -0800 Committer: Dan Smith <upthewatersp...@apache.org> Committed: Mon Dec 19 15:31:45 2016 -0800 ---------------------------------------------------------------------- .../geode/internal/cache/PartitionedRegion.java | 16 +++- .../cache/PartitionedRegionQueryDUnitTest.java | 78 +++++++++++++++++++- 2 files changed, 89 insertions(+), 5 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/83121963/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java index 7c3f19b..6a67b59 100755 --- a/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java +++ b/geode-core/src/main/java/org/apache/geode/internal/cache/PartitionedRegion.java @@ -8738,7 +8738,7 @@ public class PartitionedRegion extends LocalRegion // First step is creating all the defined indexes. // Do not send the IndexCreationMsg to remote nodes now. - throwException = + throwException |= createEmptyIndexes(indexDefinitions, remotelyOriginated, indexes, exceptionsMap); // If same indexes are created locally and also being created by a remote index creation msg @@ -8751,18 +8751,26 @@ public class PartitionedRegion extends LocalRegion // Second step is iterating over REs and populating all the created indexes if (unpopulatedIndexes != null && unpopulatedIndexes.size() > 0) { - throwException = populateEmptyIndexes(unpopulatedIndexes, exceptionsMap); + throwException |= populateEmptyIndexes(unpopulatedIndexes, exceptionsMap); } // Third step is to send the message to remote nodes // Locally originated create index request. // Send create request to other PR nodes. - throwException = + throwException |= sendCreateIndexesMessage(remotelyOriginated, indexDefinitions, indexes, exceptionsMap); // If exception is throw in any of the above steps if (throwException) { - throw new MultiIndexCreationException(exceptionsMap); + try { + for (String indexName : exceptionsMap.keySet()) { + Index index = indexManager.getIndex(indexName); + indexManager.removeIndex(index); + removeIndex(index, remotelyOriginated); + } + } finally { + throw new MultiIndexCreationException(exceptionsMap); + } } // set the populate flag for all the created PR indexes http://git-wip-us.apache.org/repos/asf/geode/blob/83121963/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryDUnitTest.java b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryDUnitTest.java index 0196542..a14e9ee 100644 --- a/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryDUnitTest.java +++ b/geode-core/src/test/java/org/apache/geode/internal/cache/PartitionedRegionQueryDUnitTest.java @@ -14,6 +14,12 @@ */ package org.apache.geode.internal.cache; +import java.io.IOException; + +import org.apache.geode.DataSerializable; +import org.apache.geode.cache.query.Struct; +import org.apache.geode.test.dunit.DUnitEnv; +import org.apache.geode.test.dunit.SerializableRunnableIF; import org.junit.experimental.categories.Category; import org.junit.Test; @@ -23,6 +29,9 @@ import org.apache.geode.test.dunit.cache.internal.JUnit4CacheTestCase; import org.apache.geode.test.dunit.internal.JUnit4DistributedTestCase; import org.apache.geode.test.junit.categories.DistributedTest; +import java.io.DataInput; +import java.io.DataOutput; +import java.io.IOException; import java.io.Serializable; import java.sql.Date; import java.util.Arrays; @@ -31,6 +40,7 @@ import java.util.HashSet; import java.util.Iterator; import java.util.concurrent.CancellationException; import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.IntStream; import org.apache.geode.cache.Cache; import org.apache.geode.cache.CacheException; @@ -149,6 +159,46 @@ public class PartitionedRegionQueryDUnitTest extends JUnit4CacheTestCase { }); } + @Test + public void testFailureToCreateIndexOnRemoteNodeThrowsException() { + Host host = Host.getHost(0); + VM vm0 = host.getVM(0); + VM vm1 = host.getVM(-1); + + SerializableRunnableIF createPR = () -> { + Cache cache = getCache(); + PartitionAttributesFactory paf = new PartitionAttributesFactory(); + paf.setTotalNumBuckets(10); + cache.createRegionFactory(RegionShortcut.PARTITION).setPartitionAttributes(paf.create()) + .create("region"); + }; + vm0.invoke(createPR); + vm1.invoke(createPR); + + vm0.invoke(() -> { + Cache cache = getCache(); + Region region = cache.getRegion("region"); + IntStream.range(1, 10).forEach(i -> region.put(i, new NotDeserializableAsset())); + }); + + vm0.invoke(() -> { + Cache cache = getCache(); + try { + cache.getQueryService().createHashIndex("ContractDocumentIndex", "document", "/region"); + fail("Should have thrown an exception"); + } catch (Exception expected) { + } + }); + + vm1.invoke(() -> { + Cache cache = getCache(); + Region region = cache.getRegion("region"); + final Index index = cache.getQueryService().getIndex(region, "ContractDocumentIndex"); + assertEquals(null, index); + }); + + } + /** * Test of bug 43102. 1. Buckets are created on several nodes 2. A query is started 3. While the * query is executing, several buckets are moved. @@ -1091,7 +1141,33 @@ public class PartitionedRegionQueryDUnitTest extends JUnit4CacheTestCase { } - private class NestedKeywordObject implements Serializable { + public static class NotDeserializableAsset implements DataSerializable { + private int allowedPid; + + public NotDeserializableAsset() { + + } + + public NotDeserializableAsset(final int allowedPid) { + this.allowedPid = allowedPid; + } + + @Override + public void toData(final DataOutput out) throws IOException { + out.writeInt(allowedPid); + + } + + @Override + public void fromData(final DataInput in) throws IOException, ClassNotFoundException { + allowedPid = in.readInt(); + if (allowedPid != DUnitEnv.get().getPid()) { + throw new IOException("Cannot deserialize"); + } + } + } + + public class NestedKeywordObject implements Serializable { public Object date; public Object nonKeyword;