From e4a1f8d852e5897ad3b23c04741a0f5e5470cb3f Mon Sep 17 00:00:00 2001 From: Tomas Cere Date: Wed, 17 Aug 2016 13:24:54 +0200 Subject: [PATCH] Fix NPE when creating a producer after shard was unregistered Change-Id: I9f6728f4c885cc18d8adf8dc9d1c14e8c99977ef Signed-off-by: Tomas Cere (cherry picked from commit f065e5c7ac0ff2bf0227b06c1ebcdf29d30414e0) --- .../mdsal/dom/broker/ShardedDOMDataTree.java | 2 +- .../dom/broker/ShardedDOMDataTreeTest.java | 33 +++++++++++++++++++ .../inmemory/InMemoryDOMDataTreeShard.java | 1 + 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTree.java b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTree.java index eb4c1df119..2ef26a9dc3 100644 --- a/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTree.java +++ b/dom/mdsal-dom-broker/src/main/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTree.java @@ -142,7 +142,7 @@ public final class ShardedDOMDataTree implements DOMDataTreeService, DOMDataTree Preconditions.checkArgument(producer == null, "Subtree %s is attached to producer %s", subtree, producer); final DOMDataTreePrefixTableEntry> possibleShardReg = shards.lookup(subtree); - if (possibleShardReg != null) { + if (possibleShardReg != null && possibleShardReg.getValue() != null) { shardMap.put(subtree, possibleShardReg.getValue().getInstance()); } } diff --git a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTreeTest.java b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTreeTest.java index 1ffa904ef4..528234f56e 100644 --- a/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTreeTest.java +++ b/dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTreeTest.java @@ -24,6 +24,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; +import junit.framework.Assert; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; @@ -109,6 +110,38 @@ public class ShardedDOMDataTreeTest { dataTreeService.createProducer(Collections.singletonList(TEST_ID)); } + @Test + public void testShardRegistrationClose() throws Exception { + rootShardReg.close(); + + final InMemoryDOMDataTreeShard newRootShard = InMemoryDOMDataTreeShard.create(ROOT_ID, executor, 1, 1); + newRootShard.onGlobalContextUpdated(schemaContext); + final DOMDataTreeProducer shardRegProducer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID)); + + ListenerRegistration newRootShardReg = + dataTreeService.registerDataTreeShard(ROOT_ID, rootShard, shardRegProducer); + shardRegProducer.close(); + + final InMemoryDOMDataTreeShard innerShard = InMemoryDOMDataTreeShard.create(INNER_CONTAINER_ID, executor, 1, 1); + innerShard.onGlobalContextUpdated(schemaContext); + final DOMDataTreeProducer shardRegProducer2 = dataTreeService.createProducer(Collections.singletonList(INNER_CONTAINER_ID)); + ListenerRegistration innerShardReg = dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, shardRegProducer2); + + innerShardReg.close(); + // try to register the shard again + innerShardReg = dataTreeService.registerDataTreeShard(INNER_CONTAINER_ID, innerShard, shardRegProducer2); + final DOMDataTreeCursorAwareTransaction tx = shardRegProducer2.createTransaction(false); + final DOMDataTreeWriteCursor cursor = tx.createCursor(INNER_CONTAINER_ID); + assertNotNull(cursor); + + cursor.close(); + tx.cancel(); + shardRegProducer2.close(); + + innerShardReg.close(); + newRootShardReg.close(); + } + @Test public void testSingleShardWrite() throws Exception { final DOMDataTreeListener mockedDataTreeListener = Mockito.mock(DOMDataTreeListener.class); diff --git a/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShard.java b/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShard.java index b45d9abab2..21ead91ae9 100644 --- a/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShard.java +++ b/dom/mdsal-dom-inmemory-datastore/src/main/java/org/opendaylight/mdsal/dom/store/inmemory/InMemoryDOMDataTreeShard.java @@ -100,6 +100,7 @@ public class InMemoryDOMDataTreeShard implements ReadableWriteableDOMDataTreeSha @Override public void onChildDetached(final DOMDataTreeIdentifier prefix, final DOMDataTreeShard child) { childShards.remove(prefix); + childShardsTable.remove(prefix); } @Override -- 2.36.6