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.assertTrue;
13 import java.io.ByteArrayInputStream;
14 import java.io.ByteArrayOutputStream;
15 import java.io.DataInputStream;
16 import java.io.DataOutput;
17 import java.io.DataOutputStream;
18 import java.io.IOException;
19 import java.nio.charset.Charset;
20 import java.util.concurrent.atomic.AtomicBoolean;
21 import javax.xml.transform.dom.DOMSource;
22 import org.custommonkey.xmlunit.Diff;
23 import org.custommonkey.xmlunit.XMLUnit;
24 import org.junit.Test;
25 import org.opendaylight.yangtools.util.xml.UntrustedXML;
26 import org.opendaylight.yangtools.yang.common.QName;
27 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
28 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
29 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
30 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
31 import org.opendaylight.yangtools.yang.data.api.schema.DOMSourceAnyxmlNode;
32 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.UserMapNode;
41 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
42 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
43 import org.w3c.dom.Document;
45 public class SerializationUtilsTest {
47 private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
50 public void testSerializeDeserializeNodes() throws IOException {
51 final ContainerNode normalizedNode = createNormalizedNode();
52 final byte[] bytes = serializeNormalizedNode(normalizedNode);
53 assertEquals(10556, bytes.length);
54 assertEquals(normalizedNode, deserializeNormalizedNode(bytes));
58 public void testSerializeDeserializeAnyXmlNode() throws Exception {
59 final ByteArrayInputStream is =
60 new ByteArrayInputStream("<xml><data/></xml>".getBytes(Charset.defaultCharset()));
61 final Document parse = UntrustedXML.newDocumentBuilder().parse(is);
62 final DOMSourceAnyxmlNode anyXmlNode = Builders.anyXmlBuilder()
63 .withNodeIdentifier(id("anyXmlNode"))
64 .withValue(new DOMSource(parse))
66 final byte[] bytes = serializeNormalizedNode(anyXmlNode);
67 assertEquals(113, bytes.length);
68 final NormalizedNode deserialized = deserializeNormalizedNode(bytes);
69 final DOMSource value = (DOMSource) deserialized.body();
70 final Diff diff = XMLUnit.compareXML((Document) anyXmlNode.body().getNode(),
71 value.getNode().getOwnerDocument());
72 assertTrue(diff.toString(), diff.similar());
76 public void testSerializeDeserializePath() throws IOException {
77 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
78 final DataOutput out = new DataOutputStream(bos);
79 final YangInstanceIdentifier path = YangInstanceIdentifier.builder()
80 .node(id("container1"))
81 .node(listId("list1", "keyName1", "keyValue1"))
82 .node(leafSetId("leafSer1", "leafSetValue1"))
84 SerializationUtils.writePath(out, path);
86 final byte[] bytes = bos.toByteArray();
87 assertEquals(105, bytes.length);
89 final YangInstanceIdentifier deserialized =
90 SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes)));
91 assertEquals(path, deserialized);
95 public void testSerializeDeserializePathAndNode() throws IOException {
96 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
97 final DataOutput out = new DataOutputStream(bos);
98 final NormalizedNode node = createNormalizedNode();
99 final YangInstanceIdentifier path = YangInstanceIdentifier.of(id("container1"));
100 SerializationUtils.writeNodeAndPath(out, path, node);
102 final byte[] bytes = bos.toByteArray();
103 assertEquals(10558, bytes.length);
105 final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
106 final AtomicBoolean applierCalled = new AtomicBoolean(false);
107 SerializationUtils.readNodeAndPath(in, applierCalled, (instance, deserializedPath, deserializedNode) -> {
108 assertEquals(path, deserializedPath);
109 assertEquals(node, deserializedNode);
110 applierCalled.set(true);
112 assertTrue(applierCalled.get());
115 private static NormalizedNode deserializeNormalizedNode(final byte[] bytes) throws IOException {
116 return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)))
120 private static byte[] serializeNormalizedNode(final NormalizedNode node) throws IOException {
121 ByteArrayOutputStream bos = new ByteArrayOutputStream();
122 SerializationUtils.writeNormalizedNode(new DataOutputStream(bos), node);
123 return bos.toByteArray();
126 private static ContainerNode createNormalizedNode() {
127 final LeafSetNode<Object> leafSetNode = Builders.leafSetBuilder()
128 .withNodeIdentifier(id("leafSetNode"))
129 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
130 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
132 final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
133 .withNodeIdentifier(id("orderedLeafSetNode"))
134 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
135 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
137 final LeafNode<Boolean> booleanLeaf = createLeaf("booleanLeaf", true);
138 final LeafNode<Byte> byteLeaf = createLeaf("byteLeaf", (byte) 0);
139 final LeafNode<Short> shortLeaf = createLeaf("shortLeaf", (short) 55);
140 final LeafNode<Integer> intLeaf = createLeaf("intLeaf", 11);
141 final LeafNode<Long> longLeaf = createLeaf("longLeaf", 151515L);
142 final LeafNode<String> stringLeaf = createLeaf("stringLeaf", "stringValue");
143 final LeafNode<String> longStringLeaf = createLeaf("longStringLeaf", getLongString());
144 final LeafNode<QName> qNameLeaf = createLeaf("stringLeaf", QName.create("base", "qName"));
145 final LeafNode<YangInstanceIdentifier> idLeaf = createLeaf("stringLeaf", YangInstanceIdentifier.of());
146 final MapEntryNode entry1 = Builders.mapEntryBuilder()
147 .withNodeIdentifier(listId("mapNode", "key", "key1"))
148 .withChild(stringLeaf)
150 final MapEntryNode entry2 = Builders.mapEntryBuilder()
151 .withNodeIdentifier(listId("mapNode", "key", "key2"))
152 .withChild(stringLeaf)
154 final MapNode mapNode = Builders.mapBuilder()
155 .withNodeIdentifier(id("mapNode"))
159 final UserMapNode orderedMapNode = Builders.orderedMapBuilder()
160 .withNodeIdentifier(id("orderedMapNode"))
164 final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
165 .withNodeIdentifier(id("unkeyedList"))
166 .withChild(stringLeaf)
168 final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
169 .withNodeIdentifier(id("unkeyedList"))
170 .withChild(stringLeaf)
172 final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
173 .withNodeIdentifier(id("unkeyedList"))
174 .withChild(unkeyedListEntry1)
175 .withChild(unkeyedListEntry2)
177 final ChoiceNode choiceNode = Builders.choiceBuilder()
178 .withNodeIdentifier(id("choiceNode"))
179 .withChild(createLeaf("choiceLeaf", 12))
181 return Builders.containerBuilder()
182 .withNodeIdentifier(new NodeIdentifier(CONTAINER_Q_NAME))
183 .withChild(booleanLeaf)
185 .withChild(shortLeaf)
188 .withChild(stringLeaf)
189 .withChild(longStringLeaf)
190 .withChild(qNameLeaf)
193 .withChild(orderedMapNode)
194 .withChild(unkeyedListNode)
195 .withChild(leafSetNode)
196 .withChild(orderedLeafSetNode)
197 .withChild(createLeaf("aug1", "aug1Value"))
198 .withChild(createLeaf("aug2", "aug2Value"))
199 .withChild(choiceNode)
203 private static <T> LeafNode<T> createLeaf(final String name, final T value) {
204 return ImmutableNodes.leafNode(id(name), value);
207 private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
208 return Builders.leafSetEntryBuilder()
209 .withNodeIdentifier(leafSetId(leafSet, value))
214 private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
215 return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
218 private static YangInstanceIdentifier.NodeIdentifierWithPredicates listId(final String listName,
219 final String keyName,
220 final Object keyValue) {
221 return YangInstanceIdentifier.NodeIdentifierWithPredicates.of(QName.create(CONTAINER_Q_NAME, listName),
222 QName.create(CONTAINER_Q_NAME, keyName), keyValue);
225 private static <T> YangInstanceIdentifier.NodeWithValue<T> leafSetId(final String node, final T value) {
226 return new YangInstanceIdentifier.NodeWithValue<>(QName.create(CONTAINER_Q_NAME, node), value);
229 private static String getLongString() {
230 final StringBuilder builder = new StringBuilder(10000);
231 for (int i = 0; i < 1000; i++) {
232 builder.append("0123456789");
234 return builder.toString();