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 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;
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;
46 public class SerializationUtilsTest {
48 private static final QName CONTAINER_Q_NAME = QName.create("ns-1", "2017-03-17", "container1");
51 public void testSerializeDeserializeNodes() throws IOException {
52 final NormalizedNode<?, ?> normalizedNode = createNormalizedNode();
53 final byte[] bytes = serializeNormalizedNode(normalizedNode);
54 Assert.assertEquals(normalizedNode, SerializationUtils.deserializeNormalizedNode(bytes));
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))
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());
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"))
84 SerializationUtils.writePath(out, path);
85 final YangInstanceIdentifier deserialized =
86 SerializationUtils.deserializePath(new DataInputStream(new ByteArrayInputStream(bos.toByteArray())));
87 Assert.assertEquals(path, deserialized);
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);
104 Assert.assertTrue(applierCalled.get());
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();
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"))
119 final LeafSetNode<Object> orderedLeafSetNode = Builders.orderedLeafSetBuilder()
120 .withNodeIdentifier(id("orderedLeafSetNode"))
121 .withChild(createLeafSetEntry("orderedLeafSetNode", "value1"))
122 .withChild(createLeafSetEntry("orderedLeafSetNode", "value2"))
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)
137 final MapEntryNode entry2 = Builders.mapEntryBuilder()
138 .withNodeIdentifier(listId("mapNode", "key", "key2"))
139 .withChild(stringLeaf)
141 final MapNode mapNode = Builders.mapBuilder()
142 .withNodeIdentifier(id("mapNode"))
146 final OrderedMapNode orderedMapNode = Builders.orderedMapBuilder()
147 .withNodeIdentifier(id("orderedMapNode"))
151 final UnkeyedListEntryNode unkeyedListEntry1 = Builders.unkeyedListEntryBuilder()
152 .withNodeIdentifier(id("unkeyedList"))
153 .withChild(stringLeaf)
155 final UnkeyedListEntryNode unkeyedListEntry2 = Builders.unkeyedListEntryBuilder()
156 .withNodeIdentifier(id("unkeyedList"))
157 .withChild(stringLeaf)
159 final UnkeyedListNode unkeyedListNode = Builders.unkeyedListBuilder()
160 .withNodeIdentifier(id("unkeyedList"))
161 .withChild(unkeyedListEntry1)
162 .withChild(unkeyedListEntry2)
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"))
171 final ChoiceNode choiceNode = Builders.choiceBuilder()
172 .withNodeIdentifier(id("choiceNode"))
173 .withChild(createLeaf("choiceLeaf", 12))
175 return Builders.containerBuilder()
176 .withNodeIdentifier(new YangInstanceIdentifier.NodeIdentifier(CONTAINER_Q_NAME))
177 .withChild(booleanLeaf)
179 .withChild(shortLeaf)
182 .withChild(stringLeaf)
183 .withChild(longStringLeaf)
184 .withChild(qNameLeaf)
187 .withChild(orderedMapNode)
188 .withChild(unkeyedListNode)
189 .withChild(leafSetNode)
190 .withChild(orderedLeafSetNode)
191 .withChild(augmentationNode)
192 .withChild(choiceNode)
196 private static <T> LeafNode<T> createLeaf(final String name, final T value) {
197 return ImmutableNodes.leafNode(id(name), value);
200 private static LeafSetEntryNode<Object> createLeafSetEntry(final String leafSet, final String value) {
201 return Builders.leafSetEntryBuilder()
202 .withNodeIdentifier(leafSetId(leafSet, value))
207 private static YangInstanceIdentifier.NodeIdentifier id(final String name) {
208 return new YangInstanceIdentifier.NodeIdentifier(QName.create(CONTAINER_Q_NAME, name));
211 private static YangInstanceIdentifier.NodeIdentifierWithPredicates listId(final String listName,
212 final String keyName,
213 final Object keyValue) {
214 return new YangInstanceIdentifier.NodeIdentifierWithPredicates(QName.create(CONTAINER_Q_NAME, listName),
215 QName.create(CONTAINER_Q_NAME, keyName), keyValue);
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);
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);
229 private static String getLongString() {
230 final StringBuilder builder = new StringBuilder(10000);
231 for (int i = 0; i < 1000; i++) {
232 builder.append("0123456789");
234 return builder.toString();