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