Do not use NodeIdentifierWithPredicates constructors
[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, SerializationUtils.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 = SerializationUtils.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.deserializePath(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.deserializePathAndNode(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 byte[] serializeNormalizedNode(final NormalizedNode<?, ?> node) throws IOException {
108         ByteArrayOutputStream bos = new ByteArrayOutputStream();
109         SerializationUtils.writeNormalizedNode(new DataOutputStream(bos), node);
110         return bos.toByteArray();
111     }
112
113     private static NormalizedNode<?, ?> createNormalizedNode() {
114         final LeafSetNode<Object> leafSetNode = Builders.leafSetBuilder()
115                 .withNodeIdentifier(id("leafSetNode"))
116                 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue1"))
117                 .withChild(createLeafSetEntry("leafSetNode", "leafSetValue2"))
118                 .build();
119         final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
120                 .withNodeIdentifier(id("orderedLeafSetNode"))
121                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
122                 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
123                 .build();
124         final LeafNode<Boolean> booleanLeaf = createLeaf("booleanLeaf", true);
125         final LeafNode<Byte> byteLeaf = createLeaf("byteLeaf", (byte) 0);
126         final LeafNode<Short> shortLeaf = createLeaf("shortLeaf", (short) 55);
127         final LeafNode<Integer> intLeaf = createLeaf("intLeaf", 11);
128         final LeafNode<Long> longLeaf = createLeaf("longLeaf", 151515L);
129         final LeafNode<String> stringLeaf = createLeaf("stringLeaf", "stringValue");
130         final LeafNode<String> longStringLeaf = createLeaf("longStringLeaf", getLongString());
131         final LeafNode<QName> qNameLeaf = createLeaf("stringLeaf", QName.create("base", "qName"));
132         final LeafNode<YangInstanceIdentifier> idLeaf = createLeaf("stringLeaf", YangInstanceIdentifier.EMPTY);
133         final MapEntryNode entry1 = Builders.mapEntryBuilder()
134                 .withNodeIdentifier(listId("mapNode", "key", "key1"))
135                 .withChild(stringLeaf)
136                 .build();
137         final MapEntryNode entry2 = Builders.mapEntryBuilder()
138                 .withNodeIdentifier(listId("mapNode", "key", "key2"))
139                 .withChild(stringLeaf)
140                 .build();
141         final MapNode mapNode = Builders.mapBuilder()
142                 .withNodeIdentifier(id("mapNode"))
143                 .withChild(entry1)
144                 .withChild(entry2)
145                 .build();
146         final OrderedMapNode orderedMapNode = Builders.orderedMapBuilder()
147                 .withNodeIdentifier(id("orderedMapNode"))
148                 .withChild(entry2)
149                 .withChild(entry1)
150                 .build();
151         final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
152                 .withNodeIdentifier(id("unkeyedList"))
153                 .withChild(stringLeaf)
154                 .build();
155         final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
156                 .withNodeIdentifier(id("unkeyedList"))
157                 .withChild(stringLeaf)
158                 .build();
159         final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
160                 .withNodeIdentifier(id("unkeyedList"))
161                 .withChild(unkeyedListEntry1)
162                 .withChild(unkeyedListEntry2)
163                 .build();
164         final ImmutableSet<QName> childNames =
165                 ImmutableSet.of(QName.create(CONTAINER_Q_NAME, "aug1"), QName.create(CONTAINER_Q_NAME, "aug1"));
166         final AugmentationNode augmentationNode = Builders.augmentationBuilder()
167                 .withNodeIdentifier(new YangInstanceIdentifier.AugmentationIdentifier(childNames))
168                 .withChild(createLeaf("aug1", "aug1Value"))
169                 .withChild(createLeaf("aug2", "aug2Value"))
170                 .build();
171         final ChoiceNode choiceNode = Builders.choiceBuilder()
172                 .withNodeIdentifier(id("choiceNode"))
173                 .withChild(createLeaf("choiceLeaf", 12))
174                 .build();
175         return Builders.containerBuilder()
176                 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONTAINER_Q_NAME))
177                 .withChild(booleanLeaf)
178                 .withChild(byteLeaf)
179                 .withChild(shortLeaf)
180                 .withChild(intLeaf)
181                 .withChild(longLeaf)
182                 .withChild(stringLeaf)
183                 .withChild(longStringLeaf)
184                 .withChild(qNameLeaf)
185                 .withChild(idLeaf)
186                 .withChild(mapNode)
187                 .withChild(orderedMapNode)
188                 .withChild(unkeyedListNode)
189                 .withChild(leafSetNode)
190                 .withChild(orderedLeafSetNode)
191                 .withChild(augmentationNode)
192                 .withChild(choiceNode)
193                 .build();
194     }
195
196     private static <T> LeafNode<T> createLeaf(final String name, final T value) {
197         return ImmutableNodes.leafNode(id(name), value);
198     }
199
200     private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
201         return Builders.leafSetEntryBuilder()
202                 .withNodeIdentifier(leafSetId(leafSet, value))
203                 .withValue(value)
204                 .build();
205     }
206
207     private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
208         return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
209     }
210
211     private static YangInstanceIdentifier.NodeIdentifierWithPredicates listId(final String listName,
212                                                                               final String keyName,
213                                                                               final Object keyValue) {
214         return YangInstanceIdentifier.NodeIdentifierWithPredicates.of(QName.create(CONTAINER_Q_NAME, listName),
215                 QName.create(CONTAINER_Q_NAME, keyName), keyValue);
216     }
217
218     private static <T> YangInstanceIdentifier.NodeWithValue<T> leafSetId(final String node, final T value) {
219         return new YangInstanceIdentifier.NodeWithValue<>(QName.create(CONTAINER_Q_NAME, node), value);
220     }
221
222     private static YangInstanceIdentifier.AugmentationIdentifier autmentationId(final String... nodes) {
223         final Set<QName> qNames = Arrays.stream(nodes)
224                 .map(node -> QName.create(CONTAINER_Q_NAME, node))
225                 .collect(Collectors.toSet());
226         return new YangInstanceIdentifier.AugmentationIdentifier(qNames);
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 }