14aa7f42f502b79969de9fd0672f49350e99286a
[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 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;
44
45 public class SerializationUtilsTest {
46
47     private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
48
49     @Test
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));
55     }
56
57     @Test
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))
65                 .build();
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());
73     }
74
75     @Test
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"))
83                 .build();
84         SerializationUtils.writePath(out, path);
85
86         final byte[] bytes = bos.toByteArray();
87         assertEquals(105, bytes.length);
88
89         final YangInstanceIdentifier deserialized =
90                 SerializationUtils.readPath(new DataInputStream(new ByteArrayInputStream(bytes)));
91         assertEquals(path, deserialized);
92     }
93
94     @Test
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);
101
102         final byte[] bytes = bos.toByteArray();
103         assertEquals(10558, bytes.length);
104
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);
111         });
112         assertTrue(applierCalled.get());
113     }
114
115     private static NormalizedNode deserializeNormalizedNode(final byte[] bytes) throws IOException {
116         return SerializationUtils.readNormalizedNode(new DataInputStream(new ByteArrayInputStream(bytes)))
117             .orElseThrow();
118     }
119
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();
124     }
125
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"))
131                 .build();
132         final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
133                 .withNodeIdentifier(id("orderedLeafSetNode"))
134                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
135                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
136                 .build();
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)
149                 .build();
150         final MapEntryNode entry2 = Builders.mapEntryBuilder()
151                 .withNodeIdentifier(listId("mapNode", "key", "key2"))
152                 .withChild(stringLeaf)
153                 .build();
154         final MapNode mapNode = Builders.mapBuilder()
155                 .withNodeIdentifier(id("mapNode"))
156                 .withChild(entry1)
157                 .withChild(entry2)
158                 .build();
159         final UserMapNode orderedMapNode = Builders.orderedMapBuilder()
160                 .withNodeIdentifier(id("orderedMapNode"))
161                 .withChild(entry2)
162                 .withChild(entry1)
163                 .build();
164         final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
165                 .withNodeIdentifier(id("unkeyedList"))
166                 .withChild(stringLeaf)
167                 .build();
168         final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
169                 .withNodeIdentifier(id("unkeyedList"))
170                 .withChild(stringLeaf)
171                 .build();
172         final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
173                 .withNodeIdentifier(id("unkeyedList"))
174                 .withChild(unkeyedListEntry1)
175                 .withChild(unkeyedListEntry2)
176                 .build();
177         final ChoiceNode choiceNode = Builders.choiceBuilder()
178                 .withNodeIdentifier(id("choiceNode"))
179                 .withChild(createLeaf("choiceLeaf", 12))
180                 .build();
181         return Builders.containerBuilder()
182                 .withNodeIdentifier(new NodeIdentifier(CONTAINER_Q_NAME))
183                 .withChild(booleanLeaf)
184                 .withChild(byteLeaf)
185                 .withChild(shortLeaf)
186                 .withChild(intLeaf)
187                 .withChild(longLeaf)
188                 .withChild(stringLeaf)
189                 .withChild(longStringLeaf)
190                 .withChild(qNameLeaf)
191                 .withChild(idLeaf)
192                 .withChild(mapNode)
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)
200                 .build();
201     }
202
203     private static <T> LeafNode<T> createLeaf(final String name, final T value) {
204         return ImmutableNodes.leafNode(id(name), value);
205     }
206
207     private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
208         return Builders.leafSetEntryBuilder()
209                 .withNodeIdentifier(leafSetId(leafSet, value))
210                 .withValue(value)
211                 .build();
212     }
213
214     private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
215         return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
216     }
217
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);
223     }
224
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);
227     }
228
229     private static String getLongString() {
230         final StringBuilder builder = new StringBuilder(10000);
231         for (int i = 0; i < 1000; i++) {
232             builder.append("0123456789");
233         }
234         return builder.toString();
235     }
236 }