Fix ForeignShardModificationContext's submit method 61/53261/9
authorJakub Morvay <jmorvay@cisco.com>
Tue, 14 Mar 2017 09:50:11 +0000 (10:50 +0100)
committerRobert Varga <nite@hq.sk>
Fri, 17 Mar 2017 09:26:00 +0000 (09:26 +0000)
ForeingShardModificationContext can be reused by several transactions.
Unready it in its submit method.

Change-Id: I84a3e74176335e87c940109d6a43c9e5131a9f0c
Signed-off-by: Jakub Morvay <jmorvay@cisco.com>
dom/mdsal-dom-broker/src/test/java/org/opendaylight/mdsal/dom/broker/ShardedDOMDataTreeTest.java
dom/mdsal-dom-inmemory-datastore/src/test/java/org/opendaylight/mdsal/dom/store/inmemory/ForeignShardThreePhaseCommitCohortTest.java
dom/mdsal-dom-spi/src/main/java/org/opendaylight/mdsal/dom/spi/shard/ForeignShardModificationContext.java

index f7038d2fdbd9064a931acb22cfea65f61ad478ec..4e4bab2810181f37922db65d597acf9d722c2361 100644 (file)
@@ -213,6 +213,51 @@ public class ShardedDOMDataTreeTest {
         verifyNoMoreInteractions(mockedDataTreeListener);
     }
 
+    @Test
+    // TODO extract common logic from testSingleSubshardWrite and
+    // testSingleShardWrite tests
+    public void testSingleSubshardWrite() throws Exception {
+        final DOMDataTreeListener mockedDataTreeListener = mock(DOMDataTreeListener.class);
+        doNothing().when(mockedDataTreeListener).onDataTreeChanged(anyCollection(), anyMap());
+
+        InMemoryDOMDataTreeShard testShard = InMemoryDOMDataTreeShard.create(TEST_ID, executor, 1);
+        testShard.onGlobalContextUpdated(schemaContext);
+
+        final DOMDataTreeProducer regProducer = dataTreeService.createProducer(Collections.singleton(TEST_ID));
+        dataTreeService.registerDataTreeShard(TEST_ID, testShard, regProducer);
+        regProducer.close();
+
+        dataTreeService.registerListener(mockedDataTreeListener, Collections.singletonList(TEST_ID),
+                true, Collections.emptyList());
+
+        final DOMDataTreeProducer producer = dataTreeService.createProducer(Collections.singletonList(ROOT_ID));
+        DOMDataTreeCursorAwareTransaction tx = producer.createTransaction(false);
+        DOMDataTreeWriteCursor cursor = tx.createCursor(ROOT_ID);
+        assertNotNull(cursor);
+
+        cursor.write(TEST_ID.getRootIdentifier().getLastPathArgument(), crossShardContainer);
+
+        cursor.close();
+        tx.submit().checkedGet();
+
+        tx = producer.createTransaction(false);
+        cursor = tx.createCursor(TEST_ID);
+        assertNotNull(cursor);
+
+        cursor.delete(TestModel.INNER_CONTAINER_PATH.getLastPathArgument());
+        cursor.close();
+        tx.submit().checkedGet();
+
+        verify(mockedDataTreeListener, timeout(5000).times(3)).onDataTreeChanged(captorForChanges.capture(),
+                captorForSubtrees.capture());
+
+        final List<Collection<DataTreeCandidate>> capturedValue = captorForChanges.getAllValues();
+        final ContainerNode capturedChange =
+                (ContainerNode) capturedValue.get(1).iterator().next().getRootNode().getDataAfter().get();
+        final ContainerNode innerContainerVerify = crossShardContainer;
+        assertEquals(innerContainerVerify, capturedChange);
+    }
+
     @Test
     public void testMultipleWritesIntoSingleMapEntry() throws Exception {
 
index fdd9293e13d6211b68f33e6f6555ec582df636aa..5f2c183c02e8dc602af42fb3ad2203f288f759f7 100644 (file)
@@ -36,8 +36,10 @@ public class ForeignShardThreePhaseCommitCohortTest {
         doReturn(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).when(DOM_DATA_TREE_SHARD_PRODUCER).createTransaction();
         doReturn(DOM_DATA_TREE_WRITE_CURSOR)
                 .when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).createCursor(DOM_DATA_TREE_IDENTIFIER);
-        foreignShardModificationContext.getCursor();
+        doNothing().when(DOM_DATA_TREE_SHARD_WRITE_TRANSACTION).ready();
 
+        foreignShardModificationContext.getCursor();
+        foreignShardModificationContext.ready();
         final ForeignShardThreePhaseCommitCohort foreignShardThreePhaseCommitCohort =
                 new ForeignShardThreePhaseCommitCohort(DOM_DATA_TREE_IDENTIFIER, foreignShardModificationContext);
 
index 4ecedf14e32b5452c6e6923191c65eb557320b2a..160c6e76e4ae78421cd770d505735a67fbea93c3 100644 (file)
@@ -29,7 +29,7 @@ public final class ForeignShardModificationContext implements Identifiable<DOMDa
     private DOMDataTreeShardWriteTransaction tx;
     private DOMDataTreeWriteCursor cursor;
 
-    private volatile boolean notReady = true;
+    private volatile boolean ready = false;
 
     public ForeignShardModificationContext(final DOMDataTreeIdentifier identifier,
                                            final DOMDataTreeShardProducer producer) {
@@ -38,7 +38,7 @@ public final class ForeignShardModificationContext implements Identifiable<DOMDa
     }
 
     public DOMDataTreeWriteCursor getCursor() {
-        Preconditions.checkState(notReady, "Context %s has been readied", this);
+        Preconditions.checkState(!ready, "Context %s has been readied", this);
 
         if (cursor == null) {
             if (tx == null) {
@@ -54,13 +54,13 @@ public final class ForeignShardModificationContext implements Identifiable<DOMDa
     }
 
     public void ready() {
-        if (!notReady) {
+        if (ready) {
             // Idempotent, but emit a debug
             LOG.debug("Duplicate ready() of context {}", this);
             return;
         }
 
-        notReady = false;
+        ready = true;
         if (cursor != null) {
             cursor.close();
             cursor = null;
@@ -86,7 +86,9 @@ public final class ForeignShardModificationContext implements Identifiable<DOMDa
     }
 
     public ListenableFuture<Void> submit() {
+        Preconditions.checkState(ready, "Modification context %s has to be ready before submit", this);
         final ListenableFuture<Void> commit = tx.commit();
+        ready = false;
         tx = null;
         return commit;
     }