blob: 5bf8ce6ae1567856b58e10706fb3e2e9cdc87a32 [file] [log] [blame]
jingane308fc12017-03-03 01:47:31 -08001/*
Brian O'Connor72b2df22017-08-03 18:48:28 -07002 * Copyright 2017-present Open Networking Foundation
jingane308fc12017-03-03 01:47:31 -08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.yang.serializers.json;
18
jingan8396f222017-03-20 23:00:25 -070019import com.fasterxml.jackson.databind.ObjectMapper;
20import com.fasterxml.jackson.databind.node.ObjectNode;
jingane308fc12017-03-03 01:47:31 -080021import org.apache.commons.io.IOUtils;
22import org.junit.BeforeClass;
janani be3c59be2017-12-19 19:33:49 +053023import org.junit.Rule;
jingane308fc12017-03-03 01:47:31 -080024import org.junit.Test;
janani be3c59be2017-12-19 19:33:49 +053025import org.junit.rules.ExpectedException;
jingane308fc12017-03-03 01:47:31 -080026import org.onosproject.yang.model.DataNode;
Gaurav Agrawald829db32017-05-13 15:39:16 +053027import org.onosproject.yang.model.DefaultResourceData;
jingane308fc12017-03-03 01:47:31 -080028import org.onosproject.yang.model.NodeKey;
29import org.onosproject.yang.model.ResourceData;
jingan8396f222017-03-20 23:00:25 -070030import org.onosproject.yang.model.ResourceId;
jingane308fc12017-03-03 01:47:31 -080031import org.onosproject.yang.model.SchemaId;
32import org.onosproject.yang.runtime.CompositeData;
33import org.onosproject.yang.runtime.CompositeStream;
jingan8396f222017-03-20 23:00:25 -070034import org.onosproject.yang.runtime.DefaultCompositeData;
jingane308fc12017-03-03 01:47:31 -080035import org.onosproject.yang.runtime.DefaultCompositeStream;
jingan8396f222017-03-20 23:00:25 -070036import org.onosproject.yang.runtime.DefaultRuntimeContext;
37import org.onosproject.yang.runtime.RuntimeContext;
jingane308fc12017-03-03 01:47:31 -080038import org.onosproject.yang.runtime.YangSerializer;
39import org.onosproject.yang.runtime.YangSerializerContext;
Andrea Campanella9a1a7c12018-11-23 14:30:49 +010040import org.slf4j.Logger;
jingane308fc12017-03-03 01:47:31 -080041
42import java.io.BufferedReader;
43import java.io.FileReader;
44import java.io.IOException;
45import java.io.InputStream;
46import java.io.InputStreamReader;
47import java.util.ArrayList;
48import java.util.Collection;
49import java.util.List;
50import java.util.Map;
51import java.util.Set;
52
Vidyashree Rama68dcfa52017-06-09 13:30:46 +053053import static org.hamcrest.MatcherAssert.assertThat;
54import static org.hamcrest.core.Is.is;
jingane308fc12017-03-03 01:47:31 -080055import static org.junit.Assert.assertEquals;
Andrea Campanella3769a332018-12-19 17:26:48 +010056import static org.junit.Assert.assertNotNull;
Vidyashree Rama68dcfa52017-06-09 13:30:46 +053057import static org.onosproject.yang.serializers.utils.SerializersUtil.convertRidToUri;
Andrea Campanella9a1a7c12018-11-23 14:30:49 +010058import static org.slf4j.LoggerFactory.getLogger;
jingane308fc12017-03-03 01:47:31 -080059
60/**
61 * Unit Test for Json Serializer.
62 */
63public class JsonSerializerTest {
jingane308fc12017-03-03 01:47:31 -080064
Andrea Campanella9a1a7c12018-11-23 14:30:49 +010065 private static final Logger log = getLogger(JsonSerializerTest.class);
66
jingane308fc12017-03-03 01:47:31 -080067 private static YangSerializerContext context;
68 private static YangSerializer jsonSerializer;
69
Andrea Campanella3769a332018-12-19 17:26:48 +010070 private static String outputIdTestJson = "{\"identity-test:con1\":" +
71 "{\"interface\":\"identity-types:physical\",\"interfaces\":" +
72 "{\"int-list\":[{\"available\":{\"ll\":[\"identity-types:Loopback\"," +
73 "\"identity-test:Giga\",\"identity-types-second:Ethernet\"]}," +
74 "\"iden\":\"identity-types-second:virtual\"},{\"available\":{" +
75 "\"ll\":[\"Giga\"]},\"iden\":\"optical\"}]}}}";
janani be3c59be2017-12-19 19:33:49 +053076
Andrea Campanella3769a332018-12-19 17:26:48 +010077 private static String outputIdTestJson1 = "{\"jsonlist:c2\":{\"leaf1\":1,\"" +
78 "leaf10\":\"-922337203685477580.8\",\"leaf2\":2,\"leaf3\":3," +
Vidyashree-Huawei65b9d172019-04-03 10:36:38 +000079 "\"leaf4\":4,\"leaf5\":5,\"leaf6\":6,\"leaf7\":\"7\"," +
80 "\"leaf8\":\"8\",\"leaf9\":true,\"leaflist1\":[\"a\",\"b\",\"c\"]," +
Andrea Campanella3769a332018-12-19 17:26:48 +010081 "\"ll1\":[1,10],\"ll10\":[\"-922337203685477580.8\",\"-922337203685477480.8\"]," +
82 "\"ll2\":[2,20],\"ll3\":[3,30],\"ll4\":[4,40],\"ll5\":[5,50],\"ll6\":[6,60]," +
Vidyashree-Huawei65b9d172019-04-03 10:36:38 +000083 "\"ll7\":[\"7\",\"70\"],\"ll8\":[\"8\",\"80\"],\"ll9\":[true,false]}}";
janani be3c59be2017-12-19 19:33:49 +053084 @Rule
85 public ExpectedException thrown = ExpectedException.none();
86
jingan8396f222017-03-20 23:00:25 -070087 @Test
Gaurav Agrawalef3068c2017-05-17 18:00:10 +053088 public void demo1Test() throws IOException {
jingan8396f222017-03-20 23:00:25 -070089 String path = "src/test/resources/test.json";
90 // decode
91 DefaultCompositeStream external =
92 new DefaultCompositeStream("demo1:device", parseInput(path));
93 CompositeData compositeData = jsonSerializer.decode(external, context);
94 ResourceData resourceData = compositeData.resourceData();
95 ResourceId rid = resourceData.resourceId();
96 DataNode rootNode = resourceData.dataNodes().get(0);
97
98 // encode
99 RuntimeContext.Builder runtimeContextBuilder = DefaultRuntimeContext.builder();
100 runtimeContextBuilder.setDataFormat("JSON");
101 DefaultResourceData.Builder resourceDataBuilder = DefaultResourceData.builder();
102 resourceDataBuilder.addDataNode(rootNode);
103 resourceDataBuilder.resourceId(rid);
104
105 ResourceData resourceDataOutput = resourceDataBuilder.build();
106 DefaultCompositeData.Builder compositeDataBuilder = DefaultCompositeData.builder();
107 compositeDataBuilder.resourceData(resourceDataOutput);
108 CompositeData compositeData1 = compositeDataBuilder.build();
109 // CompositeData --- YangRuntimeService ---> CompositeStream.
110 CompositeStream compositeStreamOutPut = jsonSerializer.encode(compositeData1,
111 context);
112 InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
113 ObjectNode rootNodeOutput;
114 ObjectMapper mapper = new ObjectMapper();
Andrea Campanella3769a332018-12-19 17:26:48 +0100115 rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
116 assertNotNull(rootNodeOutput);
jingan8396f222017-03-20 23:00:25 -0700117 }
118
Vidyashree Rama68dcfa52017-06-09 13:30:46 +0530119 @Test
Gaurav Agrawal7ff0e252018-11-15 17:28:38 +0530120 public void colonTest() throws IOException {
121 String path = "src/test/resources/colontest.json";
122 // decode
123 DefaultCompositeStream external =
124 new DefaultCompositeStream("demo1:device", parseInput(path));
125 CompositeData compositeData = jsonSerializer.decode(external, context);
126 ResourceData resourceData = compositeData.resourceData();
127 ResourceId rid = resourceData.resourceId();
128 DataNode rootNode = resourceData.dataNodes().get(0);
129
130 // encode
131 RuntimeContext.Builder runtimeContextBuilder = DefaultRuntimeContext.builder();
132 runtimeContextBuilder.setDataFormat("JSON");
133 DefaultResourceData.Builder resourceDataBuilder = DefaultResourceData.builder();
134 resourceDataBuilder.addDataNode(rootNode);
135 resourceDataBuilder.resourceId(rid);
136
137 ResourceData resourceDataOutput = resourceDataBuilder.build();
138 DefaultCompositeData.Builder compositeDataBuilder = DefaultCompositeData.builder();
139 compositeDataBuilder.resourceData(resourceDataOutput);
140 CompositeData compositeData1 = compositeDataBuilder.build();
141 // CompositeData --- YangRuntimeService ---> CompositeStream.
142 CompositeStream compositeStreamOutPut = jsonSerializer.encode(compositeData1,
143 context);
144 InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
145 ObjectNode rootNodeOutput;
146 ObjectMapper mapper = new ObjectMapper();
Andrea Campanella3769a332018-12-19 17:26:48 +0100147 rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
148 assertNotNull(rootNodeOutput);
Gaurav Agrawal7ff0e252018-11-15 17:28:38 +0530149 }
150
151 @Test
sonugupta-huawei101310f2018-01-04 10:26:22 +0530152 public void jsonListTest() throws IOException {
153 String path = "src/test/resources/testinput1.json";
154 // decode
155 DefaultCompositeStream external =
156 new DefaultCompositeStream("jsonlist:top1", parseInput(path));
157 CompositeData compositeData = jsonSerializer.decode(external, context);
158 ResourceData resourceData = compositeData.resourceData();
159 ResourceId rid = resourceData.resourceId();
160 DataNode rootNode = resourceData.dataNodes().get(0);
161
162 // encode
163 RuntimeContext.Builder runtimeContextBuilder = DefaultRuntimeContext.builder();
164 runtimeContextBuilder.setDataFormat("JSON");
165 DefaultResourceData.Builder resourceDataBuilder = DefaultResourceData.builder();
166 resourceDataBuilder.addDataNode(rootNode);
167 resourceDataBuilder.resourceId(rid);
168
169 ResourceData resourceDataOutput = resourceDataBuilder.build();
170 DefaultCompositeData.Builder compositeDataBuilder = DefaultCompositeData.builder();
171 compositeDataBuilder.resourceData(resourceDataOutput);
172 CompositeData compositeData1 = compositeDataBuilder.build();
173 // CompositeData --- YangRuntimeService ---> CompositeStream.
174 CompositeStream compositeStreamOutPut = jsonSerializer.encode(compositeData1,
175 context);
176 InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
177 ObjectNode rootNodeOutput;
178 ObjectMapper mapper = new ObjectMapper();
Andrea Campanella3769a332018-12-19 17:26:48 +0100179 rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
180 assertEquals(rootNodeOutput.toString(), outputIdTestJson1);
sonugupta-huawei101310f2018-01-04 10:26:22 +0530181 }
182
183 @Test
janani be3c59be2017-12-19 19:33:49 +0530184 public void identityValueNsTest() throws IOException {
185 String path = "src/test/resources/id-test1.json";
186 // decode
187 DefaultCompositeStream external =
188 new DefaultCompositeStream("identity-test:test", parseInput(path));
189 CompositeData compositeData = jsonSerializer.decode(external, context);
190 ResourceData resourceData = compositeData.resourceData();
191 ResourceId rid = resourceData.resourceId();
192 DataNode rootNode = resourceData.dataNodes().get(0);
193
194 // encode
195 RuntimeContext.Builder runtimeContextBuilder = DefaultRuntimeContext.builder();
196 runtimeContextBuilder.setDataFormat("JSON");
197 DefaultResourceData.Builder resourceDataBuilder = DefaultResourceData.builder();
198 resourceDataBuilder.addDataNode(rootNode);
199 resourceDataBuilder.resourceId(rid);
200
201 ResourceData resourceDataOutput = resourceDataBuilder.build();
202 DefaultCompositeData.Builder compositeDataBuilder = DefaultCompositeData.builder();
203 compositeDataBuilder.resourceData(resourceDataOutput);
204 CompositeData compositeData1 = compositeDataBuilder.build();
205 // CompositeData --- YangRuntimeService ---> CompositeStream.
206 CompositeStream compositeStreamOutPut = jsonSerializer.encode(compositeData1,
207 context);
208 InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
209 ObjectNode rootNodeOutput;
210 ObjectMapper mapper = new ObjectMapper();
Andrea Campanella3769a332018-12-19 17:26:48 +0100211 rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
212 assertEquals(rootNodeOutput.toString(), outputIdTestJson);
janani be3c59be2017-12-19 19:33:49 +0530213 }
214
215 @Test
Andrea Campanella3769a332018-12-19 17:26:48 +0100216 public void identityValueNsErrorTest() {
janani be3c59be2017-12-19 19:33:49 +0530217 thrown.expect(IllegalArgumentException.class);
218 thrown.expectMessage("Invalid input for value namespace");
219 String path = "src/test/resources/id-test2.json";
220 DefaultCompositeStream external =
221 new DefaultCompositeStream("identity-test:test", parseInput(path));
222 jsonSerializer.decode(external, context);
223 }
224
225 @Test
Vidyashree Rama68dcfa52017-06-09 13:30:46 +0530226 public void testContainerInResourceIdToUri() {
227 ResourceId rid = ResourceId.builder().addBranchPointSchema("/", null)
228 .addBranchPointSchema("device", "namespace1")
229 .addBranchPointSchema("device", "namespace1")
230 .addKeyLeaf("deviceid", "namespace1", "val").build();
231 String uriString = convertRidToUri(rid, context);
232 assertThat(uriString, is("demo1:device/device=val"));
233 rid = ResourceId.builder().addBranchPointSchema("/", null)
234 .addBranchPointSchema("device", "namespace1")
235 .addBranchPointSchema("Purchasing-supervisor", "namespace1")
236 .addBranchPointSchema("cont7", "namespace1").build();
237 uriString = convertRidToUri(rid, context);
238 assertThat(uriString, is("demo1:device/Purchasing-supervisor/cont7"));
239 }
240
241 @Test
242 public void testListInResourceIdToUri() {
243 ResourceId rid = ResourceId.builder().addBranchPointSchema("/", null)
244 .addBranchPointSchema("list1", "namespace1")
245 .addKeyLeaf("leaf1", "namespace1", "val")
246 .build();
247 String uriString = convertRidToUri(rid, context);
248 assertThat(uriString, is("demo1:list1=val"));
249 }
250
jingane308fc12017-03-03 01:47:31 -0800251 /**
Gaurav Agrawalef3068c2017-05-17 18:00:10 +0530252 * Converts name and name space to NodeKey.
253 *
254 * @param name name
255 * @param nameSpace name space
256 * @return NodeKey
257 */
258 private NodeKey convertNameStringToNodeKey(String name, String nameSpace) {
259 SchemaId schemaId = new SchemaId("top1", "jsonlist");
260 NodeKey.NodeKeyBuilder nodeKeyBuilder =
261 new NodeKey.NodeKeyBuilder<>().schemaId(schemaId);
262 NodeKey nodeKey = nodeKeyBuilder.build();
263 return nodeKey;
264 }
265
266 /**
267 * Obtain a list of NodeKey from Map container.
268 *
269 * @param nodeChils Map container of InnerNode
270 * @return List<NodeKey> list of nodeChils' key
271 */
272 private List<NodeKey> listNodeChildsKey(Map<NodeKey, DataNode> nodeChils) {
273 Set<NodeKey> set = nodeChils.keySet();
274 List<NodeKey> list = new ArrayList<>();
275 list.addAll(set);
276 return list;
277 }
278
279 /**
280 * Obtain a list of DataNode from Map container.
281 *
282 * @param nodeChils Map container of InnerNode
283 * @return List<NodeKey> list of nodeChils' value
284 */
285 private List<DataNode> listNodeChildsValue(Map<NodeKey, DataNode> nodeChils) {
286 Collection<DataNode> coll = nodeChils.values();
287 List<DataNode> list = new ArrayList(coll);
288 return list;
289 }
290
291 /**
292 * Obtain the DataNode for Map with specific name.
293 *
294 * @param nodeChils Map container of InnerNode
295 * @param keyName name of the DataNode which also shown in Json File.
296 * @return DataNode
297 */
298 private DataNode getDataNode(Map<NodeKey, DataNode> nodeChils, String keyName) {
299 List<DataNode> top1DataNodeList = listNodeChildsValue(nodeChils);
300 DataNode l1DataNode = null;
301 for (DataNode node : top1DataNodeList) {
302 String actualName = String.valueOf(node.key().schemaId().name());
303 String expectName = String.valueOf(keyName);
304 if (actualName.equals(expectName)) {
305 l1DataNode = node;
306 break;
307 }
308 }
309 return l1DataNode;
310 }
311
312 @BeforeClass
313 public static void prepare() {
314 context = new MockYangSerializerContext();
315 jsonSerializer = new JsonSerializer();
316 }
317
318 /**
jingane308fc12017-03-03 01:47:31 -0800319 * Reads JSON contents from file path and returns input stream.
320 *
321 * @param path path of JSON file
322 * @return input stream
323 */
324 private static InputStream parseInput(String path) {
325 String temp;
326 StringBuilder sb = new StringBuilder();
327 try (BufferedReader br = new BufferedReader(new FileReader(path))) {
328 while ((temp = br.readLine()) != null) {
329 temp = removeSpace(temp);
330 sb.append(temp);
331 }
332 } catch (IOException e) {
Andrea Campanella9a1a7c12018-11-23 14:30:49 +0100333 log.error("Error in processing the path {}", path, e);
jingane308fc12017-03-03 01:47:31 -0800334 }
335 return IOUtils.toInputStream(sb);
336 }
337
338 /**
339 * Reads JSON contents from file path and returns input stream.
340 *
341 * @param path path of JSON file
342 * @return json string
343 */
344 private static String parseJsonToString(String path) {
345 String temp;
346 StringBuilder sb = new StringBuilder();
347 try (BufferedReader br = new BufferedReader(new FileReader(path))) {
348 while ((temp = br.readLine()) != null) {
349 temp = removeSpaceChangeName(temp);
350 sb.append(temp);
351 }
352 } catch (IOException e) {
Andrea Campanella9a1a7c12018-11-23 14:30:49 +0100353 log.error("Error in processing the path {}", path, e);
jingane308fc12017-03-03 01:47:31 -0800354 }
355 return sb.toString();
356 }
357
358 /**
359 * While traversing a String line first remove all the white space.
360 *
361 * @param line a line of Json file.
362 * @return String modified line
363 */
364 private static String removeSpace(String line) {
365 if (line.length() == 0) {
366 return line;
367 }
368 StringBuilder sb = new StringBuilder();
369 for (int i = 0; i < line.length(); i++) {
370 if (line.charAt(i) != ' ') {
371 sb.append(line.charAt(i));
372 }
373 }
374 return sb.toString();
375 }
376
377 /**
378 * While traversing a String line
379 * first remove all the white space.
380 * second if the json attribute's name has no namespace, add it on.
381 *
382 * @param line a line of Json file.
383 * @return String modified line
384 */
385 private static String removeSpaceChangeName(String line) {
386 if (line.length() == 0) {
387 return line;
388 }
389 StringBuilder sb = new StringBuilder();
390 int count = 0;
391 for (int i = 0; i < line.length(); i++) {
392 if (line.charAt(i) == ' ') {
393 count++;
394 continue;
395 }
396 if (line.charAt(i) == '"') {
397 sb.append(line.charAt(i));
398 if (count > 4) {
399 sb.append("jsonlist:");
400 count = 0;
401 }
402 i++;
403 int start = i;
404 while (line.charAt(i) != '"') {
405 i++;
406 }
407 int end = i;
408 for (int j = start; j < end; j++) {
409 sb.append(line.charAt(j));
410 }
411 }
412 sb.append(line.charAt(i));
413 }
414 return sb.toString();
415 }
416
417 /**
jingane308fc12017-03-03 01:47:31 -0800418 * Converts input stream to string format.
419 *
420 * @param inputStream input stream of xml
421 * @return JSON string
422 */
423 private static String convertInputStreamToString(InputStream inputStream) {
424 BufferedReader br;
425 StringBuilder sb = new StringBuilder();
426 String xmlData;
427 br = new BufferedReader(new InputStreamReader(inputStream));
428 try {
429 while ((xmlData = br.readLine()) != null) {
430 sb.append(xmlData);
431 }
432 } catch (IOException e) {
433 throw new SerializerException(e.getMessage());
434 }
435 return sb.toString();
436 }
437}