--- /dev/null
+/*
+ * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.datastore.node.utils;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertSame;
+
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.util.TestModel;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.Revision;
+
+public class QNameFactoryTest {
+
+ @Test
+ @Deprecated
+ public void testBasicString() {
+ QName expected = TestModel.AUG_NAME_QNAME;
+ QName created = QNameFactory.create(expected.toString());
+ assertNotSame(expected, created);
+ assertEquals(expected, created);
+
+ QName cached = QNameFactory.create(expected.toString());
+ assertSame(created, cached);
+ }
+
+ @Test
+ public void testBasic() {
+ QName expected = TestModel.AUG_NAME_QNAME;
+ QName created = lookup(expected);
+ assertNotSame(expected, created);
+ assertEquals(expected, created);
+
+ QName cached = lookup(expected);
+ assertSame(created, cached);
+ }
+
+ private static QName lookup(final QName qname) {
+ return QNameFactory.create(qname.getLocalName(), qname.getNamespace().toString(),
+ qname.getRevision().map(Revision::toString).orElse(null));
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.datastore.node.utils.stream;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+
+public class LithiumWriteObjectMappingTest {
+ @Test
+ public void testStringType() {
+ assertEquals(LithiumValue.STRING_TYPE, AbstractLithiumDataOutput.getSerializableType("foobar"));
+ final String largeString = largeString(LithiumValue.STRING_BYTES_LENGTH_THRESHOLD);
+ assertEquals(LithiumValue.STRING_BYTES_TYPE, AbstractLithiumDataOutput.getSerializableType(largeString));
+ }
+
+ private static String largeString(final int minSize) {
+ final int pow = (int) (Math.log(minSize * 2) / Math.log(2));
+ StringBuilder sb = new StringBuilder("X");
+ for (int i = 0; i < pow; i++) {
+ sb.append(sb);
+ }
+ return sb.toString();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.datastore.node.utils.stream;
+
+import static org.junit.Assert.assertEquals;
+
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.ByteStreams;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.transform.OutputKeys;
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.dom.DOMSource;
+import javax.xml.transform.stream.StreamResult;
+import org.apache.commons.lang.SerializationUtils;
+import org.junit.Assert;
+import org.junit.Test;
+import org.opendaylight.controller.cluster.datastore.util.TestModel;
+import org.opendaylight.yangtools.yang.common.Empty;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
+import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+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.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.model.api.SchemaPath;
+import org.w3c.dom.Node;
+import org.xml.sax.InputSource;
+
+public class NormalizedNodeStreamReaderWriterTest {
+
+ @Test
+ public void testNormalizedNodeStreaming() throws IOException {
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(ByteStreams.newDataOutput(bos));
+
+ NormalizedNode<?, ?> testContainer = createTestContainer();
+ nnout.writeNormalizedNode(testContainer);
+
+ QName toaster = QName.create("http://netconfcentral.org/ns/toaster","2009-11-20","toaster");
+ QName darknessFactor = QName.create("http://netconfcentral.org/ns/toaster","2009-11-20","darknessFactor");
+ QName description = QName.create("http://netconfcentral.org/ns/toaster","2009-11-20","description");
+ ContainerNode toasterNode = Builders.containerBuilder().withNodeIdentifier(new NodeIdentifier(toaster))
+ .withChild(ImmutableNodes.leafNode(darknessFactor, "1000"))
+ .withChild(ImmutableNodes.leafNode(description, largeString(20))).build();
+
+ ContainerNode toasterContainer = Builders.containerBuilder()
+ .withNodeIdentifier(new NodeIdentifier(SchemaContext.NAME)).withChild(toasterNode).build();
+ nnout.writeNormalizedNode(toasterContainer);
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(1049619, bytes.length);
+
+ NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+
+ NormalizedNode<?, ?> node = nnin.readNormalizedNode();
+ Assert.assertEquals(testContainer, node);
+
+ node = nnin.readNormalizedNode();
+ Assert.assertEquals(toasterContainer, node);
+ }
+
+ private static NormalizedNode<?, ?> createTestContainer() {
+ byte[] bytes1 = {1, 2, 3};
+ LeafSetEntryNode<Object> entry1 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new NodeWithValue<>(TestModel.BINARY_LEAF_LIST_QNAME, bytes1)).withValue(bytes1).build();
+
+ byte[] bytes2 = {};
+ LeafSetEntryNode<Object> entry2 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new NodeWithValue<>(TestModel.BINARY_LEAF_LIST_QNAME, bytes2)).withValue(bytes2).build();
+
+ return TestModel.createBaseTestContainerBuilder()
+ .withChild(ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(
+ new NodeIdentifier(TestModel.BINARY_LEAF_LIST_QNAME))
+ .withChild(entry1).withChild(entry2).build())
+ .withChild(ImmutableNodes.leafNode(TestModel.SOME_BINARY_DATA_QNAME, new byte[]{1, 2, 3, 4}))
+ .withChild(ImmutableNodes.leafNode(TestModel.EMPTY_QNAME, Empty.getInstance()))
+ .withChild(Builders.orderedMapBuilder()
+ .withNodeIdentifier(new NodeIdentifier(TestModel.ORDERED_LIST_QNAME))
+ .withChild(ImmutableNodes.mapEntry(TestModel.ORDERED_LIST_ENTRY_QNAME,
+ TestModel.ID_QNAME, 11)).build()).build();
+ }
+
+ @Test
+ public void testYangInstanceIdentifierStreaming() throws IOException {
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder(TestModel.TEST_PATH)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(
+ TestModel.INNER_LIST_QNAME, TestModel.ID_QNAME, 10).build();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(ByteStreams.newDataOutput(bos));
+
+ nnout.writeYangInstanceIdentifier(path);
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(139, bytes.length);
+
+ NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+
+ YangInstanceIdentifier newPath = nnin.readYangInstanceIdentifier();
+ Assert.assertEquals(path, newPath);
+ }
+
+ @Test
+ public void testNormalizedNodeAndYangInstanceIdentifierStreaming() throws IOException {
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ NormalizedNodeDataOutput writer = NormalizedNodeInputOutput.newDataOutput(
+ ByteStreams.newDataOutput(bos));
+
+ NormalizedNode<?, ?> testContainer = TestModel.createBaseTestContainerBuilder().build();
+ writer.writeNormalizedNode(testContainer);
+
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder(TestModel.TEST_PATH)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(
+ TestModel.INNER_LIST_QNAME, TestModel.ID_QNAME, 10).build();
+
+ writer.writeYangInstanceIdentifier(path);
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(826, bytes.length);
+
+ NormalizedNodeDataInput reader = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+
+ NormalizedNode<?,?> node = reader.readNormalizedNode();
+ Assert.assertEquals(testContainer, node);
+
+ YangInstanceIdentifier newPath = reader.readYangInstanceIdentifier();
+ Assert.assertEquals(path, newPath);
+
+ writer.close();
+ }
+
+ @Test(expected = InvalidNormalizedNodeStreamException.class, timeout = 10000)
+ public void testInvalidNormalizedNodeStream() throws IOException {
+ byte[] invalidBytes = {1, 2, 3};
+ NormalizedNodeDataInput reader = NormalizedNodeInputOutput.newDataInput(
+ ByteStreams.newDataInput(invalidBytes));
+
+ reader.readNormalizedNode();
+ }
+
+ @Test(expected = InvalidNormalizedNodeStreamException.class, timeout = 10000)
+ public void testInvalidYangInstanceIdentifierStream() throws IOException {
+ byte[] invalidBytes = {1,2,3};
+ NormalizedNodeDataInput reader = NormalizedNodeInputOutput.newDataInput(
+ ByteStreams.newDataInput(invalidBytes));
+
+ reader.readYangInstanceIdentifier();
+ }
+
+ @Test
+ public void testWithSerializable() {
+ NormalizedNode<?, ?> input = TestModel.createTestContainer();
+ SampleNormalizedNodeSerializable serializable = new SampleNormalizedNodeSerializable(input);
+ SampleNormalizedNodeSerializable clone =
+ (SampleNormalizedNodeSerializable)SerializationUtils.clone(serializable);
+
+ Assert.assertEquals(input, clone.getInput());
+ }
+
+ @Test
+ public void testAnyXmlStreaming() throws Exception {
+ String xml = "<foo xmlns=\"http://www.w3.org/TR/html4/\" x=\"123\"><bar>one</bar><bar>two</bar></foo>";
+ final DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
+ factory.setNamespaceAware(true);
+
+ Node xmlNode = factory.newDocumentBuilder().parse(
+ new InputSource(new StringReader(xml))).getDocumentElement();
+
+ assertEquals("http://www.w3.org/TR/html4/", xmlNode.getNamespaceURI());
+
+ NormalizedNode<?, ?> anyXmlContainer = ImmutableContainerNodeBuilder.create().withNodeIdentifier(
+ new YangInstanceIdentifier.NodeIdentifier(TestModel.TEST_QNAME)).withChild(
+ Builders.anyXmlBuilder().withNodeIdentifier(new NodeIdentifier(TestModel.ANY_XML_QNAME))
+ .withValue(new DOMSource(xmlNode)).build()).build();
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(ByteStreams.newDataOutput(bos));
+
+ nnout.writeNormalizedNode(anyXmlContainer);
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(229, bytes.length);
+
+ NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+
+ ContainerNode deserialized = (ContainerNode)nnin.readNormalizedNode();
+
+ Optional<DataContainerChild<? extends PathArgument, ?>> child =
+ deserialized.getChild(new NodeIdentifier(TestModel.ANY_XML_QNAME));
+ assertEquals("AnyXml child present", true, child.isPresent());
+
+ StreamResult xmlOutput = new StreamResult(new StringWriter());
+ Transformer transformer = TransformerFactory.newInstance().newTransformer();
+ transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
+ transformer.transform(((DOMSourceAnyxmlNode)child.get()).getValue(), xmlOutput);
+
+ assertEquals("XML", xml, xmlOutput.getWriter().toString());
+ assertEquals("http://www.w3.org/TR/html4/",
+ ((DOMSourceAnyxmlNode)child.get()).getValue().getNode().getNamespaceURI());
+ }
+
+ @Test
+ public void testSchemaPathSerialization() throws IOException {
+ final SchemaPath expected = SchemaPath.create(true, TestModel.ANY_XML_QNAME);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ try (NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(ByteStreams.newDataOutput(bos))) {
+ nnout.writeSchemaPath(expected);
+ }
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(99, bytes.length);
+
+ NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+ assertEquals(expected, nnin.readSchemaPath());
+ }
+
+ @Test
+ public void testWritePathArgument() throws IOException {
+ final NodeIdentifier expected = new NodeIdentifier(TestModel.BOOLEAN_LEAF_QNAME);
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try (NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(ByteStreams.newDataOutput(bos))) {
+ nnout.writePathArgument(expected);
+ }
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(103, bytes.length);
+
+ NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+ assertEquals(expected, nnin.readPathArgument());
+ }
+
+ /*
+ * This tests the encoding of a MapNode with a lot of entries, each of them having the key leaf (a string)
+ * and an integer.
+ */
+ @Test
+ public void testHugeEntries() throws IOException {
+ final CollectionNodeBuilder<MapEntryNode, MapNode> mapBuilder = Builders.mapBuilder()
+ .withNodeIdentifier(new NodeIdentifier(TestModel.TEST_QNAME));
+ final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entryBuilder =
+ Builders.mapEntryBuilder().withChild(ImmutableNodes.leafNode(TestModel.DESC_QNAME, (byte) 42));
+
+ for (int i = 0; i < 100_000; ++i) {
+ final String key = "xyzzy" + i;
+ mapBuilder.addChild(entryBuilder
+ .withNodeIdentifier(NodeIdentifierWithPredicates.of(TestModel.TEST_QNAME,
+ TestModel.CHILD_NAME_QNAME, key))
+ .withChild(ImmutableNodes.leafNode(TestModel.CHILD_NAME_QNAME, key))
+ .build());
+ }
+
+ final MapNode expected = mapBuilder.build();
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try (NormalizedNodeDataOutput nnout = NormalizedNodeInputOutput.newDataOutput(ByteStreams.newDataOutput(bos))) {
+ nnout.writeNormalizedNode(expected);
+ }
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(2_289_103, bytes.length);
+
+ NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+ assertEquals(expected, nnin.readNormalizedNode());
+ }
+
+ @Test
+ public void testAugmentationIdentifier() throws IOException {
+ final List<QName> qnames = new ArrayList<>();
+ for (int i = 0; i < 257; ++i) {
+ qnames.add(QName.create(TestModel.TEST_QNAME, "a" + i));
+ }
+
+ for (int i = 0; i < qnames.size(); ++i) {
+ final AugmentationIdentifier expected = AugmentationIdentifier.create(
+ ImmutableSet.copyOf(qnames.subList(0, i)));
+
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+
+ try (NormalizedNodeDataOutput nnout =
+ NormalizedNodeInputOutput.newDataOutput(ByteStreams.newDataOutput(bos),
+ NormalizedNodeStreamVersion.SODIUM_SR1)) {
+ nnout.writePathArgument(expected);
+ }
+
+ final byte[] bytes = bos.toByteArray();
+
+ NormalizedNodeDataInput nnin = NormalizedNodeInputOutput.newDataInput(ByteStreams.newDataInput(bytes));
+ PathArgument arg = nnin.readPathArgument();
+ assertEquals(expected, arg);
+ }
+ }
+
+ private static String largeString(final int pow) {
+ StringBuilder sb = new StringBuilder("X");
+ for (int i = 0; i < pow; i++) {
+ sb.append(sb);
+ }
+ return sb.toString();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.node.utils.stream;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.io.Serializable;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+
+public class SampleNormalizedNodeSerializable implements Serializable {
+ private static final long serialVersionUID = 1L;
+
+ private NormalizedNode<?, ?> input;
+
+ public SampleNormalizedNodeSerializable(final NormalizedNode<?, ?> input) {
+ this.input = input;
+ }
+
+ public NormalizedNode<?, ?> getInput() {
+ return input;
+ }
+
+ private void readObject(final ObjectInputStream stream) throws IOException {
+ this.input = NormalizedNodeInputOutput.newDataInput(stream).readNormalizedNode();
+ }
+
+ private void writeObject(final ObjectOutputStream stream) throws IOException {
+ NormalizedNodeInputOutput.newDataOutput(stream).writeNormalizedNode(input);
+ }
+
+}
--- /dev/null
+/*
+ * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.opendaylight.controller.cluster.datastore.node.utils.stream;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import com.google.common.collect.ImmutableSet;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.DataInputStream;
+import java.io.DataOutput;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.Set;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Collectors;
+import javax.xml.transform.dom.DOMSource;
+import org.custommonkey.xmlunit.Diff;
+import org.custommonkey.xmlunit.XMLUnit;
+import org.junit.Test;
+import org.opendaylight.yangtools.util.xml.UntrustedXML;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode;
+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.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
+import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
+import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
+import org.w3c.dom.Document;
+
+public class SerializationUtilsTest {
+
+ private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
+
+ @Test
+ public void testSerializeDeserializeNodes() throws IOException {
+ final NormalizedNode<?, ?> normalizedNode = createNormalizedNode();
+ final byte[] bytes = serializeNormalizedNode(normalizedNode);
+ assertEquals(10564, bytes.length);
+ assertEquals(normalizedNode, deserializeNormalizedNode(bytes));
+ }
+
+ @Test
+ public void testSerializeDeserializeAnyXmlNode() throws Exception {
+ final ByteArrayInputStream is =
+ new ByteArrayInputStream("<xml><data/></xml>".getBytes(Charset.defaultCharset()));
+ final Document parse = UntrustedXML.newDocumentBuilder().parse(is);
+ final DOMSourceAnyxmlNode anyXmlNode = Builders.anyXmlBuilder()
+ .withNodeIdentifier(id("anyXmlNode"))
+ .withValue(new DOMSource(parse))
+ .build();
+ final byte[] bytes = serializeNormalizedNode(anyXmlNode);
+ assertEquals(113, bytes.length);
+ final NormalizedNode<?, ?> deserialized = deserializeNormalizedNode(bytes);
+ final DOMSource value = (DOMSource) deserialized.getValue();
+ final Diff diff = XMLUnit.compareXML((Document) anyXmlNode.getValue().getNode(),
+ value.getNode().getOwnerDocument());
+ assertTrue(diff.toString(), diff.similar());
+ }
+
+ @Test
+ public void testSerializeDeserializePath() throws IOException {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final DataOutput out = new DataOutputStream(bos);
+ final YangInstanceIdentifier path = YangInstanceIdentifier.builder()
+ .node(id("container1"))
+ .node(autmentationId("list1", "list2"))
+ .node(listId("list1", "keyName1", "keyValue1"))
+ .node(leafSetId("leafSer1", "leafSetValue1"))
+ .build();
+ SerializationUtils.writePath(out, path);
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(119, bytes.length);
+
+ final YangInstanceIdentifier deserialized =
+ SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes)));
+ assertEquals(path, deserialized);
+ }
+
+ @Test
+ public void testSerializeDeserializePathAndNode() throws IOException {
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final DataOutput out = new DataOutputStream(bos);
+ final NormalizedNode<?, ?> node = createNormalizedNode();
+ final YangInstanceIdentifier path = YangInstanceIdentifier.create(id("container1"));
+ SerializationUtils.writeNodeAndPath(out, path, node);
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(10566, bytes.length);
+
+ final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
+ final AtomicBoolean applierCalled = new AtomicBoolean(false);
+ SerializationUtils.readNodeAndPath(in, applierCalled, (instance, deserializedPath, deserializedNode) -> {
+ assertEquals(path, deserializedPath);
+ assertEquals(node, deserializedNode);
+ applierCalled.set(true);
+ });
+ assertTrue(applierCalled.get());
+ }
+
+ @Test
+ public void testSerializeDeserializeAugmentNoref() throws IOException {
+ final YangInstanceIdentifier expected = YangInstanceIdentifier.create(
+ AugmentationIdentifier.create(ImmutableSet.of(
+ QName.create("foo", "leaf1"),
+ QName.create("bar", "leaf2"))));
+
+ final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ final DataOutput out = new DataOutputStream(bos);
+ SerializationUtils.writePath(out, expected);
+
+ final byte[] bytes = bos.toByteArray();
+ assertEquals(37, bytes.length);
+
+ final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
+ final YangInstanceIdentifier read = SerializationUtils.readPath(in);
+ assertEquals(expected, read);
+ }
+
+ private static NormalizedNode<?, ?> deserializeNormalizedNode(final byte[] bytes) throws IOException {
+ return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes))).get();
+ }
+
+ private static byte[] serializeNormalizedNode(final NormalizedNode<?, ?> node) throws IOException {
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ SerializationUtils.writeNormalizedNode(new DataOutputStream(bos), node);
+ return bos.toByteArray();
+ }
+
+ private static NormalizedNode<?, ?> createNormalizedNode() {
+ final LeafSetNode<Object> leafSetNode = Builders.leafSetBuilder()
+ .withNodeIdentifier(id("leafSetNode"))
+ .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
+ .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
+ .build();
+ final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
+ .withNodeIdentifier(id("orderedLeafSetNode"))
+ .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
+ .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
+ .build();
+ final LeafNode<Boolean> booleanLeaf = createLeaf("booleanLeaf", true);
+ final LeafNode<Byte> byteLeaf = createLeaf("byteLeaf", (byte) 0);
+ final LeafNode<Short> shortLeaf = createLeaf("shortLeaf", (short) 55);
+ final LeafNode<Integer> intLeaf = createLeaf("intLeaf", 11);
+ final LeafNode<Long> longLeaf = createLeaf("longLeaf", 151515L);
+ final LeafNode<String> stringLeaf = createLeaf("stringLeaf", "stringValue");
+ final LeafNode<String> longStringLeaf = createLeaf("longStringLeaf", getLongString());
+ final LeafNode<QName> qNameLeaf = createLeaf("stringLeaf", QName.create("base", "qName"));
+ final LeafNode<YangInstanceIdentifier> idLeaf = createLeaf("stringLeaf", YangInstanceIdentifier.empty());
+ final MapEntryNode entry1 = Builders.mapEntryBuilder()
+ .withNodeIdentifier(listId("mapNode", "key", "key1"))
+ .withChild(stringLeaf)
+ .build();
+ final MapEntryNode entry2 = Builders.mapEntryBuilder()
+ .withNodeIdentifier(listId("mapNode", "key", "key2"))
+ .withChild(stringLeaf)
+ .build();
+ final MapNode mapNode = Builders.mapBuilder()
+ .withNodeIdentifier(id("mapNode"))
+ .withChild(entry1)
+ .withChild(entry2)
+ .build();
+ final OrderedMapNode orderedMapNode = Builders.orderedMapBuilder()
+ .withNodeIdentifier(id("orderedMapNode"))
+ .withChild(entry2)
+ .withChild(entry1)
+ .build();
+ final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
+ .withNodeIdentifier(id("unkeyedList"))
+ .withChild(stringLeaf)
+ .build();
+ final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
+ .withNodeIdentifier(id("unkeyedList"))
+ .withChild(stringLeaf)
+ .build();
+ final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
+ .withNodeIdentifier(id("unkeyedList"))
+ .withChild(unkeyedListEntry1)
+ .withChild(unkeyedListEntry2)
+ .build();
+ final ImmutableSet<QName> childNames =
+ ImmutableSet.of(QName.create(CONTAINER_Q_NAME, "aug1"), QName.create(CONTAINER_Q_NAME, "aug1"));
+ final AugmentationNode augmentationNode = Builders.augmentationBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.AugmentationIdentifier(childNames))
+ .withChild(createLeaf("aug1", "aug1Value"))
+ .withChild(createLeaf("aug2", "aug2Value"))
+ .build();
+ final ChoiceNode choiceNode = Builders.choiceBuilder()
+ .withNodeIdentifier(id("choiceNode"))
+ .withChild(createLeaf("choiceLeaf", 12))
+ .build();
+ return Builders.containerBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONTAINER_Q_NAME))
+ .withChild(booleanLeaf)
+ .withChild(byteLeaf)
+ .withChild(shortLeaf)
+ .withChild(intLeaf)
+ .withChild(longLeaf)
+ .withChild(stringLeaf)
+ .withChild(longStringLeaf)
+ .withChild(qNameLeaf)
+ .withChild(idLeaf)
+ .withChild(mapNode)
+ .withChild(orderedMapNode)
+ .withChild(unkeyedListNode)
+ .withChild(leafSetNode)
+ .withChild(orderedLeafSetNode)
+ .withChild(augmentationNode)
+ .withChild(choiceNode)
+ .build();
+ }
+
+ private static <T> LeafNode<T> createLeaf(final String name, final T value) {
+ return ImmutableNodes.leafNode(id(name), value);
+ }
+
+ private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
+ return Builders.leafSetEntryBuilder()
+ .withNodeIdentifier(leafSetId(leafSet, value))
+ .withValue(value)
+ .build();
+ }
+
+ private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
+ return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
+ }
+
+ private static YangInstanceIdentifier.NodeIdentifierWithPredicates listId(final String listName,
+ final String keyName,
+ final Object keyValue) {
+ return YangInstanceIdentifier.NodeIdentifierWithPredicates.of(QName.create(CONTAINER_Q_NAME, listName),
+ QName.create(CONTAINER_Q_NAME, keyName), keyValue);
+ }
+
+ private static <T> YangInstanceIdentifier.NodeWithValue<T> leafSetId(final String node, final T value) {
+ return new YangInstanceIdentifier.NodeWithValue<>(QName.create(CONTAINER_Q_NAME, node), value);
+ }
+
+ private static YangInstanceIdentifier.AugmentationIdentifier autmentationId(final String... nodes) {
+ final Set<QName> qNames = Arrays.stream(nodes)
+ .map(node -> QName.create(CONTAINER_Q_NAME, node))
+ .collect(Collectors.toSet());
+ return new YangInstanceIdentifier.AugmentationIdentifier(qNames);
+ }
+
+ private static String getLongString() {
+ final StringBuilder builder = new StringBuilder(10000);
+ for (int i = 0; i < 1000; i++) {
+ builder.append("0123456789");
+ }
+ return builder.toString();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.node.utils.transformer;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
+
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.util.concurrent.atomic.AtomicInteger;
+import javax.xml.transform.dom.DOMSource;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.MockitoAnnotations;
+import org.opendaylight.controller.cluster.datastore.node.utils.NormalizedNodeNavigator;
+import org.opendaylight.controller.cluster.datastore.util.TestModel;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode;
+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.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.stream.NormalizedNodeWriter;
+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.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+
+public class NormalizedNodePrunerTest {
+ private static final SchemaContext NO_TEST_SCHEMA = TestModel.createTestContextWithoutTestSchema();
+ private static final SchemaContext NO_AUG_SCHEMA = TestModel.createTestContextWithoutAugmentationSchema();
+ private static final SchemaContext FULL_SCHEMA = TestModel.createTestContext();
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ }
+
+ private static NormalizedNodePruner prunerFullSchema(final YangInstanceIdentifier path) {
+ return new NormalizedNodePruner(path, FULL_SCHEMA);
+ }
+
+ private static NormalizedNodePruner prunerNoAugSchema(final YangInstanceIdentifier path) {
+ return new NormalizedNodePruner(path, NO_AUG_SCHEMA);
+ }
+
+ private static NormalizedNodePruner prunerNoTestSchema(final YangInstanceIdentifier path) {
+ return new NormalizedNodePruner(path, NO_TEST_SCHEMA);
+ }
+
+ @Test
+ public void testNodesNotPrunedWhenSchemaPresent() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH);
+
+ NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
+
+ NormalizedNode<?, ?> expected = createTestContainer();
+
+ normalizedNodeWriter.write(expected);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+
+ assertEquals(expected, actual);
+
+ }
+
+ @Test(expected = IllegalStateException.class)
+ public void testReusePruner() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH);
+
+ NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
+
+ NormalizedNode<?, ?> expected = createTestContainer();
+
+ normalizedNodeWriter.write(expected);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+
+ assertEquals(expected, actual);
+
+ NormalizedNodeWriter.forStreamWriter(pruner).write(expected);
+
+ }
+
+
+ @Test
+ public void testNodesPrunedWhenAugmentationSchemaMissing() throws IOException {
+ NormalizedNodePruner pruner = prunerNoAugSchema(TestModel.TEST_PATH);
+
+ NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
+
+ NormalizedNode<?, ?> expected = createTestContainer();
+
+ normalizedNodeWriter.write(expected);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+
+ Assert.assertNotEquals(expected, actual);
+
+ // Asserting true here instead of checking actual value because I don't want this assertion to be fragile
+ assertTrue(countNodes(expected, "store:aug") > 0);
+
+ // All nodes from the augmentation module are gone from the resulting node
+ assertEquals(0, countNodes(actual, "store:aug"));
+ }
+
+ @Test
+ public void testNodesPrunedWhenTestSchemaMissing() throws IOException {
+ NormalizedNodePruner pruner = prunerNoTestSchema(TestModel.TEST_PATH);
+
+ NormalizedNodeWriter normalizedNodeWriter = NormalizedNodeWriter.forStreamWriter(pruner);
+
+ NormalizedNode<?, ?> expected = createTestContainer();
+
+ normalizedNodeWriter.write(expected);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+
+ // Since top level schema is missing null is returned
+ assertNull(actual);
+
+ // Asserting true here instead of checking actual value because I don't want this assertion to be fragile
+ assertTrue(countNodes(expected, "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test") > 0);
+
+ }
+
+ private static int countNodes(final NormalizedNode<?,?> normalizedNode, final String namespaceFilter) {
+ if (normalizedNode == null) {
+ return 0;
+ }
+ final AtomicInteger count = new AtomicInteger();
+ new NormalizedNodeNavigator((level, parentPath, normalizedNode1) -> {
+ if (!(normalizedNode1.getIdentifier() instanceof AugmentationIdentifier)) {
+ if (normalizedNode1.getIdentifier().getNodeType().getNamespace().toString().contains(namespaceFilter)) {
+ count.incrementAndGet();
+ }
+ }
+ }).navigate(YangInstanceIdentifier.empty().toString(), normalizedNode);
+
+ return count.get();
+ }
+
+ @Test
+ public void testLeafNodeNotPrunedWhenHasNoParent() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH.node(TestModel.DESC_QNAME));
+ NormalizedNode<?, ?> input = Builders.leafBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.DESC_QNAME)).withValue("test").build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", input, actual);
+ }
+
+ @Test
+ public void testLeafNodePrunedWhenHasAugmentationParentAndSchemaMissing() throws IOException {
+ AugmentationIdentifier augId = new AugmentationIdentifier(Sets.newHashSet(TestModel.AUG_CONT_QNAME));
+ NormalizedNodePruner pruner = prunerFullSchema(YangInstanceIdentifier.builder()
+ .node(TestModel.TEST_QNAME).node(TestModel.AUGMENTED_LIST_QNAME)
+ .node(TestModel.AUGMENTED_LIST_QNAME).node(augId).build());
+ LeafNode<Object> child = Builders.leafBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.INVALID_QNAME)).withValue("test").build();
+ NormalizedNode<?, ?> input = Builders.augmentationBuilder().withNodeIdentifier(augId).withChild(child).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", Builders.augmentationBuilder().withNodeIdentifier(augId).build(), actual);
+ }
+
+ @Test
+ public void testLeafNodePrunedWhenHasNoParentAndSchemaMissing() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH.node(TestModel.INVALID_QNAME));
+ NormalizedNode<?, ?> input = Builders.leafBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.INVALID_QNAME)).withValue("test").build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertNull(actual);
+ }
+
+
+ @Test
+ public void testLeafSetEntryNodeNotPrunedWhenHasNoParent() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH.node(TestModel.SHOE_QNAME));
+ NormalizedNode<?, ?> input = Builders.leafSetEntryBuilder().withValue("puma").withNodeIdentifier(
+ new NodeWithValue<>(TestModel.SHOE_QNAME, "puma")).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", input, actual);
+ }
+
+ @Test
+ public void testLeafSetEntryNodeNotPrunedWhenHasParent() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH.node(TestModel.SHOE_QNAME));
+ LeafSetEntryNode<Object> child = Builders.leafSetEntryBuilder().withValue("puma").withNodeIdentifier(
+ new NodeWithValue<>(TestModel.SHOE_QNAME, "puma")).build();
+ NormalizedNode<?, ?> input = Builders.leafSetBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.SHOE_QNAME)).withChild(child).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", input, actual);
+ }
+
+ @Test
+ public void testLeafSetEntryNodePrunedWhenHasNoParentAndSchemaMissing() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH.node(TestModel.INVALID_QNAME));
+ NormalizedNode<?, ?> input = Builders.leafSetEntryBuilder().withValue("test").withNodeIdentifier(
+ new NodeWithValue<>(TestModel.INVALID_QNAME, "test")).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertNull(actual);
+ }
+
+ @Test
+ public void testLeafSetEntryNodePrunedWhenHasParentAndSchemaMissing() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH.node(TestModel.INVALID_QNAME));
+ LeafSetEntryNode<Object> child = Builders.leafSetEntryBuilder().withValue("test").withNodeIdentifier(
+ new NodeWithValue<>(TestModel.INVALID_QNAME, "test")).build();
+ NormalizedNode<?, ?> input = Builders.leafSetBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.INVALID_QNAME)).withChild(child).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertNull(actual);
+ }
+
+ @Test
+ public void testAnyXMLNodeNotPrunedWhenHasNoParent() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH.node(TestModel.ANY_XML_QNAME));
+ NormalizedNode<?, ?> input = Builders.anyXmlBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.ANY_XML_QNAME)).withValue(mock(DOMSource.class)).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", input, actual);
+ }
+
+
+ @Test
+ public void testAnyXMLNodeNotPrunedWhenHasParent() throws IOException {
+ NormalizedNodePruner pruner = prunerFullSchema(TestModel.TEST_PATH);
+ DOMSourceAnyxmlNode child = Builders.anyXmlBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.ANY_XML_QNAME)).withValue(mock(DOMSource.class)).build();
+ NormalizedNode<?, ?> input = Builders.containerBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.TEST_QNAME)).withChild(child).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", input, actual);
+ }
+
+ @Test
+ public void testAnyXmlNodePrunedWhenHasNoParentAndSchemaMissing() throws IOException {
+ NormalizedNodePruner pruner = prunerNoTestSchema(TestModel.TEST_PATH.node(TestModel.ANY_XML_QNAME));
+ NormalizedNode<?, ?> input = Builders.anyXmlBuilder().withNodeIdentifier(
+ new NodeIdentifier(TestModel.ANY_XML_QNAME)).withValue(mock(DOMSource.class)).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertNull(actual);
+ }
+
+ @Test
+ public void testInnerContainerNodeWithFullPathPathNotPruned() throws IOException {
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(TestModel.TEST_QNAME)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .node(TestModel.INNER_LIST_QNAME).nodeWithKey(TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "one")
+ .node(TestModel.INNER_CONTAINER_QNAME).build();
+ NormalizedNodePruner pruner = prunerFullSchema(path);
+
+ NormalizedNode<?, ?> input = ImmutableNodes.containerNode(TestModel.INNER_CONTAINER_QNAME);
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", input, actual);
+ }
+
+ @Test
+ public void testInnerContainerNodeWithFullPathPrunedWhenSchemaMissing() throws IOException {
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(TestModel.TEST_QNAME)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .node(TestModel.INNER_LIST_QNAME).nodeWithKey(TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "one")
+ .node(TestModel.INVALID_QNAME).build();
+ NormalizedNodePruner pruner = prunerFullSchema(path);
+
+ NormalizedNode<?, ?> input = ImmutableNodes.containerNode(TestModel.INVALID_QNAME);
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertNull(actual);
+ }
+
+ @Test
+ public void testInnerContainerNodeWithParentPathPrunedWhenSchemaMissing() throws IOException {
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(TestModel.TEST_QNAME)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .build();
+ NormalizedNodePruner pruner = prunerFullSchema(path);
+
+ MapNode innerList = mapNodeBuilder(TestModel.INNER_LIST_QNAME).withChild(mapEntryBuilder(
+ TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "one").withChild(
+ ImmutableNodes.containerNode(TestModel.INVALID_QNAME)).build()).build();
+ NormalizedNode<?, ?> input = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .withChild(innerList).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> expected = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .withChild(mapNodeBuilder(TestModel.INNER_LIST_QNAME).withChild(mapEntryBuilder(
+ TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "one").build()).build()).build();
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", expected, actual);
+ }
+
+ @Test
+ public void testInnerListNodeWithFullPathNotPruned() throws IOException {
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(TestModel.TEST_QNAME)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .node(TestModel.INNER_LIST_QNAME).build();
+ NormalizedNodePruner pruner = prunerFullSchema(path);
+
+ MapNode input = mapNodeBuilder(TestModel.INNER_LIST_QNAME).withChild(mapEntryBuilder(
+ TestModel.INNER_LIST_QNAME, TestModel.NAME_QNAME, "one").withChild(
+ ImmutableNodes.containerNode(TestModel.INNER_CONTAINER_QNAME)).build()).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", input, actual);
+ }
+
+ @Test
+ public void testInnerListNodeWithFullPathPrunedWhenSchemaMissing() throws IOException {
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(TestModel.TEST_QNAME)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .node(TestModel.INVALID_QNAME).build();
+ NormalizedNodePruner pruner = prunerFullSchema(path);
+
+ MapNode input = mapNodeBuilder(TestModel.INVALID_QNAME).withChild(mapEntryBuilder(
+ TestModel.INVALID_QNAME, TestModel.NAME_QNAME, "one").withChild(
+ ImmutableNodes.containerNode(TestModel.INNER_CONTAINER_QNAME)).build()).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertNull(actual);
+ }
+
+ @Test
+ public void testInnerListNodeWithParentPathPrunedWhenSchemaMissing() throws IOException {
+ YangInstanceIdentifier path = YangInstanceIdentifier.builder().node(TestModel.TEST_QNAME)
+ .node(TestModel.OUTER_LIST_QNAME).nodeWithKey(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .build();
+ NormalizedNodePruner pruner = prunerFullSchema(path);
+
+ MapNode innerList = mapNodeBuilder(TestModel.INVALID_QNAME).withChild(mapEntryBuilder(
+ TestModel.INVALID_QNAME, TestModel.NAME_QNAME, "one").withChild(
+ ImmutableNodes.containerNode(TestModel.INNER_CONTAINER_QNAME)).build()).build();
+ NormalizedNode<?, ?> input = mapEntryBuilder(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1)
+ .withChild(innerList).build();
+ NormalizedNodeWriter.forStreamWriter(pruner).write(input);
+
+ NormalizedNode<?, ?> expected = mapEntry(TestModel.OUTER_LIST_QNAME, TestModel.ID_QNAME, 1);
+ NormalizedNode<?, ?> actual = pruner.normalizedNode();
+ assertEquals("normalizedNode", expected, actual);
+ }
+
+ private static NormalizedNode<?, ?> createTestContainer() {
+ byte[] bytes1 = {1, 2, 3};
+ LeafSetEntryNode<Object> entry1 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new NodeWithValue<>(TestModel.BINARY_LEAF_LIST_QNAME, bytes1)).withValue(bytes1).build();
+
+ byte[] bytes2 = {};
+ LeafSetEntryNode<Object> entry2 = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new NodeWithValue<>(TestModel.BINARY_LEAF_LIST_QNAME, bytes2)).withValue(bytes2).build();
+
+ return TestModel.createBaseTestContainerBuilder()
+ .withChild(ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(
+ new NodeIdentifier(TestModel.BINARY_LEAF_LIST_QNAME))
+ .withChild(entry1).withChild(entry2).build())
+ .withChild(ImmutableNodes.leafNode(TestModel.SOME_BINARY_DATA_QNAME, new byte[]{1, 2, 3, 4}))
+ .build();
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2014, 2015 Cisco Systems, Inc. and others. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.controller.cluster.datastore.util;
+
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntry;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapEntryBuilder;
+import static org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes.mapNodeBuilder;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
+import java.io.InputStream;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.AugmentationIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
+import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
+import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+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.LeafSetNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+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.api.CollectionNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.NormalizedNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
+import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableMapEntryNodeBuilder;
+import org.opendaylight.yangtools.yang.model.api.SchemaContext;
+import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
+
+public final class TestModel {
+
+ public static final QName TEST_QNAME = QName.create(
+ "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:test",
+ "2014-03-13", "test");
+
+ public static final QName AUG_NAME_QNAME = QName.create(
+ "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:aug",
+ "2014-03-13", "name");
+
+ public static final QName AUG_CONT_QNAME = QName.create(
+ "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:aug",
+ "2014-03-13", "cont");
+
+
+ public static final QName DESC_QNAME = QName.create(TEST_QNAME, "desc");
+ public static final QName POINTER_QNAME = QName.create(TEST_QNAME, "pointer");
+ public static final QName SOME_BINARY_DATA_QNAME = QName.create(TEST_QNAME, "some-binary-data");
+ public static final QName BINARY_LEAF_LIST_QNAME = QName.create(TEST_QNAME, "binary_leaf_list");
+ public static final QName SOME_REF_QNAME = QName.create(TEST_QNAME, "some-ref");
+ public static final QName MYIDENTITY_QNAME = QName.create(TEST_QNAME, "myidentity");
+ public static final QName SWITCH_FEATURES_QNAME = QName.create(TEST_QNAME, "switch-features");
+
+ public static final QName AUGMENTED_LIST_QNAME = QName.create(TEST_QNAME, "augmented-list");
+ public static final QName AUGMENTED_LIST_ENTRY_QNAME = QName.create(TEST_QNAME, "augmented-list-entry");
+
+ public static final QName OUTER_LIST_QNAME = QName.create(TEST_QNAME, "outer-list");
+ public static final QName INNER_LIST_QNAME = QName.create(TEST_QNAME, "inner-list");
+ public static final QName INNER_CONTAINER_QNAME = QName.create(TEST_QNAME, "inner-container");
+ public static final QName OUTER_CHOICE_QNAME = QName.create(TEST_QNAME, "outer-choice");
+ public static final QName ID_QNAME = QName.create(TEST_QNAME, "id");
+ public static final QName NAME_QNAME = QName.create(TEST_QNAME, "name");
+ public static final QName VALUE_QNAME = QName.create(TEST_QNAME, "value");
+ public static final QName BOOLEAN_LEAF_QNAME = QName.create(TEST_QNAME, "boolean-leaf");
+ public static final QName SHORT_LEAF_QNAME = QName.create(TEST_QNAME, "short-leaf");
+ public static final QName BYTE_LEAF_QNAME = QName.create(TEST_QNAME, "byte-leaf");
+ public static final QName BIGINTEGER_LEAF_QNAME = QName.create(TEST_QNAME, "biginteger-leaf");
+ public static final QName BIGDECIMAL_LEAF_QNAME = QName.create(TEST_QNAME, "bigdecimal-leaf");
+ public static final QName ORDERED_LIST_QNAME = QName.create(TEST_QNAME, "ordered-list");
+ public static final QName ORDERED_LIST_ENTRY_QNAME = QName.create(TEST_QNAME, "ordered-list-leaf");
+ public static final QName UNKEYED_LIST_QNAME = QName.create(TEST_QNAME, "unkeyed-list");
+ public static final QName UNKEYED_LIST_ENTRY_QNAME = QName.create(TEST_QNAME, "unkeyed-list-entry");
+ public static final QName CHOICE_QNAME = QName.create(TEST_QNAME, "choice");
+ public static final QName SHOE_QNAME = QName.create(TEST_QNAME, "shoe");
+ public static final QName ANY_XML_QNAME = QName.create(TEST_QNAME, "any");
+ public static final QName EMPTY_QNAME = QName.create(TEST_QNAME, "empty-leaf");
+ public static final QName INVALID_QNAME = QName.create(TEST_QNAME, "invalid");
+ private static final String DATASTORE_TEST_YANG = "/odl-datastore-test.yang";
+ private static final String DATASTORE_AUG_YANG = "/odl-datastore-augmentation.yang";
+ private static final String DATASTORE_TEST_NOTIFICATION_YANG = "/odl-datastore-test-notification.yang";
+
+ public static final YangInstanceIdentifier TEST_PATH = YangInstanceIdentifier.of(TEST_QNAME);
+ public static final YangInstanceIdentifier DESC_PATH = YangInstanceIdentifier
+ .builder(TEST_PATH).node(DESC_QNAME).build();
+ public static final YangInstanceIdentifier OUTER_LIST_PATH =
+ YangInstanceIdentifier.builder(TEST_PATH).node(OUTER_LIST_QNAME).build();
+ public static final QName TWO_THREE_QNAME = QName.create(TEST_QNAME, "two");
+ public static final QName TWO_QNAME = QName.create(TEST_QNAME, "two");
+ public static final QName THREE_QNAME = QName.create(TEST_QNAME, "three");
+
+ private static final Integer ONE_ID = 1;
+ private static final Integer TWO_ID = 2;
+ private static final String TWO_ONE_NAME = "one";
+ private static final String TWO_TWO_NAME = "two";
+ private static final String DESC = "Hello there";
+ private static final Boolean ENABLED = true;
+ private static final Short SHORT_ID = 1;
+ private static final Byte BYTE_ID = 1;
+ // Family specific constants
+ public static final QName FAMILY_QNAME = QName.create(
+ "urn:opendaylight:params:xml:ns:yang:controller:md:sal:dom:store:notification-test", "2014-04-17", "family");
+ public static final QName CHILDREN_QNAME = QName.create(FAMILY_QNAME, "children");
+ public static final QName GRAND_CHILDREN_QNAME = QName.create(FAMILY_QNAME, "grand-children");
+ public static final QName CHILD_NUMBER_QNAME = QName.create(FAMILY_QNAME, "child-number");
+ public static final QName CHILD_NAME_QNAME = QName.create(FAMILY_QNAME, "child-name");
+ public static final QName GRAND_CHILD_NUMBER_QNAME = QName.create(FAMILY_QNAME, "grand-child-number");
+ public static final QName GRAND_CHILD_NAME_QNAME = QName.create(FAMILY_QNAME,"grand-child-name");
+
+ public static final YangInstanceIdentifier FAMILY_PATH = YangInstanceIdentifier.of(FAMILY_QNAME);
+ public static final YangInstanceIdentifier FAMILY_DESC_PATH =
+ YangInstanceIdentifier.builder(FAMILY_PATH).node(DESC_QNAME).build();
+ public static final YangInstanceIdentifier CHILDREN_PATH =
+ YangInstanceIdentifier.builder(FAMILY_PATH).node(CHILDREN_QNAME).build();
+
+ private static final Integer FIRST_CHILD_ID = 1;
+ private static final Integer SECOND_CHILD_ID = 2;
+
+ private static final String FIRST_CHILD_NAME = "first child";
+ private static final String SECOND_CHILD_NAME = "second child";
+
+ private static final Integer FIRST_GRAND_CHILD_ID = 1;
+ private static final Integer SECOND_GRAND_CHILD_ID = 2;
+
+ private static final String FIRST_GRAND_CHILD_NAME = "first grand child";
+ private static final String SECOND_GRAND_CHILD_NAME = "second grand child";
+
+ private static final MapEntryNode BAR_NODE = mapEntryBuilder(
+ OUTER_LIST_QNAME, ID_QNAME, TWO_ID) //
+ .withChild(mapNodeBuilder(INNER_LIST_QNAME) //
+ .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_ONE_NAME)) //
+ .withChild(mapEntry(INNER_LIST_QNAME, NAME_QNAME, TWO_TWO_NAME)) //
+ .build()) //
+ .build();
+
+ private TestModel() {
+ throw new UnsupportedOperationException();
+ }
+
+ public static InputStream getDatastoreTestInputStream() {
+ return getInputStream(DATASTORE_TEST_YANG);
+ }
+
+ public static InputStream getDatastoreAugInputStream() {
+ return getInputStream(DATASTORE_AUG_YANG);
+ }
+
+ public static InputStream getDatastoreTestNotificationInputStream() {
+ return getInputStream(DATASTORE_TEST_NOTIFICATION_YANG);
+ }
+
+ private static InputStream getInputStream(final String resourceName) {
+ return TestModel.class.getResourceAsStream(resourceName);
+ }
+
+ public static SchemaContext createTestContext() {
+ return YangParserTestUtils.parseYangResources(TestModel.class, DATASTORE_TEST_YANG, DATASTORE_AUG_YANG,
+ DATASTORE_TEST_NOTIFICATION_YANG);
+ }
+
+ public static SchemaContext createTestContextWithoutTestSchema() {
+ return YangParserTestUtils.parseYangResource(DATASTORE_TEST_NOTIFICATION_YANG);
+ }
+
+ public static SchemaContext createTestContextWithoutAugmentationSchema() {
+ return YangParserTestUtils.parseYangResources(TestModel.class, DATASTORE_TEST_YANG,
+ DATASTORE_TEST_NOTIFICATION_YANG);
+ }
+
+ /**
+ * Returns a test document.
+ * <p/>
+ * <p/>
+ * <pre>
+ * test
+ * outer-list
+ * id 1
+ * outer-list
+ * id 2
+ * inner-list
+ * name "one"
+ * inner-list
+ * name "two"
+ *
+ * </pre>
+ */
+ public static NormalizedNode<?, ?> createDocumentOne(final SchemaContext schemaContext) {
+ return ImmutableContainerNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new NodeIdentifier(schemaContext.getQName()))
+ .withChild(createTestContainer()).build();
+
+ }
+
+ public static DataContainerNodeBuilder<NodeIdentifier, ContainerNode> createBaseTestContainerBuilder() {
+ // Create a list of shoes
+ // This is to test leaf list entry
+ final LeafSetEntryNode<Object> nike = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new NodeWithValue<>(SHOE_QNAME, "nike")).withValue("nike").build();
+
+ final LeafSetEntryNode<Object> puma = ImmutableLeafSetEntryNodeBuilder.create().withNodeIdentifier(
+ new NodeWithValue<>(SHOE_QNAME, "puma")).withValue("puma").build();
+
+ final LeafSetNode<Object> shoes = ImmutableLeafSetNodeBuilder.create().withNodeIdentifier(
+ new NodeIdentifier(SHOE_QNAME)).withChild(nike).withChild(puma).build();
+
+ // Test a leaf-list where each entry contains an identity
+ final LeafSetEntryNode<Object> cap1 =
+ ImmutableLeafSetEntryNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new NodeWithValue<>(QName.create(
+ TEST_QNAME, "capability"), DESC_QNAME))
+ .withValue(DESC_QNAME).build();
+
+ final LeafSetNode<Object> capabilities =
+ ImmutableLeafSetNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new NodeIdentifier(QName.create(
+ TEST_QNAME, "capability"))).withChild(cap1).build();
+
+ ContainerNode switchFeatures =
+ ImmutableContainerNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new NodeIdentifier(SWITCH_FEATURES_QNAME))
+ .withChild(capabilities).build();
+
+ // Create a leaf list with numbers
+ final LeafSetEntryNode<Object> five =
+ ImmutableLeafSetEntryNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new NodeWithValue<>(QName.create(
+ TEST_QNAME, "number"), 5)).withValue(5).build();
+ final LeafSetEntryNode<Object> fifteen =
+ ImmutableLeafSetEntryNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new NodeWithValue<>(QName.create(
+ TEST_QNAME, "number"), 15)).withValue(15).build();
+ final LeafSetNode<Object> numbers =
+ ImmutableLeafSetNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new NodeIdentifier(QName.create(
+ TEST_QNAME, "number"))).withChild(five).withChild(fifteen)
+ .build();
+
+
+ // Create augmentations
+ MapEntryNode augMapEntry = createAugmentedListEntry(1, "First Test");
+
+ // Create a bits leaf
+ NormalizedNodeBuilder<NodeIdentifier, Object, LeafNode<Object>>
+ myBits = Builders.leafBuilder()
+ .withNodeIdentifier(new NodeIdentifier(QName.create(TEST_QNAME, "my-bits")))
+ .withValue(ImmutableSet.of("foo", "bar"));
+
+ // Create unkeyed list entry
+ UnkeyedListEntryNode unkeyedListEntry =
+ Builders.unkeyedListEntryBuilder().withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(
+ UNKEYED_LIST_QNAME)).withChild(ImmutableNodes.leafNode(NAME_QNAME, "unkeyed-entry-name")).build();
+
+ // Create YangInstanceIdentifier with all path arg types.
+ YangInstanceIdentifier instanceID = YangInstanceIdentifier.create(
+ new NodeIdentifier(QName.create(TEST_QNAME, "qname")),
+ NodeIdentifierWithPredicates.of(QName.create(TEST_QNAME, "list-entry"),
+ QName.create(TEST_QNAME, "key"), 10),
+ new AugmentationIdentifier(ImmutableSet.of(
+ QName.create(TEST_QNAME, "aug1"), QName.create(TEST_QNAME, "aug2"))),
+ new NodeWithValue<>(QName.create(TEST_QNAME, "leaf-list-entry"), "foo"));
+
+ Map<QName, Object> keyValues = new HashMap<>();
+ keyValues.put(CHILDREN_QNAME, FIRST_CHILD_NAME);
+
+
+ // Create the document
+ return ImmutableContainerNodeBuilder
+ .create()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TEST_QNAME))
+ .withChild(myBits.build())
+ .withChild(ImmutableNodes.leafNode(DESC_QNAME, DESC))
+ .withChild(ImmutableNodes.leafNode(BOOLEAN_LEAF_QNAME, ENABLED))
+ .withChild(ImmutableNodes.leafNode(SHORT_LEAF_QNAME, SHORT_ID))
+ .withChild(ImmutableNodes.leafNode(BYTE_LEAF_QNAME, BYTE_ID))
+ .withChild(ImmutableNodes.leafNode(TestModel.BIGINTEGER_LEAF_QNAME, BigInteger.valueOf(100)))
+ .withChild(ImmutableNodes.leafNode(TestModel.BIGDECIMAL_LEAF_QNAME, BigDecimal.valueOf(1.2)))
+ .withChild(ImmutableNodes.leafNode(SOME_REF_QNAME, instanceID))
+ .withChild(ImmutableNodes.leafNode(MYIDENTITY_QNAME, DESC_QNAME))
+ .withChild(Builders.unkeyedListBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(UNKEYED_LIST_QNAME))
+ .withChild(unkeyedListEntry).build())
+ .withChild(Builders.choiceBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(TWO_THREE_QNAME))
+ .withChild(ImmutableNodes.leafNode(TWO_QNAME, "two")).build())
+ .withChild(Builders.orderedMapBuilder()
+ .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(ORDERED_LIST_QNAME))
+ .withValue(ImmutableList.<MapEntryNode>builder().add(
+ mapEntryBuilder(ORDERED_LIST_QNAME, ORDERED_LIST_ENTRY_QNAME, "1").build(),
+ mapEntryBuilder(ORDERED_LIST_QNAME, ORDERED_LIST_ENTRY_QNAME, "2").build()).build())
+ .build())
+ .withChild(shoes)
+ .withChild(numbers)
+ .withChild(switchFeatures)
+ .withChild(mapNodeBuilder(AUGMENTED_LIST_QNAME).withChild(augMapEntry).build())
+ .withChild(mapNodeBuilder(OUTER_LIST_QNAME)
+ .withChild(mapEntry(OUTER_LIST_QNAME, ID_QNAME, ONE_ID))
+ .withChild(BAR_NODE).build()
+ );
+ }
+
+ public static ContainerNode createTestContainer() {
+ return createBaseTestContainerBuilder().build();
+ }
+
+ public static MapEntryNode createAugmentedListEntry(final int id, final String name) {
+
+ Set<QName> childAugmentations = new HashSet<>();
+ childAugmentations.add(AUG_CONT_QNAME);
+
+ ContainerNode augCont =
+ ImmutableContainerNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ new YangInstanceIdentifier.NodeIdentifier(AUG_CONT_QNAME))
+ .withChild(ImmutableNodes.leafNode(AUG_NAME_QNAME, name)).build();
+
+
+ final YangInstanceIdentifier.AugmentationIdentifier augmentationIdentifier =
+ new YangInstanceIdentifier.AugmentationIdentifier(childAugmentations);
+
+ final AugmentationNode augmentationNode =
+ Builders.augmentationBuilder()
+ .withNodeIdentifier(augmentationIdentifier).withChild(augCont)
+ .build();
+
+ return ImmutableMapEntryNodeBuilder
+ .create()
+ .withNodeIdentifier(
+ YangInstanceIdentifier.NodeIdentifierWithPredicates.of(
+ AUGMENTED_LIST_QNAME, ID_QNAME, id))
+ .withChild(ImmutableNodes.leafNode(ID_QNAME, id))
+ .withChild(augmentationNode).build();
+ }
+
+
+ public static ContainerNode createFamily() {
+ final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifier, ContainerNode>
+ familyContainerBuilder = ImmutableContainerNodeBuilder.create().withNodeIdentifier(
+ new YangInstanceIdentifier.NodeIdentifier(FAMILY_QNAME));
+
+ final CollectionNodeBuilder<MapEntryNode, MapNode> childrenBuilder =
+ mapNodeBuilder(CHILDREN_QNAME);
+
+ final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+ firstChildBuilder = mapEntryBuilder(CHILDREN_QNAME, CHILD_NUMBER_QNAME, FIRST_CHILD_ID);
+ final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+ secondChildBuilder = mapEntryBuilder(CHILDREN_QNAME, CHILD_NUMBER_QNAME, SECOND_CHILD_ID);
+
+ final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+ firstGrandChildBuilder = mapEntryBuilder(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+ FIRST_GRAND_CHILD_ID);
+ final DataContainerNodeBuilder<YangInstanceIdentifier.NodeIdentifierWithPredicates, MapEntryNode>
+ secondGrandChildBuilder = mapEntryBuilder(GRAND_CHILDREN_QNAME, GRAND_CHILD_NUMBER_QNAME,
+ SECOND_GRAND_CHILD_ID);
+
+ firstGrandChildBuilder
+ .withChild(
+ ImmutableNodes.leafNode(GRAND_CHILD_NUMBER_QNAME,
+ FIRST_GRAND_CHILD_ID)).withChild(
+ ImmutableNodes.leafNode(GRAND_CHILD_NAME_QNAME,
+ FIRST_GRAND_CHILD_NAME));
+
+ secondGrandChildBuilder.withChild(
+ ImmutableNodes
+ .leafNode(GRAND_CHILD_NUMBER_QNAME, SECOND_GRAND_CHILD_ID))
+ .withChild(
+ ImmutableNodes.leafNode(GRAND_CHILD_NAME_QNAME,
+ SECOND_GRAND_CHILD_NAME));
+
+ firstChildBuilder
+ .withChild(ImmutableNodes.leafNode(CHILD_NUMBER_QNAME, FIRST_CHILD_ID))
+ .withChild(ImmutableNodes.leafNode(CHILD_NAME_QNAME, FIRST_CHILD_NAME))
+ .withChild(
+ mapNodeBuilder(GRAND_CHILDREN_QNAME).withChild(
+ firstGrandChildBuilder.build()).build());
+
+
+ secondChildBuilder
+ .withChild(ImmutableNodes.leafNode(CHILD_NUMBER_QNAME, SECOND_CHILD_ID))
+ .withChild(ImmutableNodes.leafNode(CHILD_NAME_QNAME, SECOND_CHILD_NAME))
+ .withChild(
+ mapNodeBuilder(GRAND_CHILDREN_QNAME).withChild(
+ firstGrandChildBuilder.build()).build());
+
+ childrenBuilder.withChild(firstChildBuilder.build());
+ childrenBuilder.withChild(secondChildBuilder.build());
+
+ return familyContainerBuilder.withChild(childrenBuilder.build()).build();
+ }
+
+}