Handle UNMODIFIED type in DataTreeCandidateInputOutput 35/50535/1
authorTom Pantelis <tpanteli@brocade.com>
Tue, 17 Jan 2017 09:23:02 +0000 (04:23 -0500)
committerTom Pantelis <tpanteli@brocade.com>
Tue, 17 Jan 2017 09:33:17 +0000 (04:33 -0500)
We now replicate DataTreeCandidates with root node type UNMODIFIED
however the deserialization in DataTreeCandidateInputOutput throws
an ISE with "Unhandled node type 2". The writeDataTreeCandidate
method writes the UNMODIFIED type but readDataTreeCandidate needs
to handle that case as well.

In addition, writeDataTreeCandidate also handles APPEARED and
DISAPPEARED but readDataTreeCandidate does not so I made that
change as well.

Change-Id: I19932e545bbeb95fa10d5f57d43a5780af586285
Signed-off-by: Tom Pantelis <tpanteli@brocade.com>
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java
opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ModifiedDataTreeCandidateNode.java
opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/CommitTransactionPayloadTest.java

index b765cabc7e418bd58f930e84788d446978f16d19..b8cf731b9460be2d8444449c2eb57c910d16dfea 100644 (file)
@@ -104,15 +104,25 @@ public final class DataTreeCandidateInputOutput {
 
         final DataTreeCandidateNode rootNode;
         switch (type) {
 
         final DataTreeCandidateNode rootNode;
         switch (type) {
+            case APPEARED:
+                rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED, readChildren(reader));
+                break;
             case DELETE:
                 rootNode = DeletedDataTreeCandidateNode.create();
                 break;
             case DELETE:
                 rootNode = DeletedDataTreeCandidateNode.create();
                 break;
+            case DISAPPEARED:
+                rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED, readChildren(reader));
+                break;
             case SUBTREE_MODIFIED:
             case SUBTREE_MODIFIED:
-                rootNode = ModifiedDataTreeCandidateNode.create(readChildren(reader));
+                rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.SUBTREE_MODIFIED,
+                        readChildren(reader));
                 break;
             case WRITE:
                 rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
                 break;
                 break;
             case WRITE:
                 rootNode = DataTreeCandidateNodes.fromNormalizedNode(reader.readNormalizedNode());
                 break;
+            case UNMODIFIED:
+                rootNode = AbstractDataTreeCandidateNode.createUnmodified();
+                break;
             default:
                 throw new IllegalArgumentException("Unhandled node type " + type);
         }
             default:
                 throw new IllegalArgumentException("Unhandled node type " + type);
         }
index c319286bf7ca01da44a8c1528f91a4c5a7c6dd0b..81f91aa900f72f476c8d90a66e783fbd58bc2cb3 100644 (file)
@@ -28,8 +28,8 @@ abstract class ModifiedDataTreeCandidateNode extends AbstractDataTreeCandidateNo
         this.children = Preconditions.checkNotNull(children);
     }
 
         this.children = Preconditions.checkNotNull(children);
     }
 
-    static DataTreeCandidateNode create(final Collection<DataTreeCandidateNode> children) {
-        return new ModifiedDataTreeCandidateNode(ModificationType.SUBTREE_MODIFIED, children) {
+    static DataTreeCandidateNode create(final ModificationType type, final Collection<DataTreeCandidateNode> children) {
+        return new ModifiedDataTreeCandidateNode(type, children) {
             @Override
             public PathArgument getIdentifier() {
                 throw new UnsupportedOperationException("Root node does not have an identifier");
             @Override
             public PathArgument getIdentifier() {
                 throw new UnsupportedOperationException("Root node does not have an identifier");
index 31dc624a11c6998a48c1a9fd27720212d85c60e5..315246d497393ae35c3209b172db7de9e0478fef 100644 (file)
@@ -18,6 +18,7 @@ import org.apache.commons.lang3.SerializationUtils;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.AbstractTest;
 import org.junit.Before;
 import org.junit.Test;
 import org.opendaylight.controller.cluster.datastore.AbstractTest;
+import org.opendaylight.controller.md.cluster.datastore.model.SchemaContextHelper;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.controller.md.cluster.datastore.model.TestModel;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
@@ -28,9 +29,13 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeModification;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TipProducingDataTree;
+import org.opendaylight.yangtools.yang.data.api.schema.tree.TreeType;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.tree.InMemoryDataTreeFactory;
 
 public class CommitTransactionPayloadTest extends AbstractTest {
     static final QName LEAF_SET = QName.create(TestModel.TEST_QNAME, "leaf-set");
 
 public class CommitTransactionPayloadTest extends AbstractTest {
     static final QName LEAF_SET = QName.create(TestModel.TEST_QNAME, "leaf-set");
@@ -64,40 +69,25 @@ public class CommitTransactionPayloadTest extends AbstractTest {
 
     private static void assertCandidateEquals(final DataTreeCandidate expected, final DataTreeCandidate actual) {
         assertEquals("root path", expected.getRootPath(), actual.getRootPath());
 
     private static void assertCandidateEquals(final DataTreeCandidate expected, final DataTreeCandidate actual) {
         assertEquals("root path", expected.getRootPath(), actual.getRootPath());
-
-        final DataTreeCandidateNode expRoot = expected.getRootNode();
-        final DataTreeCandidateNode actRoot = expected.getRootNode();
-        assertEquals("root type", expRoot.getModificationType(), actRoot.getModificationType());
-
-        switch (actRoot.getModificationType()) {
-            case DELETE:
-            case WRITE:
-                assertEquals("root data", expRoot.getDataAfter(), actRoot.getDataAfter());
-                break;
-            case SUBTREE_MODIFIED:
-                assertChildrenEquals(expRoot.getChildNodes(), actRoot.getChildNodes());
-                break;
-            default:
-                fail("Unexpect root type " + actRoot.getModificationType());
-                break;
-        }
-
         assertCandidateNodeEquals(expected.getRootNode(), actual.getRootNode());
     }
 
     private static void assertCandidateNodeEquals(final DataTreeCandidateNode expected,
             final DataTreeCandidateNode actual) {
         assertEquals("child type", expected.getModificationType(), actual.getModificationType());
         assertCandidateNodeEquals(expected.getRootNode(), actual.getRootNode());
     }
 
     private static void assertCandidateNodeEquals(final DataTreeCandidateNode expected,
             final DataTreeCandidateNode actual) {
         assertEquals("child type", expected.getModificationType(), actual.getModificationType());
-        assertEquals("child identifier", expected.getIdentifier(), actual.getIdentifier());
 
         switch (actual.getModificationType()) {
             case DELETE:
             case WRITE:
 
         switch (actual.getModificationType()) {
             case DELETE:
             case WRITE:
+                assertEquals("child identifier", expected.getIdentifier(), actual.getIdentifier());
                 assertEquals("child data", expected.getDataAfter(), actual.getDataAfter());
                 break;
             case SUBTREE_MODIFIED:
                 assertEquals("child data", expected.getDataAfter(), actual.getDataAfter());
                 break;
             case SUBTREE_MODIFIED:
+                assertEquals("child identifier", expected.getIdentifier(), actual.getIdentifier());
                 assertChildrenEquals(expected.getChildNodes(), actual.getChildNodes());
                 break;
                 assertChildrenEquals(expected.getChildNodes(), actual.getChildNodes());
                 break;
+            case UNMODIFIED:
+                break;
             default:
                 fail("Unexpect root type " + actual.getModificationType());
                 break;
             default:
                 fail("Unexpect root type " + actual.getModificationType());
                 break;
@@ -190,4 +180,17 @@ public class CommitTransactionPayloadTest extends AbstractTest {
         CommitTransactionPayload payload = CommitTransactionPayload.create(nextTransactionId(), candidate);
         assertCandidateEquals(candidate, payload.getCandidate().getValue());
     }
         CommitTransactionPayload payload = CommitTransactionPayload.create(nextTransactionId(), candidate);
         assertCandidateEquals(candidate, payload.getCandidate().getValue());
     }
+
+    @Test
+    public void testUnmodifiedRootCandidate() throws Exception {
+        final TipProducingDataTree dataTree = InMemoryDataTreeFactory.getInstance().create(TreeType.CONFIGURATION);
+        dataTree.setSchemaContext(SchemaContextHelper.select(SchemaContextHelper.CARS_YANG));
+
+        DataTreeModification modification = dataTree.takeSnapshot().newModification();
+        modification.ready();
+        candidate = dataTree.prepare(modification);
+
+        CommitTransactionPayload payload = CommitTransactionPayload.create(nextTransactionId(), candidate);
+        assertCandidateEquals(candidate, payload.getCandidate().getValue());
+    }
 }
 }