[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;