Collect all FRUs VPD Dbus method in vpd-manager

This commit adds code to expose new dbus method CollectAllFRUVPD under
vpd-manager service for VPD collection for all the FRUs present in the
system config JSON.

Change-Id: I393ffc15d684d6a0934d12a7f4bc1e23fdda054d
Signed-off-by: Anupama B R <anupama.b.r1@ibm.com>
diff --git a/vpd-manager/include/manager.hpp b/vpd-manager/include/manager.hpp
index 120b4bb..88e328b 100644
--- a/vpd-manager/include/manager.hpp
+++ b/vpd-manager/include/manager.hpp
@@ -219,6 +219,21 @@
     std::tuple<std::string, uint16_t> getUnexpandedLocationCode(
         const std::string& i_expandedLocationCode);
 
+    /**
+     * @brief API to collect all FRUs VPD.
+     *
+     * This api will call OEM handler API to perform VPD collection for all FRUs
+     * present in the system config JSON.
+     *
+     * Note:
+     * System VPD collection will always be skipped.
+     * If host is in power on state, FRUs marked as 'powerOffOnly' in the
+     * system config JSON will be skipped.
+     *
+     * @return true on successful request made, false otherwise.
+     */
+    bool collectAllFruVpd() const noexcept;
+
   private:
     /**
      * @brief An api to check validity of unexpanded location code.
diff --git a/vpd-manager/oem-handler/ibm_handler.cpp b/vpd-manager/oem-handler/ibm_handler.cpp
index 60b0ee8..277b499 100644
--- a/vpd-manager/oem-handler/ibm_handler.cpp
+++ b/vpd-manager/oem-handler/ibm_handler.cpp
@@ -532,4 +532,12 @@
     // required.
     return true;
 }
+
+void IbmHandler::collectAllFruVpd()
+{
+    // Setting status to "InProgress", before trigeering VPD collection.
+    m_interface->set_property("CollectionStatus", std::string("InProgress"));
+    m_worker->collectFrusFromJson();
+    SetTimerToDetectVpdCollectionStatus();
+}
 } // namespace vpd
diff --git a/vpd-manager/oem-handler/ibm_handler.hpp b/vpd-manager/oem-handler/ibm_handler.hpp
index 68f021a..74429a2 100644
--- a/vpd-manager/oem-handler/ibm_handler.hpp
+++ b/vpd-manager/oem-handler/ibm_handler.hpp
@@ -44,6 +44,22 @@
         const std::shared_ptr<boost::asio::io_context>& i_ioCon,
         const std::shared_ptr<sdbusplus::asio::connection>& i_asioConnection);
 
+    /**
+     * @brief API to collect all FRUs VPD.
+     *
+     * This api will call worker API to perform VPD collection for all FRUs
+     * present in the system config JSON and publish it on DBus. Also updates
+     * the Dbus VPD collection status property hosted under vpd-manager.
+     *
+     * Note:
+     * System VPD collection will always be skipped.
+     * If host is in power on state, FRUs marked as 'powerOffOnly' in the
+     * system config JSON will be skipped.
+     *
+     * @throw JsonException, runtime_error
+     */
+    void collectAllFruVpd();
+
   private:
     /**
      * @brief API to set timer to detect system VPD over D-Bus.
diff --git a/vpd-manager/src/manager.cpp b/vpd-manager/src/manager.cpp
index f57596c..89283df 100644
--- a/vpd-manager/src/manager.cpp
+++ b/vpd-manager/src/manager.cpp
@@ -121,6 +121,10 @@
             this->performVpdRecollection();
         });
 
+        iFace->register_method("CollectAllFRUVPD", [this]() -> bool {
+            return this->collectAllFruVpd();
+        });
+
         // Indicates FRU VPD collection for the system has not started.
         iFace->register_property_rw<std::string>(
             "CollectionStatus", sdbusplus::vtable::property_::emits_change,
@@ -603,4 +607,51 @@
         m_worker->performVpdRecollection();
     }
 }
+
+bool Manager::collectAllFruVpd() const noexcept
+{
+    try
+    {
+        types::SeverityType l_severityType;
+        if (m_vpdCollectionStatus == "NotStarted")
+        {
+            l_severityType = types::SeverityType::Informational;
+        }
+        else if (m_vpdCollectionStatus == "Completed" ||
+                 m_vpdCollectionStatus == "Failure")
+        {
+            l_severityType = types::SeverityType::Warning;
+        }
+        else
+        {
+            throw std::runtime_error(
+                "Invalid collection status " + m_vpdCollectionStatus +
+                ". Aborting all FRUs VPD collection.");
+        }
+
+        EventLogger::createSyncPel(
+            types::ErrorType::FirmwareError, l_severityType, __FILE__,
+            __FUNCTION__, 0, "Collect all FRUs VPD is requested.", std::nullopt,
+            std::nullopt, std::nullopt, std::nullopt);
+
+        if (m_ibmHandler.get() != nullptr)
+        {
+            m_ibmHandler->collectAllFruVpd();
+            return true;
+        }
+        else
+        {
+            throw std::runtime_error(
+                "Not found any OEM handler to collect all FRUs VPD.");
+        }
+    }
+    catch (const std::exception& l_ex)
+    {
+        EventLogger::createSyncPel(
+            EventLogger::getErrorType(l_ex), types::SeverityType::Warning,
+            __FILE__, __FUNCTION__, 0, std::string(l_ex.what()), std::nullopt,
+            std::nullopt, std::nullopt, std::nullopt);
+    }
+    return false;
+}
 } // namespace vpd