Merge "[ONOS-7095] Initial changes to identify inter-jar node during model registration"
diff --git a/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangCompilerManager.java b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangCompilerManager.java
index 296dd7d..5b21e83 100644
--- a/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangCompilerManager.java
+++ b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangCompilerManager.java
@@ -104,28 +104,26 @@
      * Returns YANG model for application.
      *
      * @param path    path for metadata file
-     * @param list    list of YANG node
+     * @param info    list of YANG node info
      * @param modelId model id
      * @param fromUt  if method is called from unit test
      * @return YANG model
-     * @throws IOException when fails to IO operations
      */
     public static YangModel processYangModel(
-            String path, List<YangNode> list, String modelId, boolean fromUt)
-            throws IOException {
+            String path, List<YangNodeInfo> info, String modelId, boolean fromUt) {
         YangModel.Builder b = DefaultYangModel.builder();
         YangModuleId id;
-        for (YangNode node : list) {
-            id = processModuleId(node);
+        for (YangNodeInfo i : info) {
+            id = processModuleId(i.getNode());
             String serFile = path + id.moduleName() + id.revision() + ".ser";
             if (!fromUt) {
-                serializeModuleMetaData(serFile, node);
+                serializeModuleMetaData(serFile, i.getNode());
             }
             //take the absolute jar path and make a new path for our yang files.
-            String fileName = getFileName(node.getFileName());
+            String fileName = getFileName(i.getNode().getFileName());
             YangModuleExtendedInfo module = new YangModuleExtendedInfo(
-                    id, new File(path + fileName), new File(serFile));
-            module.setSchema(node);
+                    id, new File(path + fileName), new File(serFile), i.isInterJar());
+            module.setSchema(i.getNode());
             b.addModule(id, module);
         }
         return b.addModelId(modelId).build();
@@ -147,15 +145,13 @@
      *
      * @param serFileName path of resource directory
      * @param node        YangNode
-     * @throws IOException when fails to IO operations
      */
-    private static void serializeModuleMetaData(String serFileName, YangNode node)
-            throws IOException {
+    private static void serializeModuleMetaData(String serFileName, YangNode node) {
         try (FileOutputStream outStream = new FileOutputStream(serFileName);
              ObjectOutputStream objOutStream = new ObjectOutputStream(outStream)) {
             objOutStream.writeObject(node);
         } catch (IOException e) {
-            e.printStackTrace();
+            log.info("Error while serializing YANG node", e);
         }
     }
 
@@ -224,8 +220,7 @@
                 createDirectories(resourceGenDir);
 
                 // Resolve inter jar dependency.
-                addSchemaToFileSet(dependentSchema(
-                        param.getDependentSchemas()));
+                addSchemaToFileSet(dependentSchema(param.getDependentSchemas()));
 
                 // Carry out the parsing for all the YANG files.
                 parseYangFileInfoSet();
@@ -306,10 +301,8 @@
      * Resolved inter-jar dependencies.
      *
      * @param dependentSchema dependent schema list
-     * @throws IOException when fails to do IO operations
      */
-    private void addSchemaToFileSet(Set<YangNode> dependentSchema)
-            throws IOException {
+    private void addSchemaToFileSet(Set<YangNode> dependentSchema) {
         if (dependentSchema == null || dependentSchema.isEmpty()) {
             return;
         }
@@ -320,6 +313,7 @@
             dependentFileInfo.setRootNode(node);
             dependentFileInfo.setForTranslator(false);
             dependentFileInfo.setYangFileName(node.getName());
+            dependentFileInfo.setInterJar(true);
             yangFileInfoSet.add(dependentFileInfo);
         }
     }
@@ -431,11 +425,10 @@
      * @param id   model id
      * @throws IOException when fails to IO operations
      */
-    public void processSerialization(String path, String id) throws
-            IOException {
-        List<YangNode> nodelist = new ArrayList<>();
-        nodelist.addAll(yangNodeSet);
-        model = processYangModel(path, nodelist, id, false);
+    public void processSerialization(String path, String id) throws IOException {
+        List<YangNodeInfo> nodeInfo = new ArrayList<>();
+        setNodeInfo(yangFileInfoSet, nodeInfo);
+        model = processYangModel(path, nodeInfo, id, false);
         String serFileName = path + YANG_META_DATA;
         try (FileOutputStream fileOutputStream = new FileOutputStream(serFileName);
              ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream)) {
@@ -443,6 +436,45 @@
         }
     }
 
+    private void setNodeInfo(Set<YangFileInfo> yangFileInfoSet,
+        List<YangNodeInfo> infos) {
+        for (YangFileInfo i : yangFileInfoSet) {
+            infos.add(new YangNodeInfo(i.getRootNode(), i.isInterJar()));
+        }
+    }
+
+    /**
+     * Returns YANG model for serialization.
+     *
+     * @param path    path for metadata file
+     * @param list    set of YANG file info
+     * @param modelId model id
+     * @param fromUt  if method is called from unit test
+     * @return YANG model
+     */
+    private static YangModel getModelForSerialization(
+        String path, Set<YangFileInfo> list, String modelId, boolean fromUt) {
+        YangModel.Builder b = DefaultYangModel.builder();
+        YangModuleId id;
+        boolean interJar;
+
+        for (YangFileInfo info : list) {
+            YangNode node = info.getRootNode();
+            id = processModuleId(node);
+            interJar = info.isInterJar();
+            String serFile = path + id.moduleName() + id.revision() + ".ser";
+            if (!fromUt) {
+                serializeModuleMetaData(serFile, node);
+            }
+            //take the absolute jar path and make a new path for our yang files.
+            String fileName = getFileName(node.getFileName());
+            YangModuleExtendedInfo module = new YangModuleExtendedInfo(
+                id, new File(path + fileName), new File(serFile), interJar);
+            module.setSchema(node);
+            b.addModule(id, module);
+        }
+        return b.addModelId(modelId).build();
+    }
     /**
      * Copies yang files to resource directory.
      *
@@ -542,6 +574,19 @@
     }
 
     /**
+     * Sets YANG node info.
+     *
+     * @param model YANG model
+     * @param infos node info to be filled
+     */
+    public static void setNodeInfo(YangModel model, List<YangNodeInfo> infos) {
+        for (YangModule m : model.getYangModules()) {
+            YangModuleExtendedInfo i = (YangModuleExtendedInfo) m;
+            infos.add(new YangNodeInfo(i.getSchema(), i.isInterJar()));
+        }
+    }
+
+    /**
      * Parses jar file and returns YANG model.
      *
      * @param jarFile   jar file to be parsed
diff --git a/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangFileInfo.java b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangFileInfo.java
index e0d89ce..6b169fb 100644
--- a/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangFileInfo.java
+++ b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangFileInfo.java
@@ -17,9 +17,8 @@
 package org.onosproject.yang.compiler.tool;
 
 
-import org.onosproject.yang.compiler.datamodel.YangNode;
-
 import java.util.Objects;
+import org.onosproject.yang.compiler.datamodel.YangNode;
 
 /**
  * Represents YANG file information.
@@ -42,6 +41,11 @@
     private boolean isForTranslator = true;
 
     /**
+     * Flag to know if the root node is an inter-jar node.
+     */
+    private boolean isInterJar;
+
+    /**
      * Returns data model node for YANG file.
      *
      * @return data model node for YANG file
@@ -95,6 +99,24 @@
         this.isForTranslator = isForTranslator;
     }
 
+    /**
+     * Return true if node is inter-jar node.
+     *
+     * @return true if inter-jar, false otherwise
+     */
+    public boolean isInterJar() {
+        return isInterJar;
+    }
+
+    /**
+     * Sets true if it's inter-jar node.
+     *
+     * @param interJar flag indicating if it's inter-jar node
+     */
+    public void setInterJar(boolean interJar) {
+        isInterJar = interJar;
+    }
+
     @Override
     public boolean equals(Object obj) {
 
diff --git a/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangModuleExtendedInfo.java b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangModuleExtendedInfo.java
index 8b3977e..0eaf59c 100644
--- a/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangModuleExtendedInfo.java
+++ b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangModuleExtendedInfo.java
@@ -29,6 +29,7 @@
 public class YangModuleExtendedInfo extends DefaultYangModule implements Serializable {
 
     private YangNode schema;
+    private boolean interJar;
 
     /**
      * Creates an instance of YANG module extended information.
@@ -36,12 +37,12 @@
      * @param id       module id
      * @param yangSrc  YANG resource path
      * @param metadata meta data resource path
+     * @param interJar flag indicating if module is from inter-jar
      */
-    public YangModuleExtendedInfo(YangModuleId id, File yangSrc, File metadata) {
+    public YangModuleExtendedInfo(YangModuleId id, File yangSrc, File metadata, boolean interJar) {
         super(id, yangSrc, metadata);
     }
 
-
     /**
      * Returns schema info for module.
      *
@@ -59,4 +60,22 @@
     public void setSchema(YangNode schema) {
         this.schema = schema;
     }
+
+    /**
+     * Returns true if it's inter-jar node.
+     *
+     * @return true if inter-jar node, false otherwise
+     */
+    public boolean isInterJar() {
+        return interJar;
+    }
+
+    /**
+     * Sets true if it's inter-jar node.
+     *
+     * @param interJar true if inter-jar node, false otherwise
+     */
+    public void interJar(boolean interJar) {
+        this.interJar = interJar;
+    }
 }
diff --git a/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangNodeInfo.java b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangNodeInfo.java
new file mode 100644
index 0000000..32c72e2
--- /dev/null
+++ b/compiler/base/tool/src/main/java/org/onosproject/yang/compiler/tool/YangNodeInfo.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2017-present Open Networking Foundation
+ *
+ * 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.compiler.tool;
+
+import org.onosproject.yang.compiler.datamodel.YangNode;
+
+/**
+ * Represents YANG node information.
+ */
+public class YangNodeInfo {
+
+    private YangNode node;
+    private boolean interJar;
+
+    /**
+     * Creates an instance of YANG node info.
+     *
+     * @param node YANG node
+     * @param interJar flag indicating if it's inter-jar node
+     */
+    public YangNodeInfo(YangNode node, boolean interJar) {
+        this.node = node;
+        this.interJar = interJar;
+    }
+
+    /**
+     * Returns YANG node.
+     *
+     * @return YANG node
+     */
+    public YangNode getNode() {
+        return node;
+    }
+
+    /**
+     * Returns true if inter jar.
+     *
+     * @return true if inter-jar, false otherwise
+     */
+    public boolean isInterJar() {
+        return interJar;
+    }
+}
diff --git a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/InterJarLinkerTest.java b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/InterJarLinkerTest.java
index fe5343a..5c99c57 100644
--- a/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/InterJarLinkerTest.java
+++ b/compiler/plugin/maven/src/test/java/org/onosproject/yang/compiler/plugin/maven/InterJarLinkerTest.java
@@ -25,6 +25,7 @@
 import org.onosproject.yang.compiler.datamodel.YangNode;
 import org.onosproject.yang.compiler.tool.YangCompilerManager;
 import org.onosproject.yang.compiler.tool.YangFileInfo;
+import org.onosproject.yang.compiler.tool.YangNodeInfo;
 import org.onosproject.yang.compiler.utils.io.YangPluginConfig;
 import org.onosproject.yang.model.YangModel;
 
@@ -279,10 +280,11 @@
 
         createDirectories(TARGET_RESOURCE_PATH);
 
-        List<YangNode> nodes = new ArrayList<>();
-        nodes.addAll(utilManager.getYangNodeSet());
+        List<YangNodeInfo> nodeInfo = new ArrayList<>();
+        setNodeInfo(utilManager.getYangFileInfoSet(), nodeInfo);
+
         //process model which will have only port pair node.
-        processYangModel(TARGET_RESOURCE_PATH, nodes, id, false);
+        processYangModel(TARGET_RESOURCE_PATH, nodeInfo, id, false);
 
         //create a test jar file.
         provideTestJarFile(name);
@@ -295,6 +297,13 @@
         utilManager.getYangNodeSet().remove(node);
     }
 
+    private void setNodeInfo(Set<YangFileInfo> yangFileInfoSet,
+        List<YangNodeInfo> infos) {
+        for (YangFileInfo i : yangFileInfoSet) {
+            infos.add(new YangNodeInfo(i.getRootNode(), i.isInterJar()));
+        }
+    }
+
     /**
      * Test if flow classifier code is generated.
      */
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/YangApacheUtils.java b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/YangApacheUtils.java
index b75ad53..68ee7be 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/YangApacheUtils.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/helperutils/YangApacheUtils.java
@@ -16,23 +16,22 @@
 
 package org.onosproject.yang.runtime.helperutils;
 
-import org.onosproject.yang.compiler.datamodel.YangNode;
-import org.onosproject.yang.model.YangModel;
-import org.osgi.framework.Bundle;
-import org.osgi.framework.BundleContext;
-import org.slf4j.Logger;
+import static org.onosproject.yang.compiler.tool.YangCompilerManager.parseJarFile;
+import static org.onosproject.yang.compiler.tool.YangCompilerManager.processYangModel;
+import static org.onosproject.yang.compiler.tool.YangCompilerManager.setNodeInfo;
+import static org.osgi.framework.FrameworkUtil.getBundle;
+import static org.slf4j.LoggerFactory.getLogger;
 
 import java.io.File;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.regex.Pattern;
-
-import static org.onosproject.yang.compiler.tool.YangCompilerManager.getYangNodes;
-import static org.onosproject.yang.compiler.tool.YangCompilerManager.parseJarFile;
-import static org.onosproject.yang.compiler.tool.YangCompilerManager.processYangModel;
-import static org.osgi.framework.FrameworkUtil.getBundle;
-import static org.slf4j.LoggerFactory.getLogger;
+import org.onosproject.yang.compiler.tool.YangNodeInfo;
+import org.onosproject.yang.model.YangModel;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.BundleContext;
+import org.slf4j.Logger;
 
 /**
  * Utilities for runtime to use apache tools.
@@ -63,7 +62,7 @@
         BundleContext context = getBundle(modClass).getBundleContext();
         if (context != null) {
             Bundle bundle = context.getBundle();
-            List<YangNode> curNodes = new ArrayList<>();
+            List<YangNodeInfo> nodeInfo = new ArrayList<>();
             String jarPath;
             String metaPath;
             jarPath = getJarPathFromBundleLocation(
@@ -71,16 +70,11 @@
             metaPath = jarPath + SLASH + YANG_RESOURCES + SLASH;
             YangModel model = processJarParsingOperations(jarPath);
             if (model != null) {
-                curNodes.addAll(getYangNodes(model));
+                setNodeInfo(model, nodeInfo);
                 // process model creations.
-                if (!curNodes.isEmpty()) {
-                    try {
-                        return processYangModel(metaPath, curNodes,
+                if (!nodeInfo.isEmpty()) {
+                      return processYangModel(metaPath, nodeInfo,
                                                 model.getYangModelId(), false);
-                    } catch (IOException e) {
-                        log.error(" failed to create process YANG model " +
-                                          e.getMessage(), e);
-                    }
                 }
             }
         }
diff --git a/runtime/src/main/java/org/onosproject/yang/runtime/impl/MockYangSchemaNodeProvider.java b/runtime/src/main/java/org/onosproject/yang/runtime/impl/MockYangSchemaNodeProvider.java
index b6609f2..a4d976e 100644
--- a/runtime/src/main/java/org/onosproject/yang/runtime/impl/MockYangSchemaNodeProvider.java
+++ b/runtime/src/main/java/org/onosproject/yang/runtime/impl/MockYangSchemaNodeProvider.java
@@ -18,6 +18,7 @@
 
 import org.onosproject.yang.compiler.datamodel.YangNode;
 import org.onosproject.yang.compiler.datamodel.YangSchemaNode;
+import org.onosproject.yang.compiler.tool.YangNodeInfo;
 import org.onosproject.yang.model.YangModel;
 import org.onosproject.yang.runtime.ModelRegistrationParam;
 
@@ -98,19 +99,22 @@
         //Create model registration param.
         ModelRegistrationParam.Builder b = builder();
 
-        //create a new YANG model
-        YangModel model = null;
-        try {
-            model = processYangModel(META_PATH, nodes, id, true);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
+        List<YangNodeInfo> nodeInfo = new ArrayList<>();
+        setNodeInfo(nodes, nodeInfo);
+        YangModel model = processYangModel(META_PATH, nodeInfo, id, true);
 
         //set YANG model
         b.setYangModel(model);
         return b.build();
     }
 
+    private static void setNodeInfo(List<YangNode> nodes, List<YangNodeInfo> nodeInfos) {
+        for (YangNode node : nodes) {
+            YangNodeInfo nodeInfo = new YangNodeInfo(node, false);
+            nodeInfos.add(nodeInfo);
+        }
+    }
+
     static YangModel processModelTest() {
         YangModel model = null;
         try {
@@ -118,7 +122,9 @@
             Set<YangNode> appNode = getYangNodes(model);
             List<YangNode> nodes = new ArrayList<>();
             nodes.addAll(appNode);
-            return processYangModel(META_PATH, nodes, id, false);
+            List<YangNodeInfo> nodeInfo = new ArrayList<>();
+            setNodeInfo(nodes, nodeInfo);
+            return processYangModel(META_PATH, nodeInfo, id, false);
         } catch (IOException e) {
             e.printStackTrace();
         }