Switch default stream output to Sodium SR1
[controller.git] / opendaylight / md-sal / sal-clustering-commons / src / test / java / org / opendaylight / controller / cluster / datastore / node / utils / stream / SerializationUtilsTest.java
1 /*
2  * Copyright (c) 2017 Pantheon Technologies s.r.o. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.controller.cluster.datastore.node.utils.stream;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertTrue;
12
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;
22 import java.util.Set;
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.AnyXmlNode;
34 import org.opendaylight.yangtools.yang.data.api.schema.AugmentationNode;
35 import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
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;
48
49 public class SerializationUtilsTest {
50
51     private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
52
53     @Test
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));
59     }
60
61     @Test
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 AnyXmlNode anyXmlNode = Builders.anyXmlBuilder()
67                 .withNodeIdentifier(id("anyXmlNode"))
68                 .withValue(new DOMSource(parse))
69                 .build();
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());
77     }
78
79     @Test
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"))
88                 .build();
89         SerializationUtils.writePath(out, path);
90
91         final byte[] bytes = bos.toByteArray();
92         assertEquals(119, bytes.length);
93
94         final YangInstanceIdentifier deserialized =
95                 SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes)));
96         assertEquals(path, deserialized);
97     }
98
99     @Test
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);
106
107         final byte[] bytes = bos.toByteArray();
108         assertEquals(10566, bytes.length);
109
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);
116         });
117         assertTrue(applierCalled.get());
118     }
119
120     @Test
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"))));
126
127         final ByteArrayOutputStream bos = new ByteArrayOutputStream();
128         final DataOutput out = new DataOutputStream(bos);
129         SerializationUtils.writePath(out, expected);
130
131         final byte[] bytes = bos.toByteArray();
132         assertEquals(37, bytes.length);
133
134         final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes));
135         final YangInstanceIdentifier read = SerializationUtils.readPath(in);
136         assertEquals(expected, read);
137     }
138
139     private static NormalizedNode<?, ?> deserializeNormalizedNode(final byte[] bytes) throws IOException {
140         return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes))).get();
141     }
142
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();
147     }
148
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"))
154                 .build();
155         final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
156                 .withNodeIdentifier(id("orderedLeafSetNode"))
157                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
158                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
159                 .build();
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)
172                 .build();
173         final MapEntryNode entry2 = Builders.mapEntryBuilder()
174                 .withNodeIdentifier(listId("mapNode", "key", "key2"))
175                 .withChild(stringLeaf)
176                 .build();
177         final MapNode mapNode = Builders.mapBuilder()
178                 .withNodeIdentifier(id("mapNode"))
179                 .withChild(entry1)
180                 .withChild(entry2)
181                 .build();
182         final OrderedMapNode orderedMapNode = Builders.orderedMapBuilder()
183                 .withNodeIdentifier(id("orderedMapNode"))
184                 .withChild(entry2)
185                 .withChild(entry1)
186                 .build();
187         final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
188                 .withNodeIdentifier(id("unkeyedList"))
189                 .withChild(stringLeaf)
190                 .build();
191         final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
192                 .withNodeIdentifier(id("unkeyedList"))
193                 .withChild(stringLeaf)
194                 .build();
195         final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
196                 .withNodeIdentifier(id("unkeyedList"))
197                 .withChild(unkeyedListEntry1)
198                 .withChild(unkeyedListEntry2)
199                 .build();
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"))
206                 .build();
207         final ChoiceNode choiceNode = Builders.choiceBuilder()
208                 .withNodeIdentifier(id("choiceNode"))
209                 .withChild(createLeaf("choiceLeaf", 12))
210                 .build();
211         return Builders.containerBuilder()
212                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONTAINER_Q_NAME))
213                 .withChild(booleanLeaf)
214                 .withChild(byteLeaf)
215                 .withChild(shortLeaf)
216                 .withChild(intLeaf)
217                 .withChild(longLeaf)
218                 .withChild(stringLeaf)
219                 .withChild(longStringLeaf)
220                 .withChild(qNameLeaf)
221                 .withChild(idLeaf)
222                 .withChild(mapNode)
223                 .withChild(orderedMapNode)
224                 .withChild(unkeyedListNode)
225                 .withChild(leafSetNode)
226                 .withChild(orderedLeafSetNode)
227                 .withChild(augmentationNode)
228                 .withChild(choiceNode)
229                 .build();
230     }
231
232     private static <T> LeafNode<T> createLeaf(final String name, final T value) {
233         return ImmutableNodes.leafNode(id(name), value);
234     }
235
236     private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
237         return Builders.leafSetEntryBuilder()
238                 .withNodeIdentifier(leafSetId(leafSet, value))
239                 .withValue(value)
240                 .build();
241     }
242
243     private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
244         return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
245     }
246
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);
252     }
253
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);
256     }
257
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);
263     }
264
265     private static String getLongString() {
266         final StringBuilder builder = new StringBuilder(10000);
267         for (int i = 0; i < 1000; i++) {
268             builder.append("0123456789");
269         }
270         return builder.toString();
271     }
272 }