2 * Copyright (c) 2017 Pantheon Technologies s.r.o. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.controller.cluster.datastore.node.utils.stream;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertTrue;
14 import java.io.ByteArrayInputStream;
15 import java.io.ByteArrayOutputStream;
16 import java.io.DataInputStream;
17 import java.io.DataOutputStream;
18 import java.io.IOException;
19 import java.nio.charset.StandardCharsets;
20 import java.util.concurrent.atomic.AtomicBoolean;
21 import javax.xml.transform.dom.DOMSource;
22 import org.junit.Test;
23 import org.opendaylight.yangtools.util.xml.UntrustedXML;
24 import org.opendaylight.yangtools.yang.common.QName;
25 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
26 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeWithValue;
29 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
33 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
34 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
35 import org.xmlunit.builder.DiffBuilder;
37 public class SerializationUtilsTest {
38 private static final QName CONTAINER1 = QName.create("ns-1", "2017-03-17", "container1");
41 public void testSerializeDeserializeNodes() throws Exception {
42 final var normalizedNode = createNormalizedNode();
43 final var bytes = serialize(normalizedNode);
44 assertEquals(10567, bytes.length);
45 assertEquals(normalizedNode, deserialize(bytes));
49 public void testSerializeDeserializeAnyXmlNode() throws Exception {
50 final var parse = UntrustedXML.newDocumentBuilder().parse(
51 new ByteArrayInputStream("<xml><data/></xml>".getBytes(StandardCharsets.UTF_8)));
52 final var anyXmlNode = Builders.anyXmlBuilder()
53 .withNodeIdentifier(id("anyXmlNode"))
54 .withValue(new DOMSource(parse))
56 final byte[] bytes = serialize(anyXmlNode);
57 assertEquals(113, bytes.length);
59 final var diff = DiffBuilder.compare(anyXmlNode.body().getNode())
60 // FIXME: why all this magic?
61 .withTest(((DOMSource) deserialize(bytes).body()).getNode().getOwnerDocument())
64 assertFalse(diff.toString(), diff.hasDifferences());
68 public void testSerializeDeserializePath() throws IOException {
69 final var path = YangInstanceIdentifier.builder()
70 .node(id("container1"))
71 .node(listId("list1", "keyName1", "keyValue1"))
72 .node(leafSetId("leafSer1", "leafSetValue1"))
75 final var bos = new ByteArrayOutputStream();
76 try (var out = new DataOutputStream(bos)) {
77 SerializationUtils.writePath(out, path);
80 final var bytes = bos.toByteArray();
81 assertEquals(105, bytes.length);
83 assertEquals(path, SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes))));
87 public void testSerializeDeserializePathAndNode() throws IOException {
88 final var path = YangInstanceIdentifier.of(id("container1"));
89 final var node = createNormalizedNode();
91 final var bos = new ByteArrayOutputStream();
92 try (var out = new DataOutputStream(bos)) {
93 SerializationUtils.writeNodeAndPath(out, path, node);
96 final byte[] bytes = bos.toByteArray();
97 assertEquals(10569, bytes.length);
99 final var applierCalled = new AtomicBoolean(false);
100 try (var in = new DataInputStream(new ByteArrayInputStream(bytes))) {
101 SerializationUtils.readNodeAndPath(in, applierCalled, (instance, deserializedPath, deserializedNode) -> {
102 assertEquals(path, deserializedPath);
103 assertEquals(node, deserializedNode);
104 applierCalled.set(true);
107 assertTrue(applierCalled.get());
110 private static NormalizedNode deserialize(final byte[] bytes) throws Exception {
111 return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)))
115 private static byte[] serialize(final NormalizedNode node) throws Exception {
116 final var bos = new ByteArrayOutputStream();
117 SerializationUtils.writeNormalizedNode(new DataOutputStream(bos), node);
118 return bos.toByteArray();
121 private static ContainerNode createNormalizedNode() {
122 final var stringLeaf = createLeaf("stringLeaf", "stringValue");
123 final var entry1 = Builders.mapEntryBuilder()
124 .withNodeIdentifier(listId("mapNode", "key", "key1"))
125 .withChild(stringLeaf)
127 final var entry2 = Builders.mapEntryBuilder()
128 .withNodeIdentifier(listId("mapNode", "key", "key2"))
129 .withChild(stringLeaf)
132 return Builders.containerBuilder()
133 .withNodeIdentifier(new NodeIdentifier(CONTAINER1))
134 .withChild(createLeaf("booleanLeaf", true))
135 .withChild(createLeaf("byteLeaf", (byte) 0))
136 .withChild(createLeaf("shortLeaf", (short) 55))
137 .withChild(createLeaf("intLeaf", 11))
138 .withChild(createLeaf("longLeaf", 151515L))
139 .withChild(stringLeaf)
140 .withChild(createLeaf("longStringLeaf", "0123456789".repeat(1000)))
141 .withChild(createLeaf("stringLeaf", QName.create("base", "qName")))
142 .withChild(createLeaf("stringLeaf", YangInstanceIdentifier.of(QName.create("test", "test"))))
143 .withChild(Builders.mapBuilder()
144 .withNodeIdentifier(id("mapNode"))
148 .withChild(Builders.orderedMapBuilder()
149 .withNodeIdentifier(id("orderedMapNode"))
153 .withChild(Builders.unkeyedListBuilder()
154 .withNodeIdentifier(id("unkeyedList"))
155 .withChild(Builders.unkeyedListEntryBuilder()
156 .withNodeIdentifier(id("unkeyedList"))
157 .withChild(stringLeaf)
159 .withChild(Builders.unkeyedListEntryBuilder()
160 .withNodeIdentifier(id("unkeyedList"))
161 .withChild(stringLeaf)
164 .withChild(Builders.leafSetBuilder()
165 .withNodeIdentifier(id("leafSetNode"))
166 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
167 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
169 .withChild(Builders.orderedLeafSetBuilder()
170 .withNodeIdentifier(id("orderedLeafSetNode"))
171 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
172 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
174 .withChild(createLeaf("aug1", "aug1Value"))
175 .withChild(createLeaf("aug2", "aug2Value"))
176 .withChild(Builders.choiceBuilder()
177 .withNodeIdentifier(id("choiceNode"))
178 .withChild(createLeaf("choiceLeaf", 12))
183 private static <T> LeafNode<T> createLeaf(final String name, final T value) {
184 return ImmutableNodes.leafNode(id(name), value);
187 private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
188 return Builders.leafSetEntryBuilder()
189 .withNodeIdentifier(leafSetId(leafSet, value))
194 private static NodeIdentifier id(final String name) {
195 return new NodeIdentifier(QName.create(CONTAINER1, name));
198 private static NodeIdentifierWithPredicates listId(final String listName, final String keyName,
199 final Object keyValue) {
200 return NodeIdentifierWithPredicates.of(QName.create(CONTAINER1, listName), QName.create(CONTAINER1, keyName),
204 private static <T> NodeWithValue<T> leafSetId(final String node, final T value) {
205 return new NodeWithValue<>(QName.create(CONTAINER1, node), value);