[ONOS-6057] Model converter :rpc's output object to data node conversion.

Change-Id: If9cd3e027898c89a16e5382383d92f4a87a26ce5
diff --git a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java
index 798d45b..6263264 100644
--- a/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java
+++ b/compiler/base/datamodel/src/main/java/org/onosproject/yang/compiler/datamodel/YangUses.java
@@ -22,6 +22,7 @@
 
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Set;
 
 import static java.util.Collections.unmodifiableList;
 import static org.onosproject.yang.compiler.datamodel.TraversalType.CHILD;
@@ -403,6 +404,12 @@
 
                 clonedLeaf.setContainedIn(usesParent);
                 usesParent.addLeaf(clonedLeaf);
+                if (usesParent instanceof YangList) {
+                    Set<String> keys = ((YangList) usesParent).getKeyLeaf();
+                    if (keys.contains(clonedLeaf.getName())) {
+                        clonedLeaf.setKeyLeaf(true);
+                    }
+                }
             }
         }
         if (referredGrouping.getListOfLeafList() != null) {
diff --git a/model/src/main/java/org/onosproject/yang/model/DataNode.java b/model/src/main/java/org/onosproject/yang/model/DataNode.java
index c76fa97..1833534 100644
--- a/model/src/main/java/org/onosproject/yang/model/DataNode.java
+++ b/model/src/main/java/org/onosproject/yang/model/DataNode.java
@@ -163,7 +163,7 @@
          * @param node parent node builder
          * @return builder object
          */
-        protected B parent(InnerNode.Builder node) {
+        public B parent(InnerNode.Builder node) {
             parent = node;
             return (B) this;
         }
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/ExtResourceIdBldr.java b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/ExtResourceIdBldr.java
index 4d06677..e7cdfe2 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/ExtResourceIdBldr.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/ExtResourceIdBldr.java
@@ -88,12 +88,11 @@
      * builder.
      *
      * @param ridBldr extended resource id builder
-     * @param builder resource id builder
+     * @param id      resource id
      * @return updated extended resource id builder
      */
-    public ExtResourceIdBldr copyBuilder(ExtResourceIdBldr ridBldr, ResourceId
-            .Builder builder) {
-        ResourceId id = builder.build();
+    public ExtResourceIdBldr copyBuilder(ExtResourceIdBldr ridBldr,
+                                         ResourceId id) {
         SchemaId sId;
         // Preparing the extended resource id builder from resourceId.
         List<NodeKey> keys = id.nodeKeys();
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java
index 3bb668b..0902630 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/SerializerHelper.java
@@ -215,7 +215,7 @@
     public static Builder initializeDataNode(ResourceId.Builder builder) {
 
         ExtResourceIdBldr rIdBldr = new ExtResourceIdBldr();
-        rIdBldr = rIdBldr.copyBuilder(rIdBldr, builder);
+        rIdBldr = rIdBldr.copyBuilder(rIdBldr, builder.build());
         rIdBldr.appInfo(builder.appInfo());
         SchemaContext node = (SchemaContext) builder.appInfo();
         HelperContext info = new HelperContext();
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilder.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilder.java
index 7be4b60..c78e54e 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilder.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilder.java
@@ -21,11 +21,14 @@
 import org.onosproject.yang.compiler.datamodel.YangAugmentableNode;
 import org.onosproject.yang.compiler.datamodel.YangCase;
 import org.onosproject.yang.compiler.datamodel.YangChoice;
+import org.onosproject.yang.compiler.datamodel.YangInput;
 import org.onosproject.yang.compiler.datamodel.YangLeaf;
 import org.onosproject.yang.compiler.datamodel.YangLeafList;
 import org.onosproject.yang.compiler.datamodel.YangLeavesHolder;
 import org.onosproject.yang.compiler.datamodel.YangList;
 import org.onosproject.yang.compiler.datamodel.YangNode;
+import org.onosproject.yang.compiler.datamodel.YangOutput;
+import org.onosproject.yang.compiler.datamodel.YangRpc;
 import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
 import org.onosproject.yang.compiler.utils.io.YangPluginConfig;
 import org.onosproject.yang.model.DataNode;
@@ -36,6 +39,7 @@
 import org.onosproject.yang.model.ModelObjectData;
 import org.onosproject.yang.model.ModelObjectId;
 import org.onosproject.yang.model.ResourceData;
+import org.onosproject.yang.model.ResourceId;
 import org.onosproject.yang.runtime.DefaultResourceData;
 
 import java.util.Iterator;
@@ -129,20 +133,25 @@
         //Create data nodes.
         DataTreeBuilderHelper helper = new DataTreeBuilderHelper(reg);
         YangSchemaNode curNode;
-        for (Object modObj : modelObjects) {
+        for (ModelObject modObj : modelObjects) {
             //Do processing of data node conversion from model objects.
             if (modObj instanceof LeafModelObject) {
                 //Process leaf object.
                 processLeafObj(lastIndexNode, rscData, (LeafModelObject) modObj);
             } else {
-                curNode = fetchCurNode(modObj, (YangNode) lastIndexNode);
+                if (converter.isInputOrOutput()) {
+                    curNode = handleRpcChild(modObj, (YangNode)
+                            lastIndexNode, rscData);
+                } else {
+                    curNode = fetchCurNode(modObj, (YangNode) lastIndexNode);
+                }
                 if (curNode != null) {
                     processDataNodeConversion((YangNode) curNode, helper,
                                               rscData, modObj);
                 } else {
                     throw new ModelConvertorException(
                             "failed to convert model object in data node" +
-                                    modObj.toString());
+                                    modObj);
                 }
             }
         }
@@ -192,6 +201,44 @@
     }
 
     /**
+     * Returns input/output nodes.
+     *
+     * @param obj     model object for input/output nodes
+     * @param parent  module node
+     * @param rscData resource data builder
+     * @return input/output node
+     */
+    private YangSchemaNode handleRpcChild(
+            Object obj, YangNode parent, DefaultResourceData.Builder rscData) {
+        if (obj != null && parent != null) {
+            //process all the node which are in data model tree.
+            String name = obj.getClass().getName();
+            YangNode child = parent.getChild();
+            while (child != null && !(child instanceof YangRpc)) {
+                child = child.getNextSibling();
+            }
+            if (child != null) {
+                //Rpc should be part of resource identifier for input/output
+                // nodes.
+                ResourceId id = ResourceId.builder()
+                        .addBranchPointSchema("/", null)
+                        .addBranchPointSchema(child.getName(), child
+                                .getNameSpace().getModuleNamespace()).build();
+                rscData.resourceId(id);
+                child = child.getChild();
+                return getNode(child, name);
+            }
+        }
+        // this could also be possible that we have received this module node
+        // when model object is a node at third level of root node. for
+        // example if we have a model object id which is null and model
+        // object is an object of choice instance then this will be called
+        // because choice object will be instance of case class which is an
+        // third level node.
+        return fetchCurNode(obj, parent);
+    }
+
+    /**
      * In last index node we will be having parent node of the current object
      * so we need to get the current node and start processing it for
      * conversion.
@@ -323,6 +370,10 @@
                 javaName = child.getJavaPackage() + PERIOD + DEFAULT_CAPS +
                         getAugmentClassName((YangAugment) child,
                                             new YangPluginConfig());
+            } else if (child instanceof YangInput ||
+                    child instanceof YangOutput) {
+                javaName = child.getJavaPackage() + PERIOD + DEFAULT_CAPS +
+                        getCapitalCase(child.getJavaClassNameOrBuiltInType());
             } else {
                 javaName = child.getJavaPackage() + PERIOD + DEFAULT_CAPS +
                         getCapitalCase(getCamelCase(child.getName(), null));
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java
index 77d1b7f..aab6fd7 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/DefaultModelConverter.java
@@ -43,7 +43,7 @@
     }
 
     @Override
-    public synchronized ResourceData createDataNode(ModelObjectData modelData) {
+    public ResourceData createDataNode(ModelObjectData modelData) {
         DefaultDataTreeBuilder builder = new DefaultDataTreeBuilder(reg);
         return builder.getResourceData(modelData);
     }
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 e679d60..1ba79c6 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
@@ -286,13 +286,15 @@
      * Returns schema node for the given name. Name should be nodes namespace
      * defined in YANG file
      *
-     * @param nameSpace name space of YANG file
+     * @param nameSpace         name space of YANG file
+     * @param isForChildContext if the method call has arrived for child context
      * @return YANG schema node
      */
-    public YangSchemaNode getForNameSpace(String nameSpace) {
+    public YangSchemaNode getForNameSpace(String nameSpace,
+                                          boolean isForChildContext) {
 
         YangSchemaNode node = nameSpaceSchemaStore.get(nameSpace);
-        if (node == null) {
+        if (node == null && !isForChildContext) {
             log.error("node with {} namespace not found.", nameSpace);
         }
         return node;
@@ -314,7 +316,9 @@
                 regClass = registerClassStore.get(interfaceName);
             }
         }
-        log.error("{} node should not be null.");
+        if (regClass == null) {
+            log.error("{} node should not be null.");
+        }
         return regClass;
     }
 
@@ -575,7 +579,7 @@
         }
 
         String namespace = schemaId.namespace();
-        YangSchemaNode node = getForNameSpace(namespace);
+        YangSchemaNode node = getForNameSpace(namespace, true);
         if (node == null) {
             //If namespace if module name.
             node = getForSchemaName(schemaId.namespace());
@@ -585,6 +589,9 @@
         try {
             if (node != null) {
                 return node.getChildSchema(id).getSchemaNode();
+            } else {
+                log.error("node with {} namespace not found.", schemaId
+                        .namespace());
             }
         } catch (DataModelException e) {
             log.error("failed to get child schema", e);
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModIdToRscIdConverter.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModIdToRscIdConverter.java
index 837795e..772e6a6 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModIdToRscIdConverter.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/ModIdToRscIdConverter.java
@@ -69,6 +69,11 @@
     private boolean isRpcAdded = true;
 
     /**
+     * Flag is true if we have found module node using input/output packages.
+     */
+    private boolean isInputOrOutput;
+
+    /**
      * Model registry.
      */
     private final DefaultYangModelRegistry reg;
@@ -159,6 +164,7 @@
         modPkg.deleteCharAt(modPkg.lastIndexOf(PERIOD));
         YangNode node = (YangNode) reg.getForInterfaceFilePkg(modPkg.toString());
         if (node != null) {
+            isInputOrOutput = true;
             modNode = node;
             //in this case we should update the lastIndexNode for object to
             // data fetchNode conversion. because we need to create the data fetchNode
@@ -166,7 +172,8 @@
             node = node.getChild();
             while (node != null) {
                 if (node.getJavaAttributeName().toLowerCase()
-                        .equals(strArray[i])) {
+                        .equals(strArray[i]) &&
+                        node.getYangSchemaNodeType() != YANG_NON_DATA_NODE) {
                     //last index fetchNode will be input fetchNode.
                     lastIndexNode = node.getChild();
                     break;
@@ -252,7 +259,20 @@
     private void handleLeafInRid(YangSchemaNode preNode, ModelObjectId id,
                                  ResourceId.Builder builder, AtomicPath path) {
         //check leaf nodes in previous nodes.
-        YangSchemaNode curNode = fetchLeaf(preNode, fetchPackage(path));
+        String pkg = fetchPackage(path);
+        YangSchemaNode curNode = fetchLeaf(preNode, pkg);
+        if (curNode == null) {
+            if (preNode instanceof YangAugmentableNode) {
+                List<YangAugment> augments = ((YangAugmentableNode) preNode)
+                        .getAugmentedInfoList();
+                for (YangAugment augment : augments) {
+                    curNode = fetchLeaf(augment, pkg);
+                    if (curNode != null) {
+                        break;
+                    }
+                }
+            }
+        }
         if (curNode == null) {
             throw new ModelConvertorException("invalid model object id." + id);
         }
@@ -334,13 +354,7 @@
         while (node != null) {
             //compare the java package with the package found in model object
             // identifier.
-            if (node.getYangSchemaNodeType() == YANG_NON_DATA_NODE) {
-                while (node != null &&
-                        node.getYangSchemaNodeType() == YANG_NON_DATA_NODE) {
-                    node = node.getNextSibling();
-                }
-            }
-            if (node != null) {
+            if (node.getYangSchemaNodeType() != YANG_NON_DATA_NODE) {
                 java = getJavaPkg(node);
                 if (java.equals(pkg)) {
                     return node;
@@ -358,6 +372,9 @@
                     // check in next sibling node
                     node = node.getNextSibling();
                 }
+            } else {
+                // check in next sibling node
+                node = node.getNextSibling();
             }
         }
         return null;
@@ -405,4 +422,13 @@
     boolean isMoIdWithLeaf() {
         return isMoIdWithLeaf;
     }
+
+    /**
+     * Returns true if module node is found using input/output packages.
+     *
+     * @return true if module node is found using input/output packages
+     */
+    boolean isInputOrOutput() {
+        return isInputOrOutput;
+    }
 }
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java
index 945af8d..9cb0419 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultDataTreeBuilderTest.java
@@ -48,6 +48,7 @@
 import org.onosproject.yang.runtime.mockclass.testmodule.DefaultTestNotification;
 import org.onosproject.yang.runtime.mockclass.testmodule.testnotification.DefaultTestContainer;
 import org.onosproject.yang.runtime.mockclass.testmodule.testrpc.DefaultTestInput;
+import org.onosproject.yang.runtime.mockclass.testmodule.testrpc.DefaultTestOutput;
 
 import java.math.BigDecimal;
 import java.util.ArrayList;
@@ -940,7 +941,7 @@
     @Test
     public void processRpcWithInput() {
         MoIdToRscIdTest ut = new MoIdToRscIdTest();
-        ut.addMockModWithInput();
+        ut.addMockModWithRpc();
 
         data = new DefaultModelObjectData.Builder();
         mid = ModelObjectId.builder()
@@ -975,13 +976,95 @@
     /**
      * Unit test for a module containing rpc. Model object contains input
      * class so resource identifier will start from "/" and will go till
+     * rpc node.as object is given for input node so data node will be having
+     * input node.
+     */
+    @Test
+    public void processRpcWithInputDataNode() {
+        MoIdToRscIdTest ut = new MoIdToRscIdTest();
+        ut.addMockModWithRpc();
+
+        DefaultTestInput input = new DefaultTestInput();
+        input.testContainer(new DefaultTestContainer());
+        data = new DefaultModelObjectData.Builder();
+        data.addModelObject(input);
+
+        registry = ut.reg;
+        DefaultDataTreeBuilder builder = new DefaultDataTreeBuilder(registry);
+        rscData = builder.getResourceData(data.build());
+
+        nameSpace = "testNamespace";
+        id = rscData.resourceId();
+        keys = id.nodeKeys();
+        assertThat(2, is(keys.size()));
+
+        sid = keys.get(0).schemaId();
+        assertThat("/", is(sid.name()));
+        assertThat(null, is(sid.namespace()));
+
+        sid = keys.get(1).schemaId();
+        assertThat("test-rpc", is(sid.name()));
+        assertThat(nameSpace, is(sid.namespace()));
+
+        dataNodes = rscData.dataNodes();
+        assertThat(1, is(dataNodes.size()));
+
+        node = dataNodes.get(0);
+        validateDataNode(node, "input", nameSpace,
+                         SINGLE_INSTANCE_NODE,
+                         true, null);
+    }
+
+    /**
+     * Unit test for a module containing rpc. Model object contains input
+     * class so resource identifier will start from "/" and will go till
+     * rpc node.as object is given for output node so data node will be having
+     * input node.
+     */
+    @Test
+    public void processRpcWithOutputDataNode() {
+        MoIdToRscIdTest ut = new MoIdToRscIdTest();
+        ut.addMockModWithRpc();
+
+        data = new DefaultModelObjectData.Builder();
+        data.addModelObject(new DefaultTestOutput());
+
+        registry = ut.reg;
+        DefaultDataTreeBuilder builder = new DefaultDataTreeBuilder(registry);
+        rscData = builder.getResourceData(data.build());
+
+        nameSpace = "testNamespace";
+        id = rscData.resourceId();
+        keys = id.nodeKeys();
+        assertThat(2, is(keys.size()));
+
+        sid = keys.get(0).schemaId();
+        assertThat("/", is(sid.name()));
+        assertThat(null, is(sid.namespace()));
+
+        sid = keys.get(1).schemaId();
+        assertThat("test-rpc", is(sid.name()));
+        assertThat(nameSpace, is(sid.namespace()));
+
+        dataNodes = rscData.dataNodes();
+        assertThat(1, is(dataNodes.size()));
+
+        node = dataNodes.get(0);
+        validateDataNode(node, "output", nameSpace,
+                         SINGLE_INSTANCE_NODE,
+                         true, null);
+    }
+
+    /**
+     * Unit test for a module containing rpc. Model object contains input
+     * class so resource identifier will start from "/" and will go till
      * input node. it will contains rpc node as well. as object is given for
      * input node so data node will be for container node.
      */
     @Test
     public void processRpcWithInputModId() {
         MoIdToRscIdTest ut = new MoIdToRscIdTest();
-        ut.addMockModWithInput();
+        ut.addMockModWithRpc();
 
         data = new DefaultModelObjectData.Builder();
         mid = ModelObjectId.builder()
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistryTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistryTest.java
index da4a3cb..45419a1 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistryTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/DefaultYangModelRegistryTest.java
@@ -462,7 +462,7 @@
         provider.processSchemaRegistry();
         DefaultYangModelRegistry registry = provider.registry();
 
-        YangSchemaNode yangNode = registry.getForNameSpace(NAMESPACE);
+        YangSchemaNode yangNode = registry.getForNameSpace(NAMESPACE, false);
         assertThat(true, is(CHECK.equals(yangNode.getName())));
 
         YangRevision rev = ((YangNode) yangNode).getRevision();
diff --git a/runtime/src/test/java/org/onosproject/yang/runtime/impl/MoIdToRscIdTest.java b/runtime/src/test/java/org/onosproject/yang/runtime/impl/MoIdToRscIdTest.java
index 0d65cdd..371ad88 100644
--- a/runtime/src/test/java/org/onosproject/yang/runtime/impl/MoIdToRscIdTest.java
+++ b/runtime/src/test/java/org/onosproject/yang/runtime/impl/MoIdToRscIdTest.java
@@ -45,6 +45,9 @@
 import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.carrier.MultiplexesKeys;
 import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.carrier.multiplexes.ApplicationAreasKeys;
 import org.onosproject.yang.gen.v1.yms.test.ytb.tree.builder.yangautoprefixfor.yangautoprefixlist.having.yangautoprefixlist.rev20160826.ytbtreebuilderforlisthavinglist.carrier.multiplexes.DefaultApplicationAreas;
+import org.onosproject.yang.gen.v1.yrt.model.converter.model.data.to.resource.data.rev20160826.modeldatatoresourcedata.DefaultFirstLevel;
+import org.onosproject.yang.gen.v1.yrt.model.converter.model.data.to.resource.data.rev20160826.modeldatatoresourcedata.firstlevel.DefaultContainerLeaf;
+import org.onosproject.yang.gen.v1.yrt.model.converter.model.data.to.resource.data.rev20160826.modeldatatoresourcedata.firstlevel.containerleaf.AugmentedContainerLeaf;
 import org.onosproject.yang.model.KeyLeaf;
 import org.onosproject.yang.model.LeafListKey;
 import org.onosproject.yang.model.ListKey;
@@ -55,6 +58,7 @@
 import org.onosproject.yang.runtime.mockclass.testmodule.DefaultTestNotification;
 import org.onosproject.yang.runtime.mockclass.testmodule.testnotification.DefaultTestContainer;
 import org.onosproject.yang.runtime.mockclass.testmodule.testrpc.DefaultTestInput;
+import org.onosproject.yang.runtime.mockclass.testmodule.testrpc.DefaultTestOutput;
 import org.slf4j.Logger;
 
 import java.util.List;
@@ -92,11 +96,11 @@
     /**
      * Adds mock node in registry.
      */
-    void addMockModWithInput() {
+    void addMockModWithRpc() {
         setUp();
         YangModule mod = null;
         try {
-            mod = (YangModule) getModuleWithInput();
+            mod = (YangModule) getModuleWithRpc();
         } catch (DataModelException e) {
             log.info("test error");
         }
@@ -239,6 +243,32 @@
     }
 
     /**
+     * Unit test with current node having augmented leaf as model object
+     * identifier.
+     */
+    @Test
+    public void modIdWithAugmentLeaf() {
+        setUp();
+        mid = ModelObjectId.builder()
+                .addChild(DefaultFirstLevel.class)
+                .addChild(DefaultContainerLeaf.class)
+                .addChild(AugmentedContainerLeaf.LeafIdentifier.LEAFAUG)
+                .build();
+        rscId = builder.fetchResourceId(mid);
+
+        nodeKeys = rscId.nodeKeys();
+        assertThat(4, is(nodeKeys.size()));
+
+        sid = nodeKeys.get(0).schemaId();
+        assertThat("/", is(sid.name()));
+        assertThat(null, is(sid.namespace()));
+
+        sid = nodeKeys.get(1).schemaId();
+        assertThat("first-level", is(sid.name()));
+        assertThat("yrt:model:converter:model:data:to:resource:data", is(sid.namespace()));
+    }
+
+    /**
      * Unit test case for model object identifier as list with leaf.
      */
     @Test
@@ -276,7 +306,7 @@
      */
     @Test
     public void moIdWithInput() {
-        addMockModWithInput();
+        addMockModWithRpc();
 
         mid = new ModelObjectId.Builder()
                 .addChild(DefaultTestInput.class).build();
@@ -299,11 +329,11 @@
     }
 
     /**
-     * Unit test case for model object identifier input with leaf.
+     * Unit test case for model object identifier input with container.
      */
     @Test
     public void moIdWithInputAndContainer() {
-        addMockModWithInput();
+        addMockModWithRpc();
 
         mid = new ModelObjectId.Builder()
                 .addChild(DefaultTestInput.class)
@@ -333,6 +363,34 @@
     }
 
     /**
+     * Unit test case for model object identifier output.
+     */
+    @Test
+    public void moIdWithOutput() {
+        addMockModWithRpc();
+
+        mid = new ModelObjectId.Builder()
+                .addChild(DefaultTestOutput.class)
+                .build();
+
+        rscId = builder.fetchResourceId(mid);
+        nodeKeys = rscId.nodeKeys();
+        assertThat(3, is(nodeKeys.size()));
+
+        sid = nodeKeys.get(0).schemaId();
+        assertThat("/", is(sid.name()));
+        assertThat(null, is(sid.namespace()));
+
+        sid = nodeKeys.get(1).schemaId();
+        assertThat("test-rpc", is(sid.name()));
+        assertThat("testNamespace", is(sid.namespace()));
+
+        sid = nodeKeys.get(2).schemaId();
+        assertThat("output", is(sid.name()));
+        assertThat("testNamespace", is(sid.namespace()));
+    }
+
+    /**
      * Unit test case for model object identifier as notification.
      */
     @Test
@@ -356,7 +414,8 @@
     }
 
     /**
-     * Unit test case for model object identifier as notification with leaf.
+     * Unit test case for model object identifier as notification with
+     * container.
      */
     @Test
     public void moIdWithNotificationAndContainer() {
@@ -643,7 +702,7 @@
      * @return mock node tree with module, rpc, input and output
      * @throws DataModelException when fails to do data model operations
      */
-    private YangNode getModuleWithInput() throws DataModelException {
+    private YangNode getModuleWithRpc() throws DataModelException {
         YangModule mod = getYangModule();
         YangRpc rpc = getRpcNode();
         mod.addChild(rpc);
@@ -794,7 +853,6 @@
             }
         };
         out.setName("output");
-        out.addLeaf(getLeafNode());
         out.setNameSpace(getMockNamespace());
         return out;
     }
diff --git a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
index 1f53ac5..678d88b 100644
--- a/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
+++ b/serializers/xml/src/test/java/org/onosproject/yang/serializers/xml/XmlSerializerTest.java
@@ -214,32 +214,6 @@
     }
 
     /**
-     * Validates data node in which XML element is child of YANG grouping.
-     */
-    @Test
-    public void testGroupingUsesDataNode() {
-        String path = "src/test/resources/testGroupingUses.xml";
-
-        String uri = "urn:ietf:params:xml:ns:yang:yrt-ietf-network:networks-state/network";
-        DefaultCompositeStream external =
-                new DefaultCompositeStream(uri, parseInput(path));
-        CompositeData compositeData = xmlSerializer.decode(external, context);
-        ResourceData resourceData = compositeData.resourceData();
-        List<DataNode> dataNodes = resourceData.dataNodes();
-        LeafNode dataNode = ((LeafNode) dataNodes.get(0));
-        SchemaId schemaId = dataNode.key().schemaId();
-        assertThat(schemaId.name(), is("network-ref"));
-        assertThat(schemaId.namespace(), is("urn:ietf:params:xml:ns:yang:yrt-ietf-network"));
-        assertThat(dataNode.value().toString(), is("abc"));
-
-        // encode test
-        CompositeStream compositeStream = xmlSerializer.encode(compositeData,
-                                                               context);
-        InputStream inputStream = compositeStream.resourceData();
-        assertThat(convertInputStreamToString(inputStream), is(parseXml(path)));
-    }
-
-    /**
      * Validates whether XML attributes is converted to annotations.
      */
     @Test
diff --git a/serializers/xml/src/test/resources/testGroupingUses.xml b/serializers/xml/src/test/resources/testGroupingUses.xml
deleted file mode 100644
index 45d3d05..0000000
--- a/serializers/xml/src/test/resources/testGroupingUses.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<network-ref xmlns="urn:ietf:params:xml:ns:yang:yrt-ietf-network">abc
-</network-ref>
\ No newline at end of file