Prime FRUs if only required

As vpd-manager primes the FRUs listed in the system config JSON on each
system boot, which takes significant time.

To improve the efficiency, this commit implements priming of FRUs only
if the Dbus object paths having “com.ibm.VPD.Collection" interface
count does not match with the inventoryPaths count from the system
config JSON.

Change-Id: I506503b8e8ad64342352a9aae3c889b9fd5a22d8
Signed-off-by: Anupama B R <anupama.b.r1@ibm.com>
diff --git a/vpd-manager/oem-handler/ibm_handler.cpp b/vpd-manager/oem-handler/ibm_handler.cpp
index 250f815..49fafe2 100644
--- a/vpd-manager/oem-handler/ibm_handler.cpp
+++ b/vpd-manager/oem-handler/ibm_handler.cpp
@@ -586,7 +586,10 @@
             // here.
             m_sysCfgJsonObj = m_worker->getSysCfgJsonObj();
 
-            primeSystemBlueprint();
+            if (isPrimingRequired())
+            {
+                primeSystemBlueprint();
+            }
         }
 
         // Enable all mux which are used for connecting to the i2c on the
@@ -609,4 +612,44 @@
     }
 }
 
+bool IbmHandler::isPrimingRequired() const noexcept
+{
+    try
+    {
+        // get all object paths under PIM
+        const auto l_objectPaths = dbusUtility::GetSubTreePaths(
+            constants::systemInvPath, 0,
+            std::vector<std::string>{constants::vpdCollectionInterface});
+
+        const nlohmann::json& l_listOfFrus =
+            m_sysCfgJsonObj["frus"].get_ref<const nlohmann::json::object_t&>();
+
+        size_t l_invPathCount = 0;
+
+        for (const auto& l_itemFRUS : l_listOfFrus.items())
+        {
+            for (const auto& l_Fru : l_itemFRUS.value())
+            {
+                if (l_Fru.contains("ccin") || (l_Fru.contains("noprime") &&
+                                               l_Fru.value("noprime", false)))
+                {
+                    continue;
+                }
+
+                l_invPathCount += 1;
+            }
+        }
+        return ((l_objectPaths.size() >= l_invPathCount) ? false : true);
+    }
+    catch (const std::exception& l_ex)
+    {
+        logging::logMessage(
+            "Error while checking is priming required or not, error: " +
+            std::string(l_ex.what()));
+    }
+
+    // In case of any error, perform priming, as it's unclear whether priming is
+    // required.
+    return true;
+}
 } // namespace vpd
diff --git a/vpd-manager/oem-handler/ibm_handler.hpp b/vpd-manager/oem-handler/ibm_handler.hpp
index 3a6ea42..a397f06 100644
--- a/vpd-manager/oem-handler/ibm_handler.hpp
+++ b/vpd-manager/oem-handler/ibm_handler.hpp
@@ -145,6 +145,19 @@
      */
     void enableMuxChips();
 
+    /**
+     * @brief API to check if priming is required.
+     *
+     * The API will traverse the system config JSON and counts the FRU
+     * paths which qualifies for priming and compares with count of object paths
+     * found under PIM which hosts the "com.ibm.VPD.Collection" interface. If
+     * the dbus count is equal to or greater than the count from JSON config
+     * consider as priming is not required.
+     *
+     * @return true if priming is required, false otherwise.
+     */
+    bool isPrimingRequired() const noexcept;
+
     // Parsed system config json object.
     nlohmann::json m_sysCfgJsonObj{};