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 com.google.common.collect.ImmutableSet;
14 import java.io.ByteArrayInputStream;
15 import java.io.ByteArrayOutputStream;
16 import java.io.DataInputStream;
17 import java.io.DataOutput;
18 import java.io.DataOutputStream;
19 import java.io.IOException;
20 import java.nio.charset.Charset;
21 import java.util.Arrays;
23 import java.util.concurrent.atomic.AtomicBoolean;
24 import java.util.stream.Collectors;
25 import javax.xml.transform.dom.DOMSource;
26 import org.custommonkey.xmlunit.Diff;
27 import org.custommonkey.xmlunit.XMLUnit;
28 import org.junit.Test;
29 import org.opendaylight.yangtools.util.xml.UntrustedXML;
30 import org.opendaylight.yangtools.yang.common.QName;
31 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
32 import org.opendaylight.yangtools.yang.data.api.schema.AnyXmlNode;
33 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
41 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
44 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
45 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
46 import org.w3c.dom.Document;
48 public class SerializationUtilsTest {
50 private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
53 public void testSerializeDeserializeNodes() throws IOException {
54 final NormalizedNode<?, ?> normalizedNode = createNormalizedNode();
55 final byte[] bytes = serializeNormalizedNode(normalizedNode);
56 assertEquals(10774, bytes.length);
57 assertEquals(normalizedNode, deserializeNormalizedNode(bytes));
61 public void testSerializeDeserializeAnyXmlNode() throws Exception {
62 final ByteArrayInputStream is =
63 new ByteArrayInputStream("<xml><data/></xml>".getBytes(Charset.defaultCharset()));
64 final Document parse = UntrustedXML.newDocumentBuilder().parse(is);
65 final AnyXmlNode anyXmlNode = Builders.anyXmlBuilder()
66 .withNodeIdentifier(id("anyXmlNode"))
67 .withValue(new DOMSource(parse))
69 final byte[] bytes = serializeNormalizedNode(anyXmlNode);
70 assertEquals(115, bytes.length);
71 final NormalizedNode<?, ?> deserialized = deserializeNormalizedNode(bytes);
72 final DOMSource value = (DOMSource) deserialized.getValue();
73 final Diff diff = XMLUnit.compareXML((Document) anyXmlNode.getValue().getNode(),
74 value.getNode().getOwnerDocument());
75 assertTrue(diff.toString(), diff.similar());
79 public void testSerializeDeserializePath() throws IOException {
80 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
81 final DataOutput out = new DataOutputStream(bos);
82 final YangInstanceIdentifier path = YangInstanceIdentifier.builder()
83 .node(id("container1"))
84 .node(autmentationId("list1", "list2"))
85 .node(listId("list1", "keyName1", "keyValue1"))
86 .node(leafSetId("leafSer1", "leafSetValue1"))
88 SerializationUtils.writePath(out, path);
90 final byte[] bytes = bos.toByteArray();
91 assertEquals(150, bytes.length);
93 final YangInstanceIdentifier deserialized =
94 SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes)));
95 assertEquals(path, deserialized);
99 public void testSerializeDeserializePathAndNode() throws IOException {
100 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
101 final DataOutput out = new DataOutputStream(bos);
102 final NormalizedNode<?, ?> node = createNormalizedNode();
103 final YangInstanceIdentifier path = YangInstanceIdentifier.create(id("container1"));
104 SerializationUtils.writeNodeAndPath(out, path, node);
106 final byte[] bytes = bos.toByteArray();
107 assertEquals(10783, bytes.length);
109 final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
110 final AtomicBoolean applierCalled = new AtomicBoolean(false);
111 SerializationUtils.readNodeAndPath(in, applierCalled, (instance, deserializedPath, deserializedNode) -> {
112 assertEquals(path, deserializedPath);
113 assertEquals(node, deserializedNode);
114 applierCalled.set(true);
116 assertTrue(applierCalled.get());
119 private static NormalizedNode<?, ?> deserializeNormalizedNode(final byte[] bytes) throws IOException {
120 return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes))).get();
123 private static byte[] serializeNormalizedNode(final NormalizedNode<?, ?> node) throws IOException {
124 ByteArrayOutputStream bos = new ByteArrayOutputStream();
125 SerializationUtils.writeNormalizedNode(new DataOutputStream(bos), node);
126 return bos.toByteArray();
129 private static NormalizedNode<?, ?> createNormalizedNode() {
130 final LeafSetNode<Object> leafSetNode = Builders.leafSetBuilder()
131 .withNodeIdentifier(id("leafSetNode"))
132 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
133 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
135 final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
136 .withNodeIdentifier(id("orderedLeafSetNode"))
137 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
138 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
140 final LeafNode<Boolean> booleanLeaf = createLeaf("booleanLeaf", true);
141 final LeafNode<Byte> byteLeaf = createLeaf("byteLeaf", (byte) 0);
142 final LeafNode<Short> shortLeaf = createLeaf("shortLeaf", (short) 55);
143 final LeafNode<Integer> intLeaf = createLeaf("intLeaf", 11);
144 final LeafNode<Long> longLeaf = createLeaf("longLeaf", 151515L);
145 final LeafNode<String> stringLeaf = createLeaf("stringLeaf", "stringValue");
146 final LeafNode<String> longStringLeaf = createLeaf("longStringLeaf", getLongString());
147 final LeafNode<QName> qNameLeaf = createLeaf("stringLeaf", QName.create("base", "qName"));
148 final LeafNode<YangInstanceIdentifier> idLeaf = createLeaf("stringLeaf", YangInstanceIdentifier.empty());
149 final MapEntryNode entry1 = Builders.mapEntryBuilder()
150 .withNodeIdentifier(listId("mapNode", "key", "key1"))
151 .withChild(stringLeaf)
153 final MapEntryNode entry2 = Builders.mapEntryBuilder()
154 .withNodeIdentifier(listId("mapNode", "key", "key2"))
155 .withChild(stringLeaf)
157 final MapNode mapNode = Builders.mapBuilder()
158 .withNodeIdentifier(id("mapNode"))
162 final OrderedMapNode orderedMapNode = Builders.orderedMapBuilder()
163 .withNodeIdentifier(id("orderedMapNode"))
167 final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
168 .withNodeIdentifier(id("unkeyedList"))
169 .withChild(stringLeaf)
171 final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
172 .withNodeIdentifier(id("unkeyedList"))
173 .withChild(stringLeaf)
175 final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
176 .withNodeIdentifier(id("unkeyedList"))
177 .withChild(unkeyedListEntry1)
178 .withChild(unkeyedListEntry2)
180 final ImmutableSet<QName> childNames =
181 ImmutableSet.of(QName.create(CONTAINER_Q_NAME, "aug1"), QName.create(CONTAINER_Q_NAME, "aug1"));
182 final AugmentationNode augmentationNode = Builders.augmentationBuilder()
183 .withNodeIdentifier(new YangInstanceIdentifier.AugmentationIdentifier(childNames))
184 .withChild(createLeaf("aug1", "aug1Value"))
185 .withChild(createLeaf("aug2", "aug2Value"))
187 final ChoiceNode choiceNode = Builders.choiceBuilder()
188 .withNodeIdentifier(id("choiceNode"))
189 .withChild(createLeaf("choiceLeaf", 12))
191 return Builders.containerBuilder()
192 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONTAINER_Q_NAME))
193 .withChild(booleanLeaf)
195 .withChild(shortLeaf)
198 .withChild(stringLeaf)
199 .withChild(longStringLeaf)
200 .withChild(qNameLeaf)
203 .withChild(orderedMapNode)
204 .withChild(unkeyedListNode)
205 .withChild(leafSetNode)
206 .withChild(orderedLeafSetNode)
207 .withChild(augmentationNode)
208 .withChild(choiceNode)
212 private static <T> LeafNode<T> createLeaf(final String name, final T value) {
213 return ImmutableNodes.leafNode(id(name), value);
216 private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
217 return Builders.leafSetEntryBuilder()
218 .withNodeIdentifier(leafSetId(leafSet, value))
223 private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
224 return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
227 private static YangInstanceIdentifier.NodeIdentifierWithPredicates listId(final String listName,
228 final String keyName,
229 final Object keyValue) {
230 return YangInstanceIdentifier.NodeIdentifierWithPredicates.of(QName.create(CONTAINER_Q_NAME, listName),
231 QName.create(CONTAINER_Q_NAME, keyName), keyValue);
234 private static <T> YangInstanceIdentifier.NodeWithValue<T> leafSetId(final String node, final T value) {
235 return new YangInstanceIdentifier.NodeWithValue<>(QName.create(CONTAINER_Q_NAME, node), value);
238 private static YangInstanceIdentifier.AugmentationIdentifier autmentationId(final String... nodes) {
239 final Set<QName> qNames = Arrays.stream(nodes)
240 .map(node -> QName.create(CONTAINER_Q_NAME, node))
241 .collect(Collectors.toSet());
242 return new YangInstanceIdentifier.AugmentationIdentifier(qNames);
245 private static String getLongString() {
246 final StringBuilder builder = new StringBuilder(10000);
247 for (int i = 0; i < 1000; i++) {
248 builder.append("0123456789");
250 return builder.toString();