Remove Redfish Node class

Reduces the total number of lines and will allow for easier testing of
the redfish responses.

A main purpose of the node class was to set app.routeDynamic(). However
now app.routeDynamic can handle the complexity that was once in critical
to node. The macro app.routeDynamic() provides a shorter cleaner
interface to the unerlying app.routeDyanic call. The old pattern set
permissions for 6 interfaces (get, head, patch, put, delete_, and post)
even if only one interface is created. That pattern creates unneeded
code that can be safely removed with no effect.
Unit test for the responses would have to mock the node the class in
order to fully test responses.

see https://github.com/openbmc/bmcweb/issues/181

The following files still need node to be extracted.

virtual_media.hpp
account_service.hpp
redfish_sessions.hpp
ethernet.hpp

The files above use a pattern that is not trivial to address. Often their
responses call an async lambda capturing the inherited class. ie
(https://github.com/openbmc/bmcweb/blob/ffed87b5ad1797ca966d030e7f979770
28d258fa/redfish-core/lib/account_service.hpp#L1393)
At a later point I plan to remove node from the files above.

Tested:
I ran the docker unit test with the following command.
WORKSPACE=$(pwd) UNIT_TEST_PKG=bmcweb
 ./openbmc-build-scripts/run-unit-test-docker.sh

I ran the validator and this change did not create any issues.
python3 RedfishServiceValidator.py -c config.ini

Signed-off-by: John Edward Broadbent <jebr@google.com>
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I147a0289c52cb4198345b1ad9bfe6fdddf57f3df
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index 34ef39a..0c3d9fd 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -18,197 +18,325 @@
 #include "health.hpp"
 #include "openbmc_dbus_rest.hpp"
 
-#include <node.hpp>
+#include <app.hpp>
 
 namespace redfish
 {
-class StorageCollection : public Node
+inline void requestRoutesStorageCollection(App& app)
 {
-  public:
-    StorageCollection(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Storage/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/")
+        .privileges({"Login"})
+        .methods(boost::beast::http::verb::get)(
+            [](const crow::Request&,
+               const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+                asyncResp->res.jsonValue["@odata.type"] =
+                    "#StorageCollection.StorageCollection";
+                asyncResp->res.jsonValue["@odata.id"] =
+                    "/redfish/v1/Systems/system/Storage";
+                asyncResp->res.jsonValue["Name"] = "Storage Collection";
+                asyncResp->res.jsonValue["Members"] = {
+                    {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}};
+                asyncResp->res.jsonValue["Members@odata.count"] = 1;
+            });
+}
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#StorageCollection.StorageCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage";
-        asyncResp->res.jsonValue["Name"] = "Storage Collection";
-        asyncResp->res.jsonValue["Members"] = {
-            {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}};
-        asyncResp->res.jsonValue["Members@odata.count"] = 1;
-    }
-};
-
-class Storage : public Node
+inline void requestRoutesStorage(App& app)
 {
-  public:
-    Storage(App& app) : Node(app, "/redfish/v1/Systems/system/Storage/1/")
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::
+                get)([](const crow::Request&,
+                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+            asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage";
+            asyncResp->res.jsonValue["@odata.id"] =
+                "/redfish/v1/Systems/system/Storage/1";
+            asyncResp->res.jsonValue["Name"] = "Storage";
+            asyncResp->res.jsonValue["Id"] = "1";
+            asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
 
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&, const std::vector<std::string>&) override
-    {
-        asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage/1";
-        asyncResp->res.jsonValue["Name"] = "Storage";
-        asyncResp->res.jsonValue["Id"] = "1";
-        asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+            auto health = std::make_shared<HealthPopulate>(asyncResp);
+            health->populate();
 
-        auto health = std::make_shared<HealthPopulate>(asyncResp);
-        health->populate();
+            crow::connections::systemBus->async_method_call(
+                [asyncResp,
+                 health](const boost::system::error_code ec,
+                         const std::vector<std::string>& storageList) {
+                    nlohmann::json& storageArray =
+                        asyncResp->res.jsonValue["Drives"];
+                    storageArray = nlohmann::json::array();
+                    auto& count =
+                        asyncResp->res.jsonValue["Drives@odata.count"];
+                    count = 0;
 
-        crow::connections::systemBus->async_method_call(
-            [asyncResp, health](const boost::system::error_code ec,
-                                const std::vector<std::string>& storageList) {
-                nlohmann::json& storageArray =
-                    asyncResp->res.jsonValue["Drives"];
-                storageArray = nlohmann::json::array();
-                auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
-                count = 0;
-
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "Drive mapper call error";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                health->inventory.insert(health->inventory.end(),
-                                         storageList.begin(),
-                                         storageList.end());
-
-                for (const std::string& objpath : storageList)
-                {
-                    std::size_t lastPos = objpath.rfind('/');
-                    if (lastPos == std::string::npos ||
-                        (objpath.size() <= lastPos + 1))
+                    if (ec)
                     {
-                        BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
-                        continue;
-                    }
-
-                    storageArray.push_back(
-                        {{"@odata.id",
-                          "/redfish/v1/Systems/system/Storage/1/Drives/" +
-                              objpath.substr(lastPos + 1)}});
-                }
-
-                count = storageArray.size();
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
-            "/xyz/openbmc_project/inventory", int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.Drive"});
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp,
-             health](const boost::system::error_code ec,
-                     const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec || !subtree.size())
-                {
-                    // doesn't have to be there
-                    return;
-                }
-
-                nlohmann::json& root =
-                    asyncResp->res.jsonValue["StorageControllers"];
-                root = nlohmann::json::array();
-                for (const auto& [path, interfaceDict] : subtree)
-                {
-                    std::size_t lastPos = path.rfind('/');
-                    if (lastPos == std::string::npos ||
-                        (path.size() <= lastPos + 1))
-                    {
-                        BMCWEB_LOG_ERROR << "Failed to find '/' in " << path;
+                        BMCWEB_LOG_ERROR << "Drive mapper call error";
+                        messages::internalError(asyncResp->res);
                         return;
                     }
 
-                    if (interfaceDict.size() != 1)
+                    health->inventory.insert(health->inventory.end(),
+                                             storageList.begin(),
+                                             storageList.end());
+
+                    for (const std::string& objpath : storageList)
+                    {
+                        std::size_t lastPos = objpath.rfind('/');
+                        if (lastPos == std::string::npos ||
+                            (objpath.size() <= lastPos + 1))
+                        {
+                            BMCWEB_LOG_ERROR << "Failed to find '/' in "
+                                             << objpath;
+                            continue;
+                        }
+
+                        storageArray.push_back(
+                            {{"@odata.id",
+                              "/redfish/v1/Systems/system/Storage/1/Drives/" +
+                                  objpath.substr(lastPos + 1)}});
+                    }
+
+                    count = storageArray.size();
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+                "/xyz/openbmc_project/inventory", int32_t(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.Drive"});
+
+            crow::connections::systemBus->async_method_call(
+                [asyncResp,
+                 health](const boost::system::error_code ec,
+                         const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                    if (ec || !subtree.size())
+                    {
+                        // doesn't have to be there
+                        return;
+                    }
+
+                    nlohmann::json& root =
+                        asyncResp->res.jsonValue["StorageControllers"];
+                    root = nlohmann::json::array();
+                    for (const auto& [path, interfaceDict] : subtree)
+                    {
+                        std::size_t lastPos = path.rfind('/');
+                        if (lastPos == std::string::npos ||
+                            (path.size() <= lastPos + 1))
+                        {
+                            BMCWEB_LOG_ERROR << "Failed to find '/' in "
+                                             << path;
+                            return;
+                        }
+
+                        if (interfaceDict.size() != 1)
+                        {
+                            BMCWEB_LOG_ERROR << "Connection size "
+                                             << interfaceDict.size()
+                                             << ", greater than 1";
+                            messages::internalError(asyncResp->res);
+                            return;
+                        }
+
+                        const std::string& connectionName =
+                            interfaceDict.front().first;
+
+                        size_t index = root.size();
+                        nlohmann::json& storageController =
+                            root.emplace_back(nlohmann::json::object());
+
+                        std::string id = path.substr(lastPos + 1);
+
+                        storageController["@odata.type"] =
+                            "#Storage.v1_7_0.StorageController";
+                        storageController["@odata.id"] =
+                            "/redfish/v1/Systems/system/Storage/1"
+                            "#/StorageControllers/" +
+                            std::to_string(index);
+                        storageController["Name"] = id;
+                        storageController["MemberId"] = id;
+                        storageController["Status"]["State"] = "Enabled";
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp,
+                             index](const boost::system::error_code ec2,
+                                    const std::variant<bool> present) {
+                                // this interface isn't necessary, only check it
+                                // if we get a good return
+                                if (ec2)
+                                {
+                                    return;
+                                }
+                                const bool* enabled =
+                                    std::get_if<bool>(&present);
+                                if (enabled == nullptr)
+                                {
+                                    BMCWEB_LOG_DEBUG
+                                        << "Illegal property present";
+                                    messages::internalError(asyncResp->res);
+                                    return;
+                                }
+                                if (!(*enabled))
+                                {
+                                    asyncResp->res
+                                        .jsonValue["StorageControllers"][index]
+                                                  ["Status"]["State"] =
+                                        "Disabled";
+                                }
+                            },
+                            connectionName, path,
+                            "org.freedesktop.DBus.Properties", "Get",
+                            "xyz.openbmc_project.Inventory.Item", "Present");
+
+                        crow::connections::systemBus->async_method_call(
+                            [asyncResp, index](
+                                const boost::system::error_code ec2,
+                                const std::vector<std::pair<
+                                    std::string,
+                                    std::variant<bool, std::string, uint64_t>>>&
+                                    propertiesList) {
+                                if (ec2)
+                                {
+                                    // this interface isn't necessary
+                                    return;
+                                }
+                                for (const std::pair<
+                                         std::string,
+                                         std::variant<bool, std::string,
+                                                      uint64_t>>& property :
+                                     propertiesList)
+                                {
+                                    // Store DBus properties that are also
+                                    // Redfish properties with same name and a
+                                    // string value
+                                    const std::string& propertyName =
+                                        property.first;
+                                    nlohmann::json& object =
+                                        asyncResp->res
+                                            .jsonValue["StorageControllers"]
+                                                      [index];
+                                    if ((propertyName == "PartNumber") ||
+                                        (propertyName == "SerialNumber") ||
+                                        (propertyName == "Manufacturer") ||
+                                        (propertyName == "Model"))
+                                    {
+                                        const std::string* value =
+                                            std::get_if<std::string>(
+                                                &property.second);
+                                        if (value == nullptr)
+                                        {
+                                            // illegal property
+                                            messages::internalError(
+                                                asyncResp->res);
+                                            return;
+                                        }
+                                        object[propertyName] = *value;
+                                    }
+                                }
+                            },
+                            connectionName, path,
+                            "org.freedesktop.DBus.Properties", "GetAll",
+                            "xyz.openbmc_project.Inventory.Decorator.Asset");
+                    }
+
+                    // this is done after we know the json array will no longer
+                    // be resized, as json::array uses vector underneath and we
+                    // need references to its members that won't change
+                    size_t count = 0;
+                    for (const auto& [path, interfaceDict] : subtree)
+                    {
+                        auto subHealth = std::make_shared<HealthPopulate>(
+                            asyncResp, root[count]["Status"]);
+                        subHealth->inventory.emplace_back(path);
+                        health->inventory.emplace_back(path);
+                        health->children.emplace_back(subHealth);
+                        count++;
+                    }
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", int32_t(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.StorageController"});
+        });
+}
+
+inline void requestRoutesDrive(App& app)
+{
+    BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/")
+        .privileges({"Login"})
+        .methods(
+            boost::beast::http::verb::get)([](const crow::Request&,
+                                              const std::shared_ptr<
+                                                  bmcweb::AsyncResp>& asyncResp,
+                                              const std::string& driveId) {
+            crow::connections::systemBus->async_method_call(
+                [asyncResp,
+                 driveId](const boost::system::error_code ec,
+                          const crow::openbmc_mapper::GetSubTreeType& subtree) {
+                    if (ec)
+                    {
+                        BMCWEB_LOG_ERROR << "Drive mapper call error";
+                        messages::internalError(asyncResp->res);
+                        return;
+                    }
+
+                    auto object2 = std::find_if(
+                        subtree.begin(), subtree.end(),
+                        [&driveId](auto& object) {
+                            const std::string& path = object.first;
+                            return boost::ends_with(path, "/" + driveId);
+                        });
+
+                    if (object2 == subtree.end())
+                    {
+                        messages::resourceNotFound(asyncResp->res, "Drive",
+                                                   driveId);
+                        return;
+                    }
+
+                    const std::string& path = object2->first;
+                    const std::vector<
+                        std::pair<std::string, std::vector<std::string>>>&
+                        connectionNames = object2->second;
+
+                    asyncResp->res.jsonValue["@odata.type"] =
+                        "#Drive.v1_7_0.Drive";
+                    asyncResp->res.jsonValue["@odata.id"] =
+                        "/redfish/v1/Systems/system/Storage/1/Drives/" +
+                        driveId;
+                    asyncResp->res.jsonValue["Name"] = driveId;
+                    asyncResp->res.jsonValue["Id"] = driveId;
+
+                    if (connectionNames.size() != 1)
                     {
                         BMCWEB_LOG_ERROR << "Connection size "
-                                         << interfaceDict.size()
+                                         << connectionNames.size()
                                          << ", greater than 1";
                         messages::internalError(asyncResp->res);
                         return;
                     }
 
+                    getMainChassisId(
+                        asyncResp,
+                        [](const std::string& chassisId,
+                           const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
+                            aRsp->res.jsonValue["Links"]["Chassis"] = {
+                                {"@odata.id",
+                                 "/redfish/v1/Chassis/" + chassisId}};
+                        });
+
                     const std::string& connectionName =
-                        interfaceDict.front().first;
-
-                    size_t index = root.size();
-                    nlohmann::json& storageController =
-                        root.emplace_back(nlohmann::json::object());
-
-                    std::string id = path.substr(lastPos + 1);
-
-                    storageController["@odata.type"] =
-                        "#Storage.v1_7_0.StorageController";
-                    storageController["@odata.id"] =
-                        "/redfish/v1/Systems/system/Storage/1"
-                        "#/StorageControllers/" +
-                        std::to_string(index);
-                    storageController["Name"] = id;
-                    storageController["MemberId"] = id;
-                    storageController["Status"]["State"] = "Enabled";
-
+                        connectionNames[0].first;
                     crow::connections::systemBus->async_method_call(
-                        [asyncResp, index](const boost::system::error_code ec2,
-                                           const std::variant<bool> present) {
-                            // this interface isn't necessary, only check it if
-                            // we get a good return
-                            if (ec2)
-                            {
-                                return;
-                            }
-                            const bool* enabled = std::get_if<bool>(&present);
-                            if (enabled == nullptr)
-                            {
-                                BMCWEB_LOG_DEBUG << "Illegal property present";
-                                messages::internalError(asyncResp->res);
-                                return;
-                            }
-                            if (!(*enabled))
-                            {
-                                asyncResp->res
-                                    .jsonValue["StorageControllers"][index]
-                                              ["Status"]["State"] = "Disabled";
-                            }
-                        },
-                        connectionName, path, "org.freedesktop.DBus.Properties",
-                        "Get", "xyz.openbmc_project.Inventory.Item", "Present");
-
-                    crow::connections::systemBus->async_method_call(
-                        [asyncResp,
-                         index](const boost::system::error_code ec2,
-                                const std::vector<std::pair<
-                                    std::string,
-                                    std::variant<bool, std::string, uint64_t>>>&
-                                    propertiesList) {
+                        [asyncResp](
+                            const boost::system::error_code ec2,
+                            const std::vector<std::pair<
+                                std::string,
+                                std::variant<bool, std::string, uint64_t>>>&
+                                propertiesList) {
                             if (ec2)
                             {
                                 // this interface isn't necessary
@@ -224,9 +352,6 @@
                                 // string value
                                 const std::string& propertyName =
                                     property.first;
-                                nlohmann::json& object =
-                                    asyncResp->res
-                                        .jsonValue["StorageControllers"][index];
                                 if ((propertyName == "PartNumber") ||
                                     (propertyName == "SerialNumber") ||
                                     (propertyName == "Manufacturer") ||
@@ -241,226 +366,84 @@
                                         messages::internalError(asyncResp->res);
                                         return;
                                     }
-                                    object[propertyName] = *value;
+                                    asyncResp->res.jsonValue[propertyName] =
+                                        *value;
                                 }
                             }
                         },
                         connectionName, path, "org.freedesktop.DBus.Properties",
                         "GetAll",
                         "xyz.openbmc_project.Inventory.Decorator.Asset");
-                }
 
-                // this is done after we know the json array will no longer be
-                // resized, as json::array uses vector underneath and we need
-                // references to its members that won't change
-                size_t count = 0;
-                for (const auto& [path, interfaceDict] : subtree)
-                {
-                    auto subHealth = std::make_shared<HealthPopulate>(
-                        asyncResp, root[count]["Status"]);
-                    subHealth->inventory.emplace_back(path);
+                    // default it to Enabled
+                    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+                    auto health = std::make_shared<HealthPopulate>(asyncResp);
                     health->inventory.emplace_back(path);
-                    health->children.emplace_back(subHealth);
-                    count++;
-                }
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.StorageController"});
-    }
-};
+                    health->populate();
 
-class Drive : public Node
-{
-  public:
-    Drive(App& app) :
-        Node(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/",
-             std::string())
-    {
-        entityPrivileges = {
-            {boost::beast::http::verb::get, {{"Login"}}},
-            {boost::beast::http::verb::head, {{"Login"}}},
-            {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
-            {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
-    }
-
-  private:
-    void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-               const crow::Request&,
-               const std::vector<std::string>& params) override
-    {
-        if (params.size() != 1)
-        {
-            messages::internalError(asyncResp->res);
-            return;
-        }
-        const std::string& driveId = params[0];
-
-        crow::connections::systemBus->async_method_call(
-            [asyncResp,
-             driveId](const boost::system::error_code ec,
-                      const crow::openbmc_mapper::GetSubTreeType& subtree) {
-                if (ec)
-                {
-                    BMCWEB_LOG_ERROR << "Drive mapper call error";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                auto object2 = std::find_if(
-                    subtree.begin(), subtree.end(), [&driveId](auto& object) {
-                        const std::string& path = object.first;
-                        return boost::ends_with(path, "/" + driveId);
-                    });
-
-                if (object2 == subtree.end())
-                {
-                    messages::resourceNotFound(asyncResp->res, "Drive",
-                                               driveId);
-                    return;
-                }
-
-                const std::string& path = object2->first;
-                const std::vector<
-                    std::pair<std::string, std::vector<std::string>>>&
-                    connectionNames = object2->second;
-
-                asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive";
-                asyncResp->res.jsonValue["@odata.id"] =
-                    "/redfish/v1/Systems/system/Storage/1/Drives/" + driveId;
-                asyncResp->res.jsonValue["Name"] = driveId;
-                asyncResp->res.jsonValue["Id"] = driveId;
-
-                if (connectionNames.size() != 1)
-                {
-                    BMCWEB_LOG_ERROR << "Connection size "
-                                     << connectionNames.size()
-                                     << ", greater than 1";
-                    messages::internalError(asyncResp->res);
-                    return;
-                }
-
-                getMainChassisId(
-                    asyncResp,
-                    [](const std::string& chassisId,
-                       const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
-                        aRsp->res.jsonValue["Links"]["Chassis"] = {
-                            {"@odata.id", "/redfish/v1/Chassis/" + chassisId}};
-                    });
-
-                const std::string& connectionName = connectionNames[0].first;
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp](const boost::system::error_code ec2,
-                                const std::vector<std::pair<
-                                    std::string,
-                                    std::variant<bool, std::string, uint64_t>>>&
-                                    propertiesList) {
-                        if (ec2)
-                        {
-                            // this interface isn't necessary
-                            return;
-                        }
-                        for (const std::pair<std::string,
-                                             std::variant<bool, std::string,
-                                                          uint64_t>>& property :
-                             propertiesList)
-                        {
-                            // Store DBus properties that are also
-                            // Redfish properties with same name and a
-                            // string value
-                            const std::string& propertyName = property.first;
-                            if ((propertyName == "PartNumber") ||
-                                (propertyName == "SerialNumber") ||
-                                (propertyName == "Manufacturer") ||
-                                (propertyName == "Model"))
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp, path](const boost::system::error_code ec2,
+                                          const std::variant<bool> present) {
+                            // this interface isn't necessary, only check it if
+                            // we get a good return
+                            if (ec2)
                             {
-                                const std::string* value =
-                                    std::get_if<std::string>(&property.second);
-                                if (value == nullptr)
-                                {
-                                    // illegal property
-                                    messages::internalError(asyncResp->res);
-                                    return;
-                                }
-                                asyncResp->res.jsonValue[propertyName] = *value;
+                                return;
                             }
-                        }
-                    },
-                    connectionName, path, "org.freedesktop.DBus.Properties",
-                    "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset");
+                            const bool* enabled = std::get_if<bool>(&present);
+                            if (enabled == nullptr)
+                            {
+                                BMCWEB_LOG_DEBUG << "Illegal property present";
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
+                            if (!(*enabled))
+                            {
+                                asyncResp->res.jsonValue["Status"]["State"] =
+                                    "Disabled";
+                            }
+                        },
+                        connectionName, path, "org.freedesktop.DBus.Properties",
+                        "Get", "xyz.openbmc_project.Inventory.Item", "Present");
 
-                // default it to Enabled
-                asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+                    crow::connections::systemBus->async_method_call(
+                        [asyncResp](const boost::system::error_code ec2,
+                                    const std::variant<bool> rebuilding) {
+                            // this interface isn't necessary, only check it if
+                            // we get a good return
+                            if (ec2)
+                            {
+                                return;
+                            }
+                            const bool* updating =
+                                std::get_if<bool>(&rebuilding);
+                            if (updating == nullptr)
+                            {
+                                BMCWEB_LOG_DEBUG << "Illegal property present";
+                                messages::internalError(asyncResp->res);
+                                return;
+                            }
 
-                auto health = std::make_shared<HealthPopulate>(asyncResp);
-                health->inventory.emplace_back(path);
-                health->populate();
-
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp, path](const boost::system::error_code ec2,
-                                      const std::variant<bool> present) {
-                        // this interface isn't necessary, only check it if we
-                        // get a good return
-                        if (ec2)
-                        {
-                            return;
-                        }
-                        const bool* enabled = std::get_if<bool>(&present);
-                        if (enabled == nullptr)
-                        {
-                            BMCWEB_LOG_DEBUG << "Illegal property present";
-                            messages::internalError(asyncResp->res);
-                            return;
-                        }
-                        if (!(*enabled))
-                        {
-                            asyncResp->res.jsonValue["Status"]["State"] =
-                                "Disabled";
-                        }
-                    },
-                    connectionName, path, "org.freedesktop.DBus.Properties",
-                    "Get", "xyz.openbmc_project.Inventory.Item", "Present");
-
-                crow::connections::systemBus->async_method_call(
-                    [asyncResp](const boost::system::error_code ec2,
-                                const std::variant<bool> rebuilding) {
-                        // this interface isn't necessary, only check it if we
-                        // get a good return
-                        if (ec2)
-                        {
-                            return;
-                        }
-                        const bool* updating = std::get_if<bool>(&rebuilding);
-                        if (updating == nullptr)
-                        {
-                            BMCWEB_LOG_DEBUG << "Illegal property present";
-                            messages::internalError(asyncResp->res);
-                            return;
-                        }
-
-                        // updating and disabled in the backend shouldn't be
-                        // able to be set at the same time, so we don't need to
-                        // check for the race condition of these two calls
-                        if ((*updating))
-                        {
-                            asyncResp->res.jsonValue["Status"]["State"] =
-                                "Updating";
-                        }
-                    },
-                    connectionName, path, "org.freedesktop.DBus.Properties",
-                    "Get", "xyz.openbmc_project.State.Drive", "Rebuilding");
-            },
-            "xyz.openbmc_project.ObjectMapper",
-            "/xyz/openbmc_project/object_mapper",
-            "xyz.openbmc_project.ObjectMapper", "GetSubTree",
-            "/xyz/openbmc_project/inventory", int32_t(0),
-            std::array<const char*, 1>{
-                "xyz.openbmc_project.Inventory.Item.Drive"});
-    }
-};
+                            // updating and disabled in the backend shouldn't be
+                            // able to be set at the same time, so we don't need
+                            // to check for the race condition of these two
+                            // calls
+                            if ((*updating))
+                            {
+                                asyncResp->res.jsonValue["Status"]["State"] =
+                                    "Updating";
+                            }
+                        },
+                        connectionName, path, "org.freedesktop.DBus.Properties",
+                        "Get", "xyz.openbmc_project.State.Drive", "Rebuilding");
+                },
+                "xyz.openbmc_project.ObjectMapper",
+                "/xyz/openbmc_project/object_mapper",
+                "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+                "/xyz/openbmc_project/inventory", int32_t(0),
+                std::array<const char*, 1>{
+                    "xyz.openbmc_project.Inventory.Item.Drive"});
+        });
+}
 } // namespace redfish