[ONOS-7882] Ordering Childs for json serialization to avoid splitting array/list nodes and reading just the bottom portion in the final json node.
Change-Id: Ifc0eafcd9f32c87245efec844610aa640234493f
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
index b58986e..dff37fc 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistry.java
@@ -165,7 +165,7 @@
//update child context
updateChildContext(curNodes);
- log.info("ModelId: {} registered!", id);
+ log.debug("ModelId: {} registered!", id);
}
@Override
@@ -389,7 +389,7 @@
appNode);
}
- log.info("successfully registered this application {}", name);
+ log.debug("successfully registered this application {}", name);
}
/**
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java
index f285f5f..a7d0169 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/EncoderUtils.java
@@ -23,11 +23,13 @@
import org.onosproject.yang.runtime.YangSerializerContext;
import java.util.ArrayList;
-import java.util.Collection;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_LEAF_VALUE_NODE;
@@ -67,9 +69,8 @@
FIRST_INSTANCE : NOT_MULTI_INSTANCE_NODE;
walkDataNodeTree(treeNodeListener, dataNode, siblingType);
- jsonBuilder.finalizeJson((dataNode.type() == MULTI_INSTANCE_NODE) ? true : false);
- ObjectNode resultData = jsonBuilder.getTreeNode();
- return resultData;
+ jsonBuilder.finalizeJson(dataNode.type() == MULTI_INSTANCE_NODE);
+ return jsonBuilder.getTreeNode();
}
private static void walkDataNodeTree(DataNodeVisitor dataNodeVisitor,
@@ -109,18 +110,16 @@
*/
DataNodeSiblingPositionType prevChildType = UNKNOWN_TYPE;
- DataNodeSiblingPositionType currChildType = UNKNOWN_TYPE;
+ DataNodeSiblingPositionType currChildType;
/*
- * Dynamic Config preserves the order of child nodes.
- * So, we no longer need to sort the children.
+ * Dynamic Config does not preserve the order of child nodes.
+ * For cases where an array of objects gets fragmented by an internal key
*/
- //List<DataNode> sortedChildList = sortChildrenList(childrenList);
- //checkNotNull(sortedChildList, "sorted children list cannot be null");
- Collection<DataNode> dataNodeList = childrenList.values();
- Iterator<DataNode> it = dataNodeList.iterator();
+ List<DataNode> sortedChildList = sortChildrenList(childrenList);
+ Iterator<DataNode> it = sortedChildList.iterator();
DataNode currChild = it.next();
- DataNode nextChild = null;
+ DataNode nextChild;
boolean lastChildNotProcessed = true;
while (lastChildNotProcessed) {
/*
@@ -197,35 +196,23 @@
return curChildSiblingType;
}
- private static List<DataNode> sortChildrenList(
- Map<NodeKey, DataNode> childrenList) {
- if (childrenList == null || childrenList.isEmpty()) {
- // the children list is either not yet created or empty.
- return null;
- }
+ private static List<DataNode> sortChildrenList(Map<NodeKey, DataNode> childrenList) {
List<DataNode> sortedList = new ArrayList<>();
Map<String, List<DataNode>> groupedBucket = new HashMap<>();
- Iterator it = childrenList.entrySet().iterator();
-
- while (it.hasNext()) {
- DataNode dataNode = ((Map.Entry<NodeKey, DataNode>) it.next()).getValue();
+ //Sort by name
+ for (Entry<NodeKey, DataNode> nodeKeyDataNodeEntry : childrenList.entrySet()) {
+ DataNode dataNode = nodeKeyDataNodeEntry.getValue();
String nodeName = dataNode.key().schemaId().name();
- List<DataNode> group = groupedBucket.get(nodeName);
- if (group == null) {
- group = new ArrayList<>();
- groupedBucket.put(nodeName, group);
- }
-
+ List<DataNode> group = groupedBucket.computeIfAbsent(nodeName, k -> new ArrayList<>());
group.add(dataNode);
-
}
-
- for (Map.Entry<String, List<DataNode>> entry : groupedBucket.entrySet()) {
+ for (Entry<String, List<DataNode>> entry : groupedBucket.entrySet()) {
sortedList.addAll(entry.getValue());
}
- return sortedList;
+ return sortedList.stream().sorted(Comparator.comparing(object -> object.key().schemaId().name()))
+ .collect(Collectors.toList());
}
}
diff --git a/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java
index 831534a..5bf8ce6 100644
--- a/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java
+++ b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java
@@ -53,6 +53,7 @@
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.Is.is;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
import static org.onosproject.yang.serializers.utils.SerializersUtil.convertRidToUri;
import static org.slf4j.LoggerFactory.getLogger;
@@ -66,21 +67,20 @@
private static YangSerializerContext context;
private static YangSerializer jsonSerializer;
- private static String outputIdTestJson = "{\"identity-test:con1\":{" +
- "\"interface\":\"identity-types:physical\",\"interfaces\":{" +
- "\"int-list\":[{\"iden\":\"identity-types-second:virtual\"," +
- "\"available\":{\"ll\":[\"identity-types:Loopback\"," +
- "\"identity-test:Giga\",\"identity-types-second:Ethernet\"]}}," +
- "{\"iden\":\"optical\",\"available\":{\"ll\":[\"Giga\"]}}]}}}";
+ private static String outputIdTestJson = "{\"identity-test:con1\":" +
+ "{\"interface\":\"identity-types:physical\",\"interfaces\":" +
+ "{\"int-list\":[{\"available\":{\"ll\":[\"identity-types:Loopback\"," +
+ "\"identity-test:Giga\",\"identity-types-second:Ethernet\"]}," +
+ "\"iden\":\"identity-types-second:virtual\"},{\"available\":{" +
+ "\"ll\":[\"Giga\"]},\"iden\":\"optical\"}]}}}";
- private static String outputIdTestJson1 = "{\"jsonlist:c2\":{\"leaflist1" +
- "\":[\"a\",\"b\",\"c\"],\"leaf1\":1,\"leaf2\":2,\"leaf3\":3," +
- "\"leaf4\":4,\"leaf5\":5,\"leaf6\":6,\"leaf7\":\"7\",\"leaf8\"" +
- ":\"8\",\"leaf9\":true,\"leaf10\":\"-922337203685477580.8\"" +
- ",\"ll1\":[1,10],\"ll2\":[2,20],\"ll3\":[3,30],\"ll4\":[4,40],\"" +
- "ll5\":[5,50],\"ll6\":[6,60],\"ll7\":[\"7\",\"70\"],\"ll8\":[\"" +
- "8\",\"80\"],\"ll9\":[true,false],\"ll10\":[" +
- "\"-922337203685477580.8\",\"-922337203685477480.8\"]}}";
+ private static String outputIdTestJson1 = "{\"jsonlist:c2\":{\"leaf1\":1,\"" +
+ "leaf10\":\"-922337203685477580.8\",\"leaf2\":2,\"leaf3\":3," +
+ "\"leaf4\":4,\"leaf5\":5,\"leaf6\":6,\"leaf7\":\"7\"," +
+ "\"leaf8\":\"8\",\"leaf9\":true,\"leaflist1\":[\"a\",\"b\",\"c\"]," +
+ "\"ll1\":[1,10],\"ll10\":[\"-922337203685477580.8\",\"-922337203685477480.8\"]," +
+ "\"ll2\":[2,20],\"ll3\":[3,30],\"ll4\":[4,40],\"ll5\":[5,50],\"ll6\":[6,60]," +
+ "\"ll7\":[\"7\",\"70\"],\"ll8\":[\"8\",\"80\"],\"ll9\":[true,false]}}";
@Rule
public ExpectedException thrown = ExpectedException.none();
@@ -112,12 +112,8 @@
InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
ObjectNode rootNodeOutput;
ObjectMapper mapper = new ObjectMapper();
- try {
- rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
- assertEquals(true, rootNodeOutput != null);
- } catch (IOException e) {
- throw e;
- }
+ rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
+ assertNotNull(rootNodeOutput);
}
@Test
@@ -148,12 +144,8 @@
InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
ObjectNode rootNodeOutput;
ObjectMapper mapper = new ObjectMapper();
- try {
- rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
- assertEquals(true, rootNodeOutput != null);
- } catch (IOException e) {
- throw e;
- }
+ rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
+ assertNotNull(rootNodeOutput);
}
@Test
@@ -184,12 +176,8 @@
InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
ObjectNode rootNodeOutput;
ObjectMapper mapper = new ObjectMapper();
- try {
- rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
- assertEquals(rootNodeOutput.toString(), outputIdTestJson1);
- } catch (IOException e) {
- throw e;
- }
+ rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
+ assertEquals(rootNodeOutput.toString(), outputIdTestJson1);
}
@Test
@@ -220,16 +208,12 @@
InputStream inputStreamOutput = compositeStreamOutPut.resourceData();
ObjectNode rootNodeOutput;
ObjectMapper mapper = new ObjectMapper();
- try {
- rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
- assertEquals(rootNodeOutput.toString(), outputIdTestJson);
- } catch (IOException e) {
- throw e;
- }
+ rootNodeOutput = (ObjectNode) mapper.readTree(inputStreamOutput);
+ assertEquals(rootNodeOutput.toString(), outputIdTestJson);
}
@Test
- public void identityValueNsErrorTest() throws IOException {
+ public void identityValueNsErrorTest() {
thrown.expect(IllegalArgumentException.class);
thrown.expectMessage("Invalid input for value namespace");
String path = "src/test/resources/id-test2.json";