manager: Take pre/post actions in recollection

The manager code triggers a VPD recollection for applicable FRUs.
Before we trigger the recollection, we need to perform any pre-actions
in order to setup the VPD address and/or check presence.

This commit adds a call to an existing API that performs pre-actions
just before triggering VPD recollection for the given FRU.

Signed-off-by: Santosh Puranik <santosh.puranik@in.ibm.com>
Change-Id: Ic1d7d2d727729751d62ce352d4c4fe0d3ad30338
diff --git a/vpd-manager/manager.cpp b/vpd-manager/manager.cpp
index d391a0b..1602473 100644
--- a/vpd-manager/manager.cpp
+++ b/vpd-manager/manager.cpp
@@ -9,6 +9,7 @@
 #include "reader_impl.hpp"
 #include "vpd_exceptions.hpp"
 
+#include <filesystem>
 #include <phosphor-logging/elog-errors.hpp>
 
 using namespace openpower::vpd::manager;
@@ -260,6 +261,25 @@
             singleFru["inventoryPath"]
                 .get_ref<const nlohmann::json::string_t&>();
 
+        bool prePostActionRequired = false;
+
+        if ((jsonFile["frus"][item].at(0)).find("preAction") !=
+            jsonFile["frus"][item].at(0).end())
+        {
+            if (!executePreAction(jsonFile, item))
+            {
+                // if the FRU has preAction defined then its execution should
+                // pass to ensure bind/unbind of data.
+                // preAction execution failed. should not call bind/unbind.
+                log<level::ERR>(
+                    "Pre-Action execution failed for the FRU",
+                    entry("ERROR=%s",
+                          ("Inventory path: " + inventoryPath).c_str()));
+                continue;
+            }
+            prePostActionRequired = true;
+        }
+
         if ((singleFru.find("devAddress") == singleFru.end()) ||
             (singleFru.find("driverType") == singleFru.end()) ||
             (singleFru.find("busType") == singleFru.end()))
@@ -318,6 +338,18 @@
             executeCmd(createBindUnbindDriverCmnd(deviceAddress, busType,
                                                   driverType, "/bind"));
         }
+
+        // this check is added to avoid file system expensive call in case not
+        // required.
+        if (prePostActionRequired)
+        {
+            // Check if device showed up (test for file)
+            if (!filesystem::exists(item))
+            {
+                // If not, then take failure postAction
+                executePostFailAction(jsonFile, item);
+            }
+        }
     }
 }