From 7a0fb19fe86fbf7c7bd78f7e522884b6e477b067 Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Thu, 21 Jan 2016 10:59:50 -0500 Subject: [PATCH] Bug 5109: Handle stand alone leaf nodes in CDS streaming Modified AbstractNormalizedNodeDataOutput to output the leaf set QName that is now passed to leafSetEntryNode if no parent LeafSetNode QName is present. Modified NormalizedNodeInputStreamReader accordingly. I also found that OrderedLeafSetNode was not handled correctly. AbstractNormalizedNodeDataOutput#startOrderedLeafSet needs to set lastLeafSetQName. The NormalizedNodePruner assumed a leaf set entry node must have a parent and threw an exception if not, similarly with leaf node and anyXML node. But all 3 can be standalone so I modified NormalizedNodePruner to handle it. Change-Id: I02a71d9280dac0eb466ff401699a40d3d8826220 Signed-off-by: Tom Pantelis --- .../AbstractNormalizedNodeDataOutput.java | 12 ++- .../NormalizedNodeInputStreamReader.java | 9 +- .../transformer/NormalizedNodePruner.java | 58 ++++++----- .../transformer/NormalizedNodePrunerTest.java | 99 ++++++++++--------- .../DataTreeCandidatePayloadTest.java | 66 ++++++++++++- 5 files changed, 169 insertions(+), 75 deletions(-) diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java index 4a76119822..abe1f8c588 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/AbstractNormalizedNodeDataOutput.java @@ -30,6 +30,7 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut private NormalizedNodeWriter normalizedNodeWriter; private boolean headerWritten; + private QName lastLeafSetQName; AbstractNormalizedNodeDataOutput(final DataOutput output) { this.output = Preconditions.checkNotNull(output); @@ -159,6 +160,7 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut Preconditions.checkNotNull(name, "Node identifier should not be null"); LOG.debug("Starting a new leaf set"); + lastLeafSetQName = name.getNodeType(); startNode(name.getNodeType(), NodeTypes.LEAF_SET); } @@ -167,14 +169,22 @@ abstract class AbstractNormalizedNodeDataOutput implements NormalizedNodeDataOut Preconditions.checkNotNull(name, "Node identifier should not be null"); LOG.debug("Starting a new ordered leaf set"); + lastLeafSetQName = name.getNodeType(); startNode(name.getNodeType(), NodeTypes.ORDERED_LEAF_SET); } @Override - public void leafSetEntryNode(final Object value) throws IOException, IllegalArgumentException { + public void leafSetEntryNode(final QName name, final Object value) throws IOException, IllegalArgumentException { LOG.debug("Writing a new leaf set entry node"); output.writeByte(NodeTypes.LEAF_SET_ENTRY_NODE); + + // lastLeafSetQName is set if the parent LeafSetNode was previously written. Otherwise this is a + // stand alone LeafSetEntryNode so write out it's name here. + if(lastLeafSetQName == null) { + writeQName(name); + } + writeObject(value); } diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java index 7753242fca..7ed50ff731 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/stream/NormalizedNodeInputStreamReader.java @@ -134,8 +134,13 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput, withNodeIdentifier(augIdentifier)).build(); case NodeTypes.LEAF_SET_ENTRY_NODE : + QName name = lastLeafSetQName; + if(name == null) { + name = readQName(); + } + Object value = readObject(); - NodeWithValue leafIdentifier = new NodeWithValue(lastLeafSetQName, value); + NodeWithValue leafIdentifier = new NodeWithValue<>(name, value); LOG.debug("Reading leaf set entry node {}, value {}", leafIdentifier, value); @@ -222,7 +227,7 @@ public class NormalizedNodeInputStreamReader implements NormalizedNodeDataInput, Builders.leafSetBuilder().withNodeIdentifier(identifier)).build(); case NodeTypes.ORDERED_LEAF_SET: - LOG.debug("Read leaf set node"); + LOG.debug("Read ordered leaf set node {}", identifier); ListNodeBuilder> orderedLeafSetBuilder = Builders.orderedLeafSetBuilder().withNodeIdentifier(identifier); orderedLeafSetBuilder = addLeafSetChildren(identifier.getNodeType(), orderedLeafSetBuilder); diff --git a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePruner.java b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePruner.java index 88c4763233..27504f37f1 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePruner.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/main/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePruner.java @@ -10,18 +10,17 @@ package org.opendaylight.controller.cluster.datastore.node.utils.transformer; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Preconditions; - import java.io.IOException; import java.net.URI; import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Set; - import javax.xml.transform.dom.DOMSource; - import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeStreamWriter; import org.opendaylight.yangtools.yang.data.impl.schema.Builders; @@ -49,6 +48,7 @@ public class NormalizedNodePruner implements NormalizedNodeStreamWriter { this.validNamespaces = validNamespaces; } + @SuppressWarnings("unchecked") @Override public void leafNode(YangInstanceIdentifier.NodeIdentifier nodeIdentifier, Object o) throws IOException, IllegalArgumentException { @@ -57,13 +57,16 @@ public class NormalizedNodePruner implements NormalizedNodeStreamWriter { if(!isValidNamespace(nodeIdentifier)){ return; } + NormalizedNodeBuilderWrapper parent = stack.peek(); - Preconditions.checkState(parent != null, "leafNode has no parent"); - parent.builder() - .addChild(Builders.leafBuilder() - .withNodeIdentifier(nodeIdentifier) - .withValue(o) - .build()); + LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier(nodeIdentifier).withValue(o).build(); + if(parent != null) { + parent.builder().addChild(leafNode); + } else { + // If there's no parent node then this is a stand alone LeafNode. + this.normalizedNode = leafNode; + sealed = true; + } } @Override @@ -82,22 +85,25 @@ public class NormalizedNodePruner implements NormalizedNodeStreamWriter { addBuilder(Builders.orderedLeafSetBuilder().withNodeIdentifier(nodeIdentifier), nodeIdentifier); } + @SuppressWarnings({ "unchecked" }) @Override - public void leafSetEntryNode(Object o) throws IOException, IllegalArgumentException { - + public void leafSetEntryNode(QName name, Object o) throws IOException, IllegalArgumentException { checkNotSealed(); - NormalizedNodeBuilderWrapper parent = stack.peek(); - Preconditions.checkState(parent != null, "leafSetEntryNode has no parent"); - if(!isValidNamespace(parent.identifier())){ + if(!isValidNamespace(name)){ return; } - parent.builder() - .addChild(Builders.leafSetEntryBuilder() - .withValue(o) - .withNodeIdentifier(new YangInstanceIdentifier.NodeWithValue(parent.nodeType(), o)) - .build()); + NormalizedNodeBuilderWrapper parent = stack.peek(); + if(parent != null) { + parent.builder().addChild(Builders.leafSetEntryBuilder().withValue(o).withNodeIdentifier( + new YangInstanceIdentifier.NodeWithValue<>(parent.nodeType(), o)).build()); + } else { + // If there's no parent LeafSetNode then this is a stand alone LeafSetEntryNode. + this.normalizedNode = Builders.leafSetEntryBuilder().withValue(o).withNodeIdentifier( + new YangInstanceIdentifier.NodeWithValue<>(name, o)).build(); + sealed = true; + } } @Override @@ -169,17 +175,25 @@ public class NormalizedNodePruner implements NormalizedNodeStreamWriter { addBuilder(Builders.augmentationBuilder().withNodeIdentifier(augmentationIdentifier), augmentationIdentifier); } + @SuppressWarnings("unchecked") @Override public void anyxmlNode(YangInstanceIdentifier.NodeIdentifier nodeIdentifier, Object o) throws IOException, IllegalArgumentException { - checkNotSealed(); if(!isValidNamespace(nodeIdentifier)){ return; } + NormalizedNodeBuilderWrapper parent = stack.peek(); - Preconditions.checkState(parent != null, "anyxmlNode has no parent"); - parent.builder().addChild(Builders.anyXmlBuilder().withNodeIdentifier(nodeIdentifier).withValue((DOMSource) o).build()); + AnyXmlNode anyXmlNode = Builders.anyXmlBuilder().withNodeIdentifier(nodeIdentifier). + withValue((DOMSource) o).build(); + if(parent != null) { + parent.builder().addChild(anyXmlNode); + } else { + // If there's no parent node then this is a stand alone AnyXmlNode. + this.normalizedNode = anyXmlNode; + sealed = true; + } } @Override diff --git a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePrunerTest.java b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePrunerTest.java index 596540d4b3..2ee859466a 100644 --- a/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePrunerTest.java +++ b/opendaylight/md-sal/sal-clustering-commons/src/test/java/org/opendaylight/controller/cluster/datastore/node/utils/transformer/NormalizedNodePrunerTest.java @@ -25,7 +25,6 @@ import javax.xml.transform.dom.DOMSource; import org.junit.Assert; import org.junit.Before; import org.junit.Test; -import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeNavigator; @@ -33,6 +32,8 @@ import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeVi import org.opendaylight.controller.cluster.datastore.util.TestModel; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode; import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter; @@ -169,26 +170,26 @@ public class NormalizedNodePrunerTest { return count.get(); } - @Test(expected = IllegalStateException.class) + @Test public void testLeafNodeHasNoParent() throws IOException { - prunerFullSchema.leafNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), mock(Object.class)); + NormalizedNode input = Builders.leafBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.DESC_QNAME)).withValue("test").build(); + NormalizedNodeWriter.forStreamWriter(prunerFullSchema).write(input); + + NormalizedNode actual = prunerFullSchema.normalizedNode(); + assertEquals("normalizedNode", input, actual); } @Test public void testLeafNodeHasParent() throws IOException { - prunerFullSchema.stack().push(normalizedNodeBuilderWrapper); - Object o = mock(Object.class); - prunerFullSchema.leafNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), o); - - ArgumentCaptor captor = ArgumentCaptor.forClass(NormalizedNode.class); - - verify(normalizedNodeContainerBuilder).addChild(captor.capture()); - - NormalizedNode value = captor.getValue(); - assertEquals(normalizedNodeBuilderWrapper.identifier().getNodeType(), value.getNodeType()); - assertEquals(normalizedNodeBuilderWrapper.identifier(), value.getIdentifier()); - assertEquals(o, value.getValue()); - + LeafNode child = Builders.leafBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.DESC_QNAME)).withValue("test").build(); + NormalizedNode input = Builders.containerBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME)).withChild(child).build(); + NormalizedNodeWriter.forStreamWriter(prunerFullSchema).write(input); + + NormalizedNode actual = prunerFullSchema.normalizedNode(); + assertEquals("normalizedNode", input, actual); } @Test @@ -198,28 +199,26 @@ public class NormalizedNodePrunerTest { verify(normalizedNodeContainerBuilder, never()).addChild(any(NormalizedNode.class)); } - @Test(expected = IllegalStateException.class) + @Test public void testLeafSetEntryNodeHasNoParent() throws IOException { - prunerFullSchema.leafSetEntryNode(mock(Object.class)); + NormalizedNode input = Builders.leafSetEntryBuilder().withValue("test").withNodeIdentifier( + new YangInstanceIdentifier.NodeWithValue<>(TestModel.FAMILY_QNAME, "test")).build(); + NormalizedNodeWriter.forStreamWriter(prunerFullSchema).write(input); + + NormalizedNode actual = prunerFullSchema.normalizedNode(); + assertEquals("normalizedNode", input, actual); } @Test public void testLeafSetEntryNodeHasParent() throws IOException { - prunerFullSchema.stack().push(normalizedNodeBuilderWrapper); - Object o = mock(Object.class); - YangInstanceIdentifier.PathArgument nodeIdentifier - = new YangInstanceIdentifier.NodeWithValue(normalizedNodeBuilderWrapper.identifier().getNodeType(), o); - prunerFullSchema.leafSetEntryNode(o); - - ArgumentCaptor captor = ArgumentCaptor.forClass(NormalizedNode.class); - - verify(normalizedNodeContainerBuilder).addChild(captor.capture()); - - NormalizedNode value = captor.getValue(); - assertEquals(nodeIdentifier.getNodeType(), value.getNodeType()); - assertEquals(nodeIdentifier, value.getIdentifier()); - assertEquals(o, value.getValue()); - + LeafSetEntryNode child = Builders.leafSetEntryBuilder().withValue("test").withNodeIdentifier( + new YangInstanceIdentifier.NodeWithValue<>(TestModel.FAMILY_QNAME, "test")).build(); + NormalizedNode input = Builders.leafSetBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.FAMILY_QNAME)).withChild(child).build(); + NormalizedNodeWriter.forStreamWriter(prunerFullSchema).write(input); + + NormalizedNode actual = prunerFullSchema.normalizedNode(); + assertEquals("normalizedNode", input, actual); } @Test @@ -227,31 +226,33 @@ public class NormalizedNodePrunerTest { doReturn(new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME)).when(normalizedNodeBuilderWrapper).identifier(); prunerNoAugSchema.stack().push(normalizedNodeBuilderWrapper); - prunerNoAugSchema.leafSetEntryNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME)); + prunerNoAugSchema.leafSetEntryNode(TestModel.AUG_CONT_QNAME, ""); verify(normalizedNodeContainerBuilder, never()).addChild(any(NormalizedNode.class)); } - @Test(expected = IllegalStateException.class) + @Test public void testAnyXMLNodeHasNoParent() throws IOException { - prunerFullSchema.anyxmlNode(new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME), mock(Object.class)); + NormalizedNode input = Builders.anyXmlBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.CHILD_NAME_QNAME)). + withValue(mock(DOMSource.class)).build(); + NormalizedNodeWriter.forStreamWriter(prunerFullSchema).write(input); + + NormalizedNode actual = prunerFullSchema.normalizedNode(); + assertEquals("normalizedNode", input, actual); } @Test public void testAnyXMLNodeHasParent() throws IOException { - prunerFullSchema.stack().push(normalizedNodeBuilderWrapper); - YangInstanceIdentifier.NodeIdentifier nodeIdentifier = new YangInstanceIdentifier.NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME); - DOMSource o = mock(DOMSource.class); - prunerFullSchema.anyxmlNode(nodeIdentifier, o); - - ArgumentCaptor captor = ArgumentCaptor.forClass(NormalizedNode.class); - - verify(normalizedNodeContainerBuilder).addChild(captor.capture()); - - NormalizedNode value = captor.getValue(); - assertEquals(nodeIdentifier.getNodeType(), value.getNodeType()); - assertEquals(nodeIdentifier, value.getIdentifier()); - assertEquals(o, value.getValue()); + AnyXmlNode child = Builders.anyXmlBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.CHILD_NAME_QNAME)). + withValue(mock(DOMSource.class)).build(); + NormalizedNode input = Builders.containerBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.AUG_CONT_QNAME)).withChild(child).build(); + NormalizedNodeWriter.forStreamWriter(prunerFullSchema).write(input); + + NormalizedNode actual = prunerFullSchema.normalizedNode(); + assertEquals("normalizedNode", input, actual); } @Test diff --git a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataTreeCandidatePayloadTest.java b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataTreeCandidatePayloadTest.java index 781c3dba71..07ccce25ca 100644 --- a/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataTreeCandidatePayloadTest.java +++ b/opendaylight/md-sal/sal-distributed-datastore/src/test/java/org/opendaylight/controller/cluster/datastore/DataTreeCandidatePayloadTest.java @@ -16,17 +16,23 @@ import java.util.Collection; import org.apache.commons.lang3.SerializationUtils; import org.junit.Before; import org.junit.Test; +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.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument; +import org.opendaylight.yangtools.yang.data.api.schema.LeafNode; +import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode; 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.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.controller.md.cluster.datastore.model.TestModel; public class DataTreeCandidatePayloadTest { + static final QName LEAF_SET = QName.create(TestModel.TEST_QNAME, "leaf-set"); + private DataTreeCandidate candidate; private static DataTreeCandidateNode findNode(final Collection nodes, final PathArgument arg) { @@ -120,4 +126,62 @@ public class DataTreeCandidatePayloadTest { final DataTreeCandidatePayload payload = DataTreeCandidatePayload.create(candidate); assertCandidateEquals(candidate, SerializationUtils.clone(payload).getCandidate()); } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testLeafSetEntryNodeCandidate() throws Exception { + YangInstanceIdentifier.NodeWithValue entryPathArg = new YangInstanceIdentifier.NodeWithValue(LEAF_SET, "one"); + YangInstanceIdentifier leafSetEntryPath = YangInstanceIdentifier.builder(TestModel.TEST_PATH).node(LEAF_SET) + .node(entryPathArg).build(); + + NormalizedNode leafSetEntryNode = Builders.leafSetEntryBuilder(). + withNodeIdentifier(entryPathArg).withValue("one").build(); + + DataTreeCandidate candidate = DataTreeCandidates.fromNormalizedNode(leafSetEntryPath, leafSetEntryNode); + DataTreeCandidatePayload payload = DataTreeCandidatePayload.create(candidate); + assertCandidateEquals(candidate, payload.getCandidate()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testLeafSetNodeCandidate() throws Exception { + YangInstanceIdentifier.NodeWithValue entryPathArg = new YangInstanceIdentifier.NodeWithValue(LEAF_SET, "one"); + YangInstanceIdentifier leafSetPath = YangInstanceIdentifier.builder(TestModel.TEST_PATH).node(LEAF_SET).build(); + + LeafSetEntryNode leafSetEntryNode = Builders.leafSetEntryBuilder(). + withNodeIdentifier(entryPathArg).withValue("one").build(); + NormalizedNode leafSetNode = Builders.leafSetBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(LEAF_SET)).withChild(leafSetEntryNode).build(); + + DataTreeCandidate candidate = DataTreeCandidates.fromNormalizedNode(leafSetPath, leafSetNode); + DataTreeCandidatePayload payload = DataTreeCandidatePayload.create(candidate); + assertCandidateEquals(candidate, payload.getCandidate()); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testOrderedLeafSetNodeCandidate() throws Exception { + YangInstanceIdentifier.NodeWithValue entryPathArg = new YangInstanceIdentifier.NodeWithValue(LEAF_SET, "one"); + YangInstanceIdentifier leafSetPath = YangInstanceIdentifier.builder(TestModel.TEST_PATH).node(LEAF_SET).build(); + + LeafSetEntryNode leafSetEntryNode = Builders.leafSetEntryBuilder(). + withNodeIdentifier(entryPathArg).withValue("one").build(); + NormalizedNode leafSetNode = Builders.orderedLeafSetBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(LEAF_SET)).withChild(leafSetEntryNode).build(); + + DataTreeCandidate candidate = DataTreeCandidates.fromNormalizedNode(leafSetPath, leafSetNode); + DataTreeCandidatePayload payload = DataTreeCandidatePayload.create(candidate); + assertCandidateEquals(candidate, payload.getCandidate()); + } + + @Test + public void testLeafNodeCandidate() throws Exception { + YangInstanceIdentifier leafPath = YangInstanceIdentifier.builder(TestModel.TEST_PATH).node(TestModel.DESC_QNAME).build(); + LeafNode leafNode = Builders.leafBuilder().withNodeIdentifier( + new YangInstanceIdentifier.NodeIdentifier(TestModel.DESC_QNAME)).withValue("test").build(); + + DataTreeCandidate candidate = DataTreeCandidates.fromNormalizedNode(leafPath, leafNode); + DataTreeCandidatePayload payload = DataTreeCandidatePayload.create(candidate); + assertCandidateEquals(candidate, payload.getCandidate()); + } } -- 2.36.6