Use getAssetInfo util function

This commit is to use getAssetInfo utility function for GET AssetInfo in
various places like

- Chassis
- FabricAdapter
  This will also include `Manufacturer` property if available on dbus.
- Fan
- PCIeDevice
- PowerSupply
- Storage
- System

Tested:
- GET the above schemas
- Redfish Service Validator passes

Change-Id: I9d01d583212fe4916d5fdd144d2b8e52ad865d16
Signed-off-by: Myung Bae <myungbae@us.ibm.com>
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index e2fadba..afef198 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -18,6 +18,7 @@
 #include "logging.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
+#include "utils/asset_utils.hpp"
 #include "utils/chassis_utils.hpp"
 #include "utils/collection.hpp"
 #include "utils/dbus_utils.hpp"
@@ -418,49 +419,8 @@
     const std::string& chassisId, const std::string& path,
     const dbus::utility::DBusPropertiesMap& propertiesList)
 {
-    const std::string* partNumber = nullptr;
-    const std::string* serialNumber = nullptr;
-    const std::string* manufacturer = nullptr;
-    const std::string* model = nullptr;
-    const std::string* sparePartNumber = nullptr;
-
-    const bool success = sdbusplus::unpackPropertiesNoThrow(
-        dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
-        partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
-        "Model", model, "SparePartNumber", sparePartNumber);
-
-    if (!success)
-    {
-        messages::internalError(asyncResp->res);
-        return;
-    }
-
-    if (partNumber != nullptr)
-    {
-        asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-    }
-
-    if (serialNumber != nullptr)
-    {
-        asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-    }
-
-    if (manufacturer != nullptr)
-    {
-        asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
-    }
-
-    if (model != nullptr)
-    {
-        asyncResp->res.jsonValue["Model"] = *model;
-    }
-
-    // SparePartNumber is optional on D-Bus
-    // so skip if it is empty
-    if (sparePartNumber != nullptr && !sparePartNumber->empty())
-    {
-        asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
-    }
+    asset_utils::extractAssetInfo(asyncResp, ""_json_pointer, propertiesList,
+                                  true);
 
     asyncResp->res.jsonValue["Name"] = chassisId;
     asyncResp->res.jsonValue["Id"] = chassisId;
diff --git a/redfish-core/lib/fabric_adapters.hpp b/redfish-core/lib/fabric_adapters.hpp
index 532da5f..7d20302 100644
--- a/redfish-core/lib/fabric_adapters.hpp
+++ b/redfish-core/lib/fabric_adapters.hpp
@@ -14,6 +14,7 @@
 #include "logging.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
+#include "utils/asset_utils.hpp"
 #include "utils/collection.hpp"
 #include "utils/dbus_utils.hpp"
 #include "utils/json_utils.hpp"
@@ -62,64 +63,6 @@
         });
 }
 
-inline void getFabricAdapterAsset(
-    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-    const std::string& serviceName, const std::string& fabricAdapterPath)
-{
-    dbus::utility::getAllProperties(
-        serviceName, fabricAdapterPath,
-        "xyz.openbmc_project.Inventory.Decorator.Asset",
-        [fabricAdapterPath, asyncResp{asyncResp}](
-            const boost::system::error_code& ec,
-            const dbus::utility::DBusPropertiesMap& propertiesList) {
-            if (ec)
-            {
-                if (ec.value() != EBADR)
-                {
-                    BMCWEB_LOG_ERROR("DBUS response error for Properties");
-                    messages::internalError(asyncResp->res);
-                }
-                return;
-            }
-
-            const std::string* serialNumber = nullptr;
-            const std::string* model = nullptr;
-            const std::string* partNumber = nullptr;
-            const std::string* sparePartNumber = nullptr;
-
-            const bool success = sdbusplus::unpackPropertiesNoThrow(
-                dbus_utils::UnpackErrorPrinter(), propertiesList,
-                "SerialNumber", serialNumber, "Model", model, "PartNumber",
-                partNumber, "SparePartNumber", sparePartNumber);
-
-            if (!success)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            if (serialNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-            }
-
-            if (model != nullptr)
-            {
-                asyncResp->res.jsonValue["Model"] = *model;
-            }
-
-            if (partNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-            }
-
-            if (sparePartNumber != nullptr && !sparePartNumber->empty())
-            {
-                asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
-            }
-        });
-}
-
 inline void getFabricAdapterState(
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     const std::string& serviceName, const std::string& fabricAdapterPath)
@@ -196,7 +139,8 @@
                             systemName, adapterId);
 
     getFabricAdapterLocation(asyncResp, serviceName, fabricAdapterPath);
-    getFabricAdapterAsset(asyncResp, serviceName, fabricAdapterPath);
+    asset_utils::getAssetInfo(asyncResp, serviceName, fabricAdapterPath,
+                              ""_json_pointer, true);
     getFabricAdapterState(asyncResp, serviceName, fabricAdapterPath);
     getFabricAdapterHealth(asyncResp, serviceName, fabricAdapterPath);
     getLocationIndicatorActive(asyncResp, fabricAdapterPath);
diff --git a/redfish-core/lib/fan.hpp b/redfish-core/lib/fan.hpp
index c10288d..9319dfa 100644
--- a/redfish-core/lib/fan.hpp
+++ b/redfish-core/lib/fan.hpp
@@ -12,6 +12,7 @@
 #include "logging.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
+#include "utils/asset_utils.hpp"
 #include "utils/chassis_utils.hpp"
 #include "utils/dbus_utils.hpp"
 #include "utils/json_utils.hpp"
@@ -295,63 +296,6 @@
         });
 }
 
-inline void getFanAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                        const std::string& fanPath, const std::string& service)
-{
-    dbus::utility::getAllProperties(
-        service, fanPath, "xyz.openbmc_project.Inventory.Decorator.Asset",
-        [fanPath, asyncResp{asyncResp}](
-            const boost::system::error_code& ec,
-            const dbus::utility::DBusPropertiesMap& assetList) {
-            if (ec)
-            {
-                if (ec.value() != EBADR)
-                {
-                    BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
-                                     ec.value());
-                    messages::internalError(asyncResp->res);
-                }
-                return;
-            }
-            const std::string* manufacturer = nullptr;
-            const std::string* model = nullptr;
-            const std::string* partNumber = nullptr;
-            const std::string* serialNumber = nullptr;
-            const std::string* sparePartNumber = nullptr;
-
-            const bool success = sdbusplus::unpackPropertiesNoThrow(
-                dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
-                manufacturer, "Model", model, "PartNumber", partNumber,
-                "SerialNumber", serialNumber, "SparePartNumber",
-                sparePartNumber);
-            if (!success)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-            if (manufacturer != nullptr)
-            {
-                asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
-            }
-            if (model != nullptr)
-            {
-                asyncResp->res.jsonValue["Model"] = *model;
-            }
-            if (partNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-            }
-            if (serialNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-            }
-            if (sparePartNumber != nullptr && !sparePartNumber->empty())
-            {
-                asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
-            }
-        });
-}
-
 inline void getFanLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                            const std::string& fanPath,
                            const std::string& service)
@@ -385,7 +329,8 @@
     addFanCommonProperties(asyncResp->res, chassisId, fanId);
     getFanState(asyncResp, fanPath, service);
     getFanHealth(asyncResp, fanPath, service);
-    getFanAsset(asyncResp, fanPath, service);
+    asset_utils::getAssetInfo(asyncResp, service, fanPath, ""_json_pointer,
+                              true);
     getFanLocation(asyncResp, fanPath, service);
     getLocationIndicatorActive(asyncResp, fanPath);
 }
diff --git a/redfish-core/lib/pcie.hpp b/redfish-core/lib/pcie.hpp
index 6a961f0..3860216 100644
--- a/redfish-core/lib/pcie.hpp
+++ b/redfish-core/lib/pcie.hpp
@@ -17,6 +17,7 @@
 #include "logging.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
+#include "utils/asset_utils.hpp"
 #include "utils/dbus_utils.hpp"
 #include "utils/pcie_util.hpp"
 
@@ -361,71 +362,6 @@
         });
 }
 
-inline void getPCIeDeviceAsset(
-    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-    const std::string& pcieDevicePath, const std::string& service)
-{
-    dbus::utility::getAllProperties(
-        service, pcieDevicePath,
-        "xyz.openbmc_project.Inventory.Decorator.Asset",
-        [pcieDevicePath, asyncResp{asyncResp}](
-            const boost::system::error_code& ec,
-            const dbus::utility::DBusPropertiesMap& assetList) {
-            if (ec)
-            {
-                if (ec.value() != EBADR)
-                {
-                    BMCWEB_LOG_ERROR("DBUS response error for Properties{}",
-                                     ec.value());
-                    messages::internalError(asyncResp->res);
-                }
-                return;
-            }
-
-            const std::string* manufacturer = nullptr;
-            const std::string* model = nullptr;
-            const std::string* partNumber = nullptr;
-            const std::string* serialNumber = nullptr;
-            const std::string* sparePartNumber = nullptr;
-
-            const bool success = sdbusplus::unpackPropertiesNoThrow(
-                dbus_utils::UnpackErrorPrinter(), assetList, "Manufacturer",
-                manufacturer, "Model", model, "PartNumber", partNumber,
-                "SerialNumber", serialNumber, "SparePartNumber",
-                sparePartNumber);
-
-            if (!success)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            if (manufacturer != nullptr)
-            {
-                asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
-            }
-            if (model != nullptr)
-            {
-                asyncResp->res.jsonValue["Model"] = *model;
-            }
-
-            if (partNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-            }
-
-            if (serialNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-            }
-
-            if (sparePartNumber != nullptr && !sparePartNumber->empty())
-            {
-                asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
-            }
-        });
-}
-
 inline void addPCIeDeviceProperties(
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     const std::string& pcieDeviceId,
@@ -570,7 +506,8 @@
     const std::string& service)
 {
     addPCIeDeviceCommonProperties(asyncResp, pcieDeviceId);
-    getPCIeDeviceAsset(asyncResp, pcieDevicePath, service);
+    asset_utils::getAssetInfo(asyncResp, service, pcieDevicePath,
+                              ""_json_pointer, true);
     getPCIeDeviceState(asyncResp, pcieDevicePath, service);
     getPCIeDeviceHealth(asyncResp, pcieDevicePath, service);
     getPCIeDeviceProperties(
diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp
index 89c84e1..0336ddc 100644
--- a/redfish-core/lib/power_supply.hpp
+++ b/redfish-core/lib/power_supply.hpp
@@ -12,6 +12,7 @@
 #include "logging.hpp"
 #include "query.hpp"
 #include "registries/privilege_registry.hpp"
+#include "utils/asset_utils.hpp"
 #include "utils/chassis_utils.hpp"
 #include "utils/dbus_utils.hpp"
 #include "utils/json_utils.hpp"
@@ -293,51 +294,20 @@
                 return;
             }
 
-            const std::string* partNumber = nullptr;
-            const std::string* serialNumber = nullptr;
-            const std::string* manufacturer = nullptr;
-            const std::string* model = nullptr;
-            const std::string* sparePartNumber = nullptr;
+            asset_utils::extractAssetInfo(asyncResp, ""_json_pointer,
+                                          propertiesList, true);
+
             const std::string* buildDate = nullptr;
 
             const bool success = sdbusplus::unpackPropertiesNoThrow(
-                dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
-                partNumber, "SerialNumber", serialNumber, "Manufacturer",
-                manufacturer, "Model", model, "SparePartNumber",
-                sparePartNumber, "BuildDate", buildDate);
-
+                dbus_utils::UnpackErrorPrinter(), propertiesList, "BuildDate",
+                buildDate);
             if (!success)
             {
                 messages::internalError(asyncResp->res);
                 return;
             }
 
-            if (partNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-            }
-
-            if (serialNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-            }
-
-            if (manufacturer != nullptr)
-            {
-                asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
-            }
-
-            if (model != nullptr)
-            {
-                asyncResp->res.jsonValue["Model"] = *model;
-            }
-
-            // SparePartNumber is optional on D-Bus so skip if it is empty
-            if (sparePartNumber != nullptr && !sparePartNumber->empty())
-            {
-                asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
-            }
-
             if (buildDate != nullptr)
             {
                 time_utils::productionDateReport(asyncResp->res, *buildDate);
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index a7243a0..89ae4b1 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -291,60 +291,6 @@
             std::bind_front(handleStorageGet, std::ref(app)));
 }
 
-inline void getDriveAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                          const std::string& connectionName,
-                          const std::string& path)
-{
-    dbus::utility::getAllProperties(
-        connectionName, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
-        [asyncResp](const boost::system::error_code& ec,
-                    const std::vector<
-                        std::pair<std::string, dbus::utility::DbusVariantType>>&
-                        propertiesList) {
-            if (ec)
-            {
-                // this interface isn't necessary
-                return;
-            }
-
-            const std::string* partNumber = nullptr;
-            const std::string* serialNumber = nullptr;
-            const std::string* manufacturer = nullptr;
-            const std::string* model = nullptr;
-
-            const bool success = sdbusplus::unpackPropertiesNoThrow(
-                dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
-                partNumber, "SerialNumber", serialNumber, "Manufacturer",
-                manufacturer, "Model", model);
-
-            if (!success)
-            {
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            if (partNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-            }
-
-            if (serialNumber != nullptr)
-            {
-                asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-            }
-
-            if (manufacturer != nullptr)
-            {
-                asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
-            }
-
-            if (model != nullptr)
-            {
-                asyncResp->res.jsonValue["Model"] = *model;
-            }
-        });
-}
-
 inline void getDrivePresent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                             const std::string& connectionName,
                             const std::string& path)
@@ -614,7 +560,8 @@
     {
         if (interface == "xyz.openbmc_project.Inventory.Decorator.Asset")
         {
-            getDriveAsset(asyncResp, connectionName, path);
+            asset_utils::getAssetInfo(asyncResp, connectionName, path,
+                                      ""_json_pointer, false);
         }
         else if (interface == "xyz.openbmc_project.Inventory.Item")
         {
@@ -971,53 +918,6 @@
             std::bind_front(handleChassisDriveGet, std::ref(app)));
 }
 
-inline void getStorageControllerAsset(
-    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-    const boost::system::error_code& ec,
-    const std::vector<std::pair<std::string, dbus::utility::DbusVariantType>>&
-        propertiesList)
-{
-    if (ec)
-    {
-        // this interface isn't necessary
-        BMCWEB_LOG_DEBUG("Failed to get StorageControllerAsset");
-        return;
-    }
-
-    const std::string* partNumber = nullptr;
-    const std::string* serialNumber = nullptr;
-    const std::string* manufacturer = nullptr;
-    const std::string* model = nullptr;
-    if (!sdbusplus::unpackPropertiesNoThrow(
-            dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
-            partNumber, "SerialNumber", serialNumber, "Manufacturer",
-            manufacturer, "Model", model))
-    {
-        messages::internalError(asyncResp->res);
-        return;
-    }
-
-    if (partNumber != nullptr)
-    {
-        asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-    }
-
-    if (serialNumber != nullptr)
-    {
-        asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-    }
-
-    if (manufacturer != nullptr)
-    {
-        asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
-    }
-
-    if (model != nullptr)
-    {
-        asyncResp->res.jsonValue["Model"] = *model;
-    }
-}
-
 inline void populateStorageController(
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     const std::string& controllerId, const std::string& connectionName,
@@ -1049,14 +949,8 @@
             }
         });
 
-    dbus::utility::getAllProperties(
-        connectionName, path, "xyz.openbmc_project.Inventory.Decorator.Asset",
-        [asyncResp](const boost::system::error_code& ec,
-                    const std::vector<
-                        std::pair<std::string, dbus::utility::DbusVariantType>>&
-                        propertiesList) {
-            getStorageControllerAsset(asyncResp, ec, propertiesList);
-        });
+    asset_utils::getAssetInfo(asyncResp, connectionName, path, ""_json_pointer,
+                              false);
 }
 
 inline void getStorageControllerHandler(
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index a336988..3123f06 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -21,6 +21,7 @@
 #include "query.hpp"
 #include "redfish_util.hpp"
 #include "registries/privilege_registry.hpp"
+#include "utils/asset_utils.hpp"
 #include "utils/dbus_utils.hpp"
 #include "utils/json_utils.hpp"
 #include "utils/pcie_util.hpp"
@@ -297,16 +298,13 @@
     }
     BMCWEB_LOG_DEBUG("Got {} properties for system", propertiesList.size());
 
-    const std::string* partNumber = nullptr;
-    const std::string* serialNumber = nullptr;
-    const std::string* manufacturer = nullptr;
-    const std::string* model = nullptr;
+    asset_utils::extractAssetInfo(asyncResp, ""_json_pointer, propertiesList,
+                                  false);
+
     const std::string* subModel = nullptr;
 
     const bool success = sdbusplus::unpackPropertiesNoThrow(
-        dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
-        partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
-        "Model", model, "SubModel", subModel);
+        dbus_utils::UnpackErrorPrinter(), propertiesList, "SubModel", subModel);
 
     if (!success)
     {
@@ -314,26 +312,6 @@
         return;
     }
 
-    if (partNumber != nullptr)
-    {
-        asyncResp->res.jsonValue["PartNumber"] = *partNumber;
-    }
-
-    if (serialNumber != nullptr)
-    {
-        asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
-    }
-
-    if (manufacturer != nullptr)
-    {
-        asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
-    }
-
-    if (model != nullptr)
-    {
-        asyncResp->res.jsonValue["Model"] = *model;
-    }
-
     if (subModel != nullptr)
     {
         asyncResp->res.jsonValue["SubModel"] = *subModel;