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.YangInstanceIdentifier.AugmentationIdentifier;
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.DOMSourceAnyxmlNode;
36 import org.opendaylight.yangtools.yang.data.api.schema.LeafNode;
37 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
38 import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
39 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.MapNode;
41 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.OrderedMapNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
44 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
45 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
46 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
47 import org.w3c.dom.Document;
49 public class SerializationUtilsTest {
51 private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
54 public void testSerializeDeserializeNodes() throws IOException {
55 final NormalizedNode<?, ?> normalizedNode = createNormalizedNode();
56 final byte[] bytes = serializeNormalizedNode(normalizedNode);
57 assertEquals(10564, bytes.length);
58 assertEquals(normalizedNode, deserializeNormalizedNode(bytes));
62 public void testSerializeDeserializeAnyXmlNode() throws Exception {
63 final ByteArrayInputStream is =
64 new ByteArrayInputStream("<xml><data/></xml>".getBytes(Charset.defaultCharset()));
65 final Document parse = UntrustedXML.newDocumentBuilder().parse(is);
66 final DOMSourceAnyxmlNode anyXmlNode = Builders.anyXmlBuilder()
67 .withNodeIdentifier(id("anyXmlNode"))
68 .withValue(new DOMSource(parse))
70 final byte[] bytes = serializeNormalizedNode(anyXmlNode);
71 assertEquals(113, bytes.length);
72 final NormalizedNode<?, ?> deserialized = deserializeNormalizedNode(bytes);
73 final DOMSource value = (DOMSource) deserialized.getValue();
74 final Diff diff = XMLUnit.compareXML((Document) anyXmlNode.getValue().getNode(),
75 value.getNode().getOwnerDocument());
76 assertTrue(diff.toString(), diff.similar());
80 public void testSerializeDeserializePath() throws IOException {
81 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
82 final DataOutput out = new DataOutputStream(bos);
83 final YangInstanceIdentifier path = YangInstanceIdentifier.builder()
84 .node(id("container1"))
85 .node(autmentationId("list1", "list2"))
86 .node(listId("list1", "keyName1", "keyValue1"))
87 .node(leafSetId("leafSer1", "leafSetValue1"))
89 SerializationUtils.writePath(out, path);
91 final byte[] bytes = bos.toByteArray();
92 assertEquals(119, bytes.length);
94 final YangInstanceIdentifier deserialized =
95 SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes)));
96 assertEquals(path, deserialized);
100 public void testSerializeDeserializePathAndNode() throws IOException {
101 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
102 final DataOutput out = new DataOutputStream(bos);
103 final NormalizedNode<?, ?> node = createNormalizedNode();
104 final YangInstanceIdentifier path = YangInstanceIdentifier.create(id("container1"));
105 SerializationUtils.writeNodeAndPath(out, path, node);
107 final byte[] bytes = bos.toByteArray();
108 assertEquals(10566, bytes.length);
110 final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
111 final AtomicBoolean applierCalled = new AtomicBoolean(false);
112 SerializationUtils.readNodeAndPath(in, applierCalled, (instance, deserializedPath, deserializedNode) -> {
113 assertEquals(path, deserializedPath);
114 assertEquals(node, deserializedNode);
115 applierCalled.set(true);
117 assertTrue(applierCalled.get());
121 public void testSerializeDeserializeAugmentNoref() throws IOException {
122 final YangInstanceIdentifier expected = YangInstanceIdentifier.create(
123 AugmentationIdentifier.create(ImmutableSet.of(
124 QName.create("foo", "leaf1"),
125 QName.create("bar", "leaf2"))));
127 final ByteArrayOutputStream bos = new ByteArrayOutputStream();
128 final DataOutput out = new DataOutputStream(bos);
129 SerializationUtils.writePath(out, expected);
131 final byte[] bytes = bos.toByteArray();
132 assertEquals(37, bytes.length);
134 final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
135 final YangInstanceIdentifier read = SerializationUtils.readPath(in);
136 assertEquals(expected, read);
139 private static NormalizedNode<?, ?> deserializeNormalizedNode(final byte[] bytes) throws IOException {
140 return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes))).get();
143 private static byte[] serializeNormalizedNode(final NormalizedNode<?, ?> node) throws IOException {
144 ByteArrayOutputStream bos = new ByteArrayOutputStream();
145 SerializationUtils.writeNormalizedNode(new DataOutputStream(bos), node);
146 return bos.toByteArray();
149 private static NormalizedNode<?, ?> createNormalizedNode() {
150 final LeafSetNode<Object> leafSetNode = Builders.leafSetBuilder()
151 .withNodeIdentifier(id("leafSetNode"))
152 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
153 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
155 final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
156 .withNodeIdentifier(id("orderedLeafSetNode"))
157 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
158 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
160 final LeafNode<Boolean> booleanLeaf = createLeaf("booleanLeaf", true);
161 final LeafNode<Byte> byteLeaf = createLeaf("byteLeaf", (byte) 0);
162 final LeafNode<Short> shortLeaf = createLeaf("shortLeaf", (short) 55);
163 final LeafNode<Integer> intLeaf = createLeaf("intLeaf", 11);
164 final LeafNode<Long> longLeaf = createLeaf("longLeaf", 151515L);
165 final LeafNode<String> stringLeaf = createLeaf("stringLeaf", "stringValue");
166 final LeafNode<String> longStringLeaf = createLeaf("longStringLeaf", getLongString());
167 final LeafNode<QName> qNameLeaf = createLeaf("stringLeaf", QName.create("base", "qName"));
168 final LeafNode<YangInstanceIdentifier> idLeaf = createLeaf("stringLeaf", YangInstanceIdentifier.empty());
169 final MapEntryNode entry1 = Builders.mapEntryBuilder()
170 .withNodeIdentifier(listId("mapNode", "key", "key1"))
171 .withChild(stringLeaf)
173 final MapEntryNode entry2 = Builders.mapEntryBuilder()
174 .withNodeIdentifier(listId("mapNode", "key", "key2"))
175 .withChild(stringLeaf)
177 final MapNode mapNode = Builders.mapBuilder()
178 .withNodeIdentifier(id("mapNode"))
182 final OrderedMapNode orderedMapNode = Builders.orderedMapBuilder()
183 .withNodeIdentifier(id("orderedMapNode"))
187 final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
188 .withNodeIdentifier(id("unkeyedList"))
189 .withChild(stringLeaf)
191 final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
192 .withNodeIdentifier(id("unkeyedList"))
193 .withChild(stringLeaf)
195 final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
196 .withNodeIdentifier(id("unkeyedList"))
197 .withChild(unkeyedListEntry1)
198 .withChild(unkeyedListEntry2)
200 final ImmutableSet<QName> childNames =
201 ImmutableSet.of(QName.create(CONTAINER_Q_NAME, "aug1"), QName.create(CONTAINER_Q_NAME, "aug1"));
202 final AugmentationNode augmentationNode = Builders.augmentationBuilder()
203 .withNodeIdentifier(new YangInstanceIdentifier.AugmentationIdentifier(childNames))
204 .withChild(createLeaf("aug1", "aug1Value"))
205 .withChild(createLeaf("aug2", "aug2Value"))
207 final ChoiceNode choiceNode = Builders.choiceBuilder()
208 .withNodeIdentifier(id("choiceNode"))
209 .withChild(createLeaf("choiceLeaf", 12))
211 return Builders.containerBuilder()
212 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONTAINER_Q_NAME))
213 .withChild(booleanLeaf)
215 .withChild(shortLeaf)
218 .withChild(stringLeaf)
219 .withChild(longStringLeaf)
220 .withChild(qNameLeaf)
223 .withChild(orderedMapNode)
224 .withChild(unkeyedListNode)
225 .withChild(leafSetNode)
226 .withChild(orderedLeafSetNode)
227 .withChild(augmentationNode)
228 .withChild(choiceNode)
232 private static <T> LeafNode<T> createLeaf(final String name, final T value) {
233 return ImmutableNodes.leafNode(id(name), value);
236 private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
237 return Builders.leafSetEntryBuilder()
238 .withNodeIdentifier(leafSetId(leafSet, value))
243 private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
244 return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
247 private static YangInstanceIdentifier.NodeIdentifierWithPredicates listId(final String listName,
248 final String keyName,
249 final Object keyValue) {
250 return YangInstanceIdentifier.NodeIdentifierWithPredicates.of(QName.create(CONTAINER_Q_NAME, listName),
251 QName.create(CONTAINER_Q_NAME, keyName), keyValue);
254 private static <T> YangInstanceIdentifier.NodeWithValue<T> leafSetId(final String node, final T value) {
255 return new YangInstanceIdentifier.NodeWithValue<>(QName.create(CONTAINER_Q_NAME, node), value);
258 private static YangInstanceIdentifier.AugmentationIdentifier autmentationId(final String... nodes) {
259 final Set<QName> qNames = Arrays.stream(nodes)
260 .map(node -> QName.create(CONTAINER_Q_NAME, node))
261 .collect(Collectors.toSet());
262 return new YangInstanceIdentifier.AugmentationIdentifier(qNames);
265 private static String getLongString() {
266 final StringBuilder builder = new StringBuilder(10000);
267 for (int i = 0; i < 1000; i++) {
268 builder.append("0123456789");
270 return builder.toString();