From: Tom Pantelis Date: Tue, 17 Jan 2017 09:23:02 +0000 (-0500) Subject: Handle UNMODIFIED type in DataTreeCandidateInputOutput X-Git-Tag: release/carbon~323 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=commitdiff_plain;h=875679ec8a3aea94478ff2a106e4f9cb4f5fc884;hp=8438f3659c2b70ecb66af27684781b34bcfa328f Handle UNMODIFIED type in DataTreeCandidateInputOutput 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 --- diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java index b765cabc7e..b8cf731b94 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/DataTreeCandidateInputOutput.java @@ -104,15 +104,25 @@ public final class DataTreeCandidateInputOutput { final DataTreeCandidateNode rootNode; switch (type) { + case APPEARED: + rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.APPEARED, readChildren(reader)); + break; case DELETE: rootNode = DeletedDataTreeCandidateNode.create(); break; + case DISAPPEARED: + rootNode = ModifiedDataTreeCandidateNode.create(ModificationType.DISAPPEARED, readChildren(reader)); + break; 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; + case UNMODIFIED: + rootNode = AbstractDataTreeCandidateNode.createUnmodified(); + break; default: throw new IllegalArgumentException("Unhandled node type " + type); } diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ModifiedDataTreeCandidateNode.java b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ModifiedDataTreeCandidateNode.java index c319286bf7..81f91aa900 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ModifiedDataTreeCandidateNode.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/main/java/org/opendaylight/controller/cluster/datastore/persisted/ModifiedDataTreeCandidateNode.java @@ -28,8 +28,8 @@ abstract class ModifiedDataTreeCandidateNode extends AbstractDataTreeCandidateNo this.children = Preconditions.checkNotNull(children); } - static DataTreeCandidateNode create(final Collection children) { - return new ModifiedDataTreeCandidateNode(ModificationType.SUBTREE_MODIFIED, children) { + static DataTreeCandidateNode create(final ModificationType type, final Collection children) { + return new ModifiedDataTreeCandidateNode(type, children) { @Override public PathArgument getIdentifier() { throw new UnsupportedOperationException("Root node does not have an identifier"); diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/CommitTransactionPayloadTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/CommitTransactionPayloadTest.java index 31dc624a11..315246d497 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/CommitTransactionPayloadTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/persisted/CommitTransactionPayloadTest.java @@ -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.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; @@ -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.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.tree.InMemoryDataTreeFactory; 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()); - - 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()); - assertEquals("child identifier", expected.getIdentifier(), actual.getIdentifier()); 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 identifier", expected.getIdentifier(), actual.getIdentifier()); assertChildrenEquals(expected.getChildNodes(), actual.getChildNodes()); break; + case UNMODIFIED: + 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()); } + + @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()); + } }