[ONOS-6062] Unit Test for Json Serializer
1. Add Unit Test cases for Json Serializer.
2. Resolved issues during Unit Test.
Change-Id: If7a12607ed88cae38e972e885cb3db2e9e440e2b
diff --git a/serializers/json/pom.xml b/serializers/json/pom.xml
index f14f010..b8ce21e 100644
--- a/serializers/json/pom.xml
+++ b/serializers/json/pom.xml
@@ -61,4 +61,31 @@
<version>RELEASE</version>
</dependency>
</dependencies>
+
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.onosproject</groupId>
+ <artifactId>onos-yang-compiler-maven-plugin</artifactId>
+ <version>${project.version}</version>
+ <configuration>
+ <yangFilesDir>src/test/resources</yangFilesDir>
+ </configuration>
+ <executions>
+ <execution>
+ <id>default</id>
+ <goals>
+ <goal>yang2java</goal>
+ </goals>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.felix</groupId>
+ <artifactId>maven-bundle-plugin</artifactId>
+ <version>3.2.0</version>
+ <extensions>true</extensions>
+ </plugin>
+ </plugins>
+ </build>
</project>
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java
index c4fcaf6..ecc3177 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DataNodeJsonVisitor.java
@@ -25,13 +25,19 @@
import static org.onosproject.yang.serializers.json.DataNodeSiblingPositionType.LAST_INSTANCE;
import static org.onosproject.yang.serializers.json.DataNodeSiblingPositionType.SINGLE_INSTANCE_IN_MULTI_NODE;
+/**
+ * Representation implementation of DataNode visitor, which traverse data tree.
+ */
public class DataNodeJsonVisitor implements DataNodeVisitor {
private static final String COLON = ":";
private JsonBuilder jsonBuilder;
- public DataNodeJsonVisitor(JsonBuilder jsonBuilder) {
- this.jsonBuilder = jsonBuilder;
+ /**
+ * Constructor.
+ */
+ public DataNodeJsonVisitor(JsonBuilder jb) {
+ jsonBuilder = jb;
}
@Override
@@ -50,15 +56,17 @@
jsonBuilder.addNodeTopHalf("", JsonNodeType.OBJECT);
break;
case SINGLE_INSTANCE_LEAF_VALUE_NODE:
+ LeafNode sLeafNode = (LeafNode) dataNode;
jsonBuilder.addNodeWithValueTopHalf(nodeName,
- ((LeafNode) dataNode).value().toString());
+ sLeafNode.asString());
break;
case MULTI_INSTANCE_LEAF_VALUE_NODE:
if (siblingType == FIRST_INSTANCE ||
siblingType == SINGLE_INSTANCE_IN_MULTI_NODE) {
jsonBuilder.addNodeTopHalf(nodeName, JsonNodeType.ARRAY);
}
- jsonBuilder.addValueToLeafListNode(((LeafNode) dataNode).value().toString());
+ LeafNode mLeafNode = (LeafNode) dataNode;
+ jsonBuilder.addValueToLeafListNode(mLeafNode.asString());
break;
default:
break;
@@ -71,13 +79,13 @@
StringBuilder builder = new StringBuilder();
- builder.append(nodeName);
-
if (nameSpace != null) {
- builder.append(COLON);
builder.append(nameSpace);
+ builder.append(COLON);
}
+ builder.append(nodeName);
+
return builder.toString();
}
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonWalker.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonWalker.java
index a4edcab..6110cb7 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonWalker.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/DefaultJsonWalker.java
@@ -16,19 +16,20 @@
package org.onosproject.yang.serializers.json;
+import java.util.Iterator;
+import java.util.Map;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.JsonNodeType;
import org.onosproject.yang.model.DataNode;
import org.onosproject.yang.runtime.helperutils.SerializerHelper;
-import java.util.Iterator;
-import java.util.Map;
-
import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_LEAF_VALUE_NODE;
import static org.onosproject.yang.model.DataNode.Type.MULTI_INSTANCE_NODE;
import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_LEAF_VALUE_NODE;
import static org.onosproject.yang.model.DataNode.Type.SINGLE_INSTANCE_NODE;
+import static org.onosproject.yang.serializers.utils.SerializersUtil.getLatterSegment;
+import static org.onosproject.yang.serializers.utils.SerializersUtil.getPreSegment;
/**
* Represents implementation of JSON walk, which walks the JSON object node.
@@ -38,19 +39,19 @@
private DataNode.Builder dataNodeBuilder;
- public DefaultJsonWalker(DataNode.Builder dataNodeBuilder) {
- this.dataNodeBuilder = dataNodeBuilder;
+ /**
+ * Constructor.
+ */
+ public DefaultJsonWalker(DataNode.Builder db) {
+ dataNodeBuilder = db;
}
@Override
public void walkJsonNode(String fieldName, JsonNode jsonNode) {
-
- JsonNodeType nodeType = jsonNode.getNodeType();
-
if (!jsonNode.isContainerNode()) {
//the node has no children, so add it as leaf node to the data tree.
addLeafNodeToDataTree(fieldName, jsonNode);
- SerializerHelper.exitDataNode(dataNodeBuilder);
+ dataNodeBuilder = SerializerHelper.exitDataNode(dataNodeBuilder);
return;
}
@@ -64,7 +65,8 @@
// Let's deal with the leaflist case first.
if (isJsonNodeLeafList((ArrayNode) jsonNode)) {
addLeafListNodeToDataTree(fieldName, (ArrayNode) jsonNode);
- SerializerHelper.exitDataNode(dataNodeBuilder);
+ //Don't move up, as addLeafListNodeToDataTree() does it.
+ //SerializerHelper.exitDataNode(dataNodeBuilder);
return;
}
@@ -80,12 +82,13 @@
// Recursively build the subtree of element
walkJsonNode(null, element);
- // We are done with this array element
- SerializerHelper.exitDataNode(dataNodeBuilder);
+ // We are done with this array element.
+ dataNodeBuilder = SerializerHelper.exitDataNode(dataNodeBuilder);
}
// We are done with this array node.
- SerializerHelper.exitDataNode(dataNodeBuilder);
+ // Don't move up, as we are already at the parent node.
+ //SerializerHelper.exitDataNode(dataNodeBuilder);
return;
}
@@ -113,18 +116,18 @@
if (fieldName != null) {
// move up since we finish creating a container node.
- SerializerHelper.exitDataNode(dataNodeBuilder);
+ dataNodeBuilder = SerializerHelper.exitDataNode(dataNodeBuilder);
}
}
private void addDataNode(String fieldName, String value, DataNode.Type nodeType) {
String nodeName = getLatterSegment(fieldName, COLON);
String namespace = getPreSegment(fieldName, COLON);
- SerializerHelper.addDataNode(dataNodeBuilder,
- nodeName,
- namespace,
- value,
- nodeType);
+ dataNodeBuilder = SerializerHelper.addDataNode(dataNodeBuilder,
+ nodeName,
+ namespace,
+ value,
+ nodeType);
}
private void addNoneLeafDataNode(String fieldName, DataNode.Type nodeType) {
@@ -159,7 +162,7 @@
if (eleType == JsonNodeType.STRING || eleType == JsonNodeType.NUMBER) {
addLeafDataNode(fieldName, element.asText(),
MULTI_INSTANCE_LEAF_VALUE_NODE);
- SerializerHelper.exitDataNode(dataNodeBuilder);
+ dataNodeBuilder = SerializerHelper.exitDataNode(dataNodeBuilder);
}
}
}
@@ -168,7 +171,6 @@
if (!jsonNode.isArray()) {
return false;
}
-
Iterator<JsonNode> elements = jsonNode.elements();
while (elements.hasNext()) {
JsonNode element = elements.next();
@@ -177,55 +179,6 @@
return false;
}
}
-
return true;
}
-
- /**
- * Returns the previous segment of a path which is separated by a split char.
- * For example:
- * <pre>
- * "foo:bar", ":" --> "foo"
- * </pre>
- *
- * @param path the original path string
- * @param splitChar char used to split the path
- * @return the previous segment of the path
- */
- private String getPreSegment(String path, String splitChar) {
- int idx = path.indexOf(splitChar);
- if (idx == -1) {
- return null;
- }
-
- if (path.indexOf(splitChar, idx + 1) != -1) {
- return null;
- }
-
- return path.substring(0, idx);
- }
-
- /**
- * Returns the latter segment of a path which is separated by a split char.
- * For example:
- * <pre>
- * "foo:bar", ":" --> "bar"
- * </pre>
- *
- * @param path the original path string
- * @param splitChar char used to split the path
- * @return the latter segment of the path
- */
- private String getLatterSegment(String path, String splitChar) {
- int idx = path.indexOf(splitChar);
- if (idx == -1) {
- return path;
- }
-
- if (path.indexOf(splitChar, idx + 1) != -1) {
- return null;
- }
-
- return path.substring(idx + 1);
- }
-}
+}
\ No newline at end of file
diff --git a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonSerializer.java b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonSerializer.java
index 40608b7..bf8ceb5 100644
--- a/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonSerializer.java
+++ b/serializers/json/src/main/java/org/onosproject/yang/serializers/json/JsonSerializer.java
@@ -47,6 +47,7 @@
*/
public class JsonSerializer implements YangSerializer {
private static final String JSON_FORMAT = "JSON";
+ private static final String ERROR_INFO = "JSON serializer decode failure";
private final Logger log = getLogger(getClass());
private final ObjectMapper mapper = new ObjectMapper();
@@ -92,17 +93,19 @@
yangSerializerContext);
}
- ResourceData resourceData = DefaultResourceData.builder().
- addDataNode(dataNode).resourceId(rIdBuilder.build()).build();
+ ResourceData resourceData = DefaultResourceData.builder()
+ .addDataNode(dataNode)
+ .resourceId(rIdBuilder == null ? null : rIdBuilder.build())
+ .build();
return DefaultCompositeData.builder().resourceData(resourceData).build();
} catch (JsonProcessingException e) {
log.error("ERROR: JsonProcessingException {}",
e.getMessage());
log.debug("Exception in decode:", e);
- throw new SerializerException("JSON serializer decode failure");
+ throw new SerializerException(ERROR_INFO);
} catch (IOException ex) {
log.error("ERROR: decode ", ex);
- throw new SerializerException("JSON serializer decode failure");
+ throw new SerializerException(ERROR_INFO);
}
}
@@ -125,10 +128,7 @@
if (rootNode != null) {
inputStream = IOUtils.toInputStream(rootNode.toString());
}
-
- CompositeStream compositeStream = new DefaultCompositeStream(uriString,
- inputStream);
-
- return compositeStream;
+ // return a CompositeStream
+ return new DefaultCompositeStream(uriString, inputStream);
}
}
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
new file mode 100644
index 0000000..6d4b165
--- /dev/null
+++ b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/JsonSerializerTest.java
@@ -0,0 +1,320 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.serializers.json;
+
+import org.apache.commons.io.IOUtils;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.onosproject.yang.model.DataNode;
+import org.onosproject.yang.model.DataNode.Type;
+import org.onosproject.yang.model.InnerNode;
+import org.onosproject.yang.model.LeafNode;
+import org.onosproject.yang.model.NodeKey;
+import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.SchemaId;
+import org.onosproject.yang.runtime.CompositeData;
+import org.onosproject.yang.runtime.CompositeStream;
+import org.onosproject.yang.runtime.DefaultCompositeStream;
+import org.onosproject.yang.runtime.YangSerializer;
+import org.onosproject.yang.runtime.YangSerializerContext;
+
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.junit.Assert.assertEquals;
+
+/**
+ * Unit Test for Json Serializer.
+ */
+public class JsonSerializerTest {
+ private static final String WRONG_STRUCTURE = "The Data Node structure is wrong!";
+ private static final String WRONG_TYPE = "The Data Node type is wrong!";
+
+ private static YangSerializerContext context;
+ private static YangSerializer jsonSerializer;
+
+ @BeforeClass
+ public static void prepare() {
+ context = new MockYangSerializerContext();
+ jsonSerializer = new JsonSerializer();
+ }
+
+ @Test
+ public void jsonSerializerTest() {
+ String path = "src/test/resources/testinput.json";
+ DefaultCompositeStream external =
+ new DefaultCompositeStream(null, parseInput(path));
+ CompositeData compositeData = jsonSerializer.decode(external, context);
+ ResourceData resourceData = compositeData.resourceData();
+ DataNode rootNode = resourceData.dataNodes().get(0);
+
+ // 1. test if rootNode is SINGLE_INSTANCE_NODE.
+ assertEquals(WRONG_TYPE, Type.SINGLE_INSTANCE_NODE, rootNode.type());
+ InnerNode innerNode = (InnerNode) rootNode;
+ Map<NodeKey, DataNode> nodeChilds = innerNode.childNodes();
+ // 2. test if Root Node only have one child.
+ assertEquals(WRONG_STRUCTURE, 1, nodeChilds.size());
+ NodeKey nodeChildKey = convertNameStringToNodeKey("top1", "jsonlist");
+ // 3. test if l1 is the only child of Root Node.
+ assertEquals(WRONG_STRUCTURE, true, nodeChilds.containsKey(nodeChildKey));
+ InnerNode nodeTop1 = (InnerNode) nodeChilds.get(nodeChildKey);
+ Map<NodeKey, DataNode> nodeTop1Childs = nodeTop1.childNodes();
+ // 4. test if top1 contains three childs.
+ assertEquals(WRONG_STRUCTURE, 3, nodeTop1Childs.size());
+ DataNode l1DataNode = getDataNode(nodeTop1Childs, "l1");
+ // 5. test if l1 is multi_instance_node
+ assertEquals(WRONG_TYPE, Type.MULTI_INSTANCE_NODE, l1DataNode.type());
+
+ InnerNode l1InnerNode = (InnerNode) l1DataNode;
+ Map<NodeKey, DataNode> l1ChildNodes = l1InnerNode.childNodes();
+ DataNode k1DataNode = getDataNode(l1ChildNodes, "k1");
+ LeafNode k1LeafNode = (LeafNode) k1DataNode;
+ DataNode k2DataNode = getDataNode(l1ChildNodes, "k2");
+ LeafNode k2LeafNode = (LeafNode) k2DataNode;
+ DataNode k3DataNode = getDataNode(l1ChildNodes, "k3");
+ LeafNode k3LeafNode = (LeafNode) k3DataNode;
+ // 6. test if k1, k2, k3 are with the right value.
+ assertEquals(WRONG_STRUCTURE, true,
+ k1LeafNode.asString().equals("k1value"));
+ assertEquals(WRONG_STRUCTURE, true,
+ k2LeafNode.asString().equals("k2value"));
+ assertEquals(WRONG_STRUCTURE, true,
+ k3LeafNode.asString().equals("k3value"));
+
+ // 7. test if c1 is in the right structure.
+ DataNode c1DataNode = getDataNode(l1ChildNodes, "c1");
+ InnerNode c1InnerNode = (InnerNode) c1DataNode;
+ DataNode leafC1DataNode = getDataNode(c1InnerNode.childNodes(), "leaf_c1");
+ LeafNode leafC1LeafNode = (LeafNode) leafC1DataNode;
+ assertEquals(WRONG_STRUCTURE, 1, c1InnerNode.childNodes().size());
+ assertEquals(WRONG_TYPE, Type.SINGLE_INSTANCE_LEAF_VALUE_NODE, leafC1DataNode.type());
+ assertEquals(WRONG_STRUCTURE, true, leafC1LeafNode.asString().equals("c1leaf"));
+
+ DataNode c2DataNode = getDataNode(nodeTop1Childs, "c2");
+ // 8. test if c2 is single_instance_node.
+ assertEquals(WRONG_TYPE, Type.SINGLE_INSTANCE_NODE, c2DataNode.type());
+
+ InnerNode c2InnerNode = (InnerNode) c2DataNode;
+ Map<NodeKey, DataNode> c2ChildNodes = c2InnerNode.childNodes();
+ DataNode leaflist1DataNode = getDataNode(c2ChildNodes, "leaflist1");
+ LeafNode leafList1LeafNode = (LeafNode) leaflist1DataNode;
+ // 9. test if leaflist1 is in the right structure.
+ assertEquals(WRONG_TYPE, Type.MULTI_INSTANCE_LEAF_VALUE_NODE, leafList1LeafNode.type());
+
+ }
+
+ @Test
+ public void encodeTest() {
+ String path = "src/test/resources/testinput.json";
+ DefaultCompositeStream external =
+ new DefaultCompositeStream(null, parseInput(path));
+ CompositeData compositeData = jsonSerializer.decode(external, context);
+ CompositeStream compositeStream = jsonSerializer.encode(compositeData, context);
+ InputStream inputStream = compositeStream.resourceData();
+ String expectString = parseJsonToString(path);
+ assertEquals(WRONG_STRUCTURE, expectString, convertInputStreamToString(inputStream));
+ }
+
+ /**
+ * Reads JSON contents from file path and returns input stream.
+ *
+ * @param path path of JSON file
+ * @return input stream
+ */
+ private static InputStream parseInput(String path) {
+ String temp;
+ StringBuilder sb = new StringBuilder();
+ try (BufferedReader br = new BufferedReader(new FileReader(path))) {
+ while ((temp = br.readLine()) != null) {
+ temp = removeSpace(temp);
+ sb.append(temp);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return IOUtils.toInputStream(sb);
+ }
+
+ /**
+ * Reads JSON contents from file path and returns input stream.
+ *
+ * @param path path of JSON file
+ * @return json string
+ */
+ private static String parseJsonToString(String path) {
+ String temp;
+ StringBuilder sb = new StringBuilder();
+ try (BufferedReader br = new BufferedReader(new FileReader(path))) {
+ while ((temp = br.readLine()) != null) {
+ temp = removeSpaceChangeName(temp);
+ sb.append(temp);
+ }
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ return sb.toString();
+ }
+
+ /**
+ * While traversing a String line first remove all the white space.
+ *
+ * @param line a line of Json file.
+ * @return String modified line
+ */
+ private static String removeSpace(String line) {
+ if (line.length() == 0) {
+ return line;
+ }
+ StringBuilder sb = new StringBuilder();
+ for (int i = 0; i < line.length(); i++) {
+ if (line.charAt(i) != ' ') {
+ sb.append(line.charAt(i));
+ }
+ }
+ return sb.toString();
+ }
+
+ /**
+ * While traversing a String line
+ * first remove all the white space.
+ * second if the json attribute's name has no namespace, add it on.
+ *
+ * @param line a line of Json file.
+ * @return String modified line
+ */
+ private static String removeSpaceChangeName(String line) {
+ if (line.length() == 0) {
+ return line;
+ }
+ StringBuilder sb = new StringBuilder();
+ int count = 0;
+ for (int i = 0; i < line.length(); i++) {
+ if (line.charAt(i) == ' ') {
+ count++;
+ continue;
+ }
+ if (line.charAt(i) == '"') {
+ sb.append(line.charAt(i));
+ if (count > 4) {
+ sb.append("jsonlist:");
+ count = 0;
+ }
+ i++;
+ int start = i;
+ while (line.charAt(i) != '"') {
+ i++;
+ }
+ int end = i;
+ for (int j = start; j < end; j++) {
+ sb.append(line.charAt(j));
+ }
+ }
+ sb.append(line.charAt(i));
+ }
+ return sb.toString();
+ }
+
+ /**
+ * Converts name and name space to NodeKey.
+ *
+ * @param name name
+ * @param nameSpace name space
+ * @return NodeKey
+ */
+ private NodeKey convertNameStringToNodeKey(String name, String nameSpace) {
+ SchemaId schemaId = new SchemaId("top1", "jsonlist");
+ NodeKey.NodeKeyBuilder nodeKeyBuilder =
+ new NodeKey.NodeKeyBuilder<>().schemaId(schemaId);
+ NodeKey nodeKey = nodeKeyBuilder.build();
+ return nodeKey;
+ }
+
+ /**
+ * Obtain a list of NodeKey from Map container.
+ *
+ * @param nodeChils Map container of InnerNode
+ * @return List<NodeKey> list of nodeChils' key
+ */
+ private List<NodeKey> listNodeChildsKey(Map<NodeKey, DataNode> nodeChils) {
+ Set<NodeKey> set = nodeChils.keySet();
+ List<NodeKey> list = new ArrayList<>();
+ list.addAll(set);
+ return list;
+ }
+
+ /**
+ * Obtain a list of DataNode from Map container.
+ *
+ * @param nodeChils Map container of InnerNode
+ * @return List<NodeKey> list of nodeChils' value
+ */
+ private List<DataNode> listNodeChildsValue(Map<NodeKey, DataNode> nodeChils) {
+ Collection<DataNode> coll = nodeChils.values();
+ List<DataNode> list = new ArrayList(coll);
+ return list;
+ }
+
+ /**
+ * Obtain the DataNode for Map with specific name.
+ *
+ * @param nodeChils Map container of InnerNode
+ * @param keyName name of the DataNode which also shown in Json File.
+ * @return DataNode
+ */
+ private DataNode getDataNode(Map<NodeKey, DataNode> nodeChils, String keyName) {
+ List<DataNode> top1DataNodeList = listNodeChildsValue(nodeChils);
+ DataNode l1DataNode = null;
+ for (DataNode node : top1DataNodeList) {
+ String actualName = String.valueOf(node.key().schemaId().name());
+ String expectName = String.valueOf(keyName);
+ if (actualName.equals(expectName)) {
+ l1DataNode = node;
+ break;
+ }
+ }
+ return l1DataNode;
+ }
+
+ /**
+ * Converts input stream to string format.
+ *
+ * @param inputStream input stream of xml
+ * @return JSON string
+ */
+ private static String convertInputStreamToString(InputStream inputStream) {
+ BufferedReader br;
+ StringBuilder sb = new StringBuilder();
+ String xmlData;
+ br = new BufferedReader(new InputStreamReader(inputStream));
+ try {
+ while ((xmlData = br.readLine()) != null) {
+ sb.append(xmlData);
+ }
+ } catch (IOException e) {
+ throw new SerializerException(e.getMessage());
+ }
+ return sb.toString();
+ }
+}
diff --git a/serializers/json/src/test/java/org/onosproject/yang/serializers/json/MockYangSchemaNodeProvider.java b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/MockYangSchemaNodeProvider.java
new file mode 100644
index 0000000..c45d18a
--- /dev/null
+++ b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/MockYangSchemaNodeProvider.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.serializers.json;
+
+import org.onosproject.yang.model.YangModel;
+import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.runtime.AppModuleInfo;
+import org.onosproject.yang.runtime.DefaultAppModuleInfo;
+import org.onosproject.yang.runtime.DefaultModelRegistrationParam;
+import org.onosproject.yang.runtime.ModelRegistrationParam;
+import org.onosproject.yang.runtime.YangModelRegistry;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import static org.onosproject.yang.compiler.datamodel.utils.DataModelUtils.deSerializeDataModel;
+import static org.onosproject.yang.runtime.helperutils.YangApacheUtils.processModuleId;
+import static org.onosproject.yang.runtime.helperutils.YangApacheUtils.processYangModel;
+import static org.onosproject.yang.compiler.utils.UtilConstants.TEMP;
+import static org.onosproject.yang.compiler.utils.io.impl.YangIoUtils.deleteDirectory;
+import static org.onosproject.yang.runtime.helperutils.RuntimeHelper.getInterfaceClassName;
+
+/**
+ * Represents mock bundle context. provides bundle context for YSR to do unit
+ * testing.
+ */
+public class MockYangSchemaNodeProvider {
+
+ private static final String FS = File.separator;
+ private static final String PATH = System.getProperty("user.dir") +
+ FS + "target" + FS + "classes" + FS;
+ private static final String SER_FILE_PATH = "yang" + FS + "resources" +
+ FS + "YangMetaData.ser";
+ private static final String META_PATH = PATH + SER_FILE_PATH;
+ private static final String TEMP_FOLDER_PATH = PATH + TEMP;
+ private YangModelRegistry reg = new DefaultYangModelRegistry();
+ private List<YangNode> nodes = new ArrayList<>();
+
+ /**
+ * Creates an instance of mock bundle context.
+ */
+ public MockYangSchemaNodeProvider() {
+ }
+
+ /**
+ * Process YANG schema node for a application.
+ */
+ public void processSchemaRegistry() {
+ try {
+ //Need to deserialize generated meta data file for unit tests.
+ Set<YangNode> appNode = deSerializeDataModel(META_PATH);
+ nodes.addAll(appNode);
+ reg.registerModel(prepareParam(nodes));
+ deleteDirectory(TEMP_FOLDER_PATH);
+ } catch (IOException e) {
+ }
+ }
+
+ /**
+ * Unregister given nodes from runtime service.
+ *
+ * @param nodes list of nodes
+ */
+ public void unRegister(List<YangNode> nodes) {
+ reg.unregisterModel(prepareParam(nodes));
+ }
+
+ /**
+ * Prepares model registration parameter.
+ *
+ * @param nodes list of nodes
+ * @return model registration parameter
+ */
+ private ModelRegistrationParam prepareParam(List<YangNode> nodes) {
+ //Process loading class file.
+ String appName;
+ ClassLoader classLoader = getClass().getClassLoader();
+
+ //Create model registration param.
+ ModelRegistrationParam.Builder b =
+ DefaultModelRegistrationParam.builder();
+
+ //create a new YANG model
+ YangModel model = processYangModel(META_PATH, nodes);
+ //set YANG model
+ b.setYangModel(model);
+
+ Iterator<YangNode> it = nodes.iterator();
+ while (it.hasNext()) {
+ YangSchemaNode node = it.next();
+
+ //If service class is not generated then use
+ // interface file to load this class.
+ appName = getInterfaceClassName(node);
+ Class<?> cls;
+ try {
+ cls = classLoader.loadClass(appName);
+ } catch (ClassNotFoundException e) {
+ continue;
+ }
+
+ //generate app info.
+ AppModuleInfo info = new DefaultAppModuleInfo(cls, null);
+ b.addAppModuleInfo(processModuleId((YangNode) node), info);
+ }
+ return b.build();
+ }
+
+ /**
+ * Returns schema registry.
+ *
+ * @return schema registry
+ */
+ public DefaultYangModelRegistry registry() {
+ return (DefaultYangModelRegistry) reg;
+ }
+}
diff --git a/serializers/json/src/test/java/org/onosproject/yang/serializers/json/MockYangSerializerContext.java b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/MockYangSerializerContext.java
new file mode 100644
index 0000000..aeb4d8d
--- /dev/null
+++ b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/MockYangSerializerContext.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.onosproject.yang.serializers.json;
+
+import org.onosproject.yang.model.SchemaContext;
+import org.onosproject.yang.runtime.Annotation;
+import org.onosproject.yang.runtime.DefaultAnnotation;
+import org.onosproject.yang.runtime.YangSerializerContext;
+import org.onosproject.yang.runtime.impl.DefaultYangModelRegistry;
+
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Tests the default schema context provider methods.
+ */
+public class MockYangSerializerContext implements YangSerializerContext {
+
+ private static MockYangSchemaNodeProvider schemaProvider =
+ new MockYangSchemaNodeProvider();
+ private static final String NETCONF_NS =
+ "urn:ietf:params:xml:ns:netconf:base:1.0";
+ private static final String XMNLS_NC = "xml:xc";
+
+
+ @Override
+ public SchemaContext getContext() {
+ schemaProvider.processSchemaRegistry();
+ DefaultYangModelRegistry registry = schemaProvider.registry();
+ return registry;
+ }
+
+ @Override
+ public List<Annotation> getProtocolAnnotations() {
+ Annotation annotation = new DefaultAnnotation(XMNLS_NC, NETCONF_NS);
+ List<Annotation> protocolAnnotation = new LinkedList<>();
+ protocolAnnotation.add(annotation);
+ return protocolAnnotation;
+ }
+}
diff --git a/serializers/json/src/test/java/org/onosproject/yang/serializers/json/package-info.java b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/package-info.java
new file mode 100644
index 0000000..a3a416b
--- /dev/null
+++ b/serializers/json/src/test/java/org/onosproject/yang/serializers/json/package-info.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2017-present Open Networking Laboratory
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/**
+ * The JSON serializer implementation of the YangSerializer interface.
+ */
+package org.onosproject.yang.serializers.json;
diff --git a/serializers/json/src/test/resources/json-test.yang b/serializers/json/src/test/resources/json-test.yang
new file mode 100644
index 0000000..46a1caf
--- /dev/null
+++ b/serializers/json/src/test/resources/json-test.yang
@@ -0,0 +1,46 @@
+module jsonlist {
+
+ yang-version 1;
+
+ namespace "jsonlist";
+
+ prefix "l";
+
+ organization "ON-LAB";
+
+ description "This module defines for list.";
+
+ revision "2016-06-24" {
+ description "Initial revision.";
+ }
+
+ container top1 {
+ list l1 {
+ key "k1 k2 k3";
+ leaf k1 {
+ type string;
+ }
+
+ leaf k2 {
+ type string;
+ }
+
+ leaf k3 {
+ type string;
+ }
+
+ container c1 {
+ leaf leaf_c1 {
+ type string;
+ }
+ }
+ }
+
+ container c2 {
+ leaf-list leaflist1 {
+ type string;
+ }
+ }
+
+ }
+}
diff --git a/serializers/json/src/test/resources/testinput.json b/serializers/json/src/test/resources/testinput.json
new file mode 100644
index 0000000..62728dd
--- /dev/null
+++ b/serializers/json/src/test/resources/testinput.json
@@ -0,0 +1,25 @@
+{
+ "jsonlist:top1":{
+ "jsonlist:l1":[
+ {
+ "k1":"k1value",
+ "k2":"k2value",
+ "k3":"k3value",
+ "c1":{
+ "leaf_c1":"c1leaf"
+ }
+ },
+ {
+ "k1":"k1value2",
+ "k2":"k2value2",
+ "k3":"k3value2",
+ "c1":{
+ "leaf_c1":"c1leaf2"
+ }
+ }
+ ],
+ "jsonlist:c2":{
+ "leaflist1":["a","b","c"]
+ }
+ }
+}
\ No newline at end of file
diff --git a/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java b/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java
index dbb0222..8e136bf 100644
--- a/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java
+++ b/serializers/utils/src/main/java/org/onosproject/yang/serializers/utils/SerializersUtil.java
@@ -260,14 +260,14 @@
* Returns the previous segment of a path which is separated by a split char.
* For example:
* <pre>
- * "foo:bar", ":" --> "foo"
+ * "foo:bar", ":" to "foo"
* </pre>
*
* @param path the original path string
* @param splitChar char used to split the path
* @return the previous segment of the path
*/
- private static String getPreSegment(String path, String splitChar) {
+ public static String getPreSegment(String path, String splitChar) {
int idx = path.lastIndexOf(splitChar);
if (idx == -1) {
return null;
@@ -279,14 +279,14 @@
* Returns the latter segment of a path which is separated by a split char.
* For example:
* <pre>
- * "foo:bar", ":" --> "bar"
+ * "foo:bar", ":" to "bar"
* </pre>
*
* @param path the original path string
* @param splitChar char used to split the path
* @return the latter segment of the path
*/
- private static String getLatterSegment(String path, String splitChar) {
+ public static String getLatterSegment(String path, String splitChar) {
int idx = path.lastIndexOf(splitChar);
if (idx == -1) {
return path;