Break out storage methods

Change-Id: I2128e223f6c2d07d5c8e5a865921468a7510faf2
Signed-off-by: Ed Tanous <edtanous@google.com>
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
index 44b7746..53af1f1 100644
--- a/redfish-core/lib/storage.hpp
+++ b/redfish-core/lib/storage.hpp
@@ -39,39 +39,86 @@
 
 namespace redfish
 {
+
+inline void handleSystemsStorageCollectionGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if (systemName != "system")
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    asyncResp->res.jsonValue["@odata.type"] =
+        "#StorageCollection.StorageCollection";
+    asyncResp->res.jsonValue["@odata.id"] =
+        "/redfish/v1/Systems/system/Storage";
+    asyncResp->res.jsonValue["Name"] = "Storage Collection";
+    nlohmann::json::array_t members;
+    nlohmann::json::object_t member;
+    member["@odata.id"] = "/redfish/v1/Systems/system/Storage/1";
+    members.emplace_back(member);
+    asyncResp->res.jsonValue["Members"] = std::move(members);
+    asyncResp->res.jsonValue["Members@odata.count"] = 1;
+}
+
 inline void requestRoutesStorageCollection(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/")
         .privileges(redfish::privileges::getStorageCollection)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        if (systemName != "system")
-        {
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
-
-        asyncResp->res.jsonValue["@odata.type"] =
-            "#StorageCollection.StorageCollection";
-        asyncResp->res.jsonValue["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage";
-        asyncResp->res.jsonValue["Name"] = "Storage Collection";
-        nlohmann::json::array_t members;
-        nlohmann::json::object_t member;
-        member["@odata.id"] = "/redfish/v1/Systems/system/Storage/1";
-        members.emplace_back(member);
-        asyncResp->res.jsonValue["Members"] = std::move(members);
-        asyncResp->res.jsonValue["Members@odata.count"] = 1;
-        });
+            std::bind_front(handleSystemsStorageCollectionGet, std::ref(app)));
 }
 
+inline void afterChassisDriveCollectionSubtree(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::shared_ptr<HealthPopulate>& health,
+    const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreePathsResponse& driveList)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR << "Drive mapper call error";
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    nlohmann::json& driveArray = asyncResp->res.jsonValue["Drives"];
+    driveArray = nlohmann::json::array();
+    auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
+    count = 0;
+
+    if constexpr (bmcwebEnableHealthPopulate)
+    {
+        health->inventory.insert(health->inventory.end(), driveList.begin(),
+                                 driveList.end());
+    }
+
+    for (const std::string& drive : driveList)
+    {
+        sdbusplus::message::object_path object(drive);
+        if (object.filename().empty())
+        {
+            BMCWEB_LOG_ERROR << "Failed to find filename in " << drive;
+            return;
+        }
+
+        nlohmann::json::object_t driveJson;
+        driveJson["@odata.id"] = boost::urls::format(
+            "/redfish/v1/Systems/system/Storage/1/Drives/{}",
+            object.filename());
+        driveArray.emplace_back(std::move(driveJson));
+    }
+
+    count = driveArray.size();
+}
 inline void getDrives(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
                       const std::shared_ptr<HealthPopulate>& health)
 {
@@ -79,45 +126,33 @@
         "xyz.openbmc_project.Inventory.Item.Drive"};
     dbus::utility::getSubTreePaths(
         "/xyz/openbmc_project/inventory", 0, interfaces,
-        [asyncResp, health](
-            const boost::system::error_code& ec,
-            const dbus::utility::MapperGetSubTreePathsResponse& driveList) {
-        if (ec)
-        {
-            BMCWEB_LOG_ERROR << "Drive mapper call error";
-            messages::internalError(asyncResp->res);
-            return;
-        }
+        std::bind_front(afterChassisDriveCollectionSubtree, asyncResp, health));
+}
 
-        nlohmann::json& driveArray = asyncResp->res.jsonValue["Drives"];
-        driveArray = nlohmann::json::array();
-        auto& count = asyncResp->res.jsonValue["Drives@odata.count"];
-        count = 0;
+inline void
+    handleSystemsStorageGet(App& app, const crow::Request& req,
+                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_13_0.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";
 
-        if constexpr (bmcwebEnableHealthPopulate)
-        {
-            health->inventory.insert(health->inventory.end(), driveList.begin(),
-                                     driveList.end());
-        }
+    auto health = std::make_shared<HealthPopulate>(asyncResp);
+    if constexpr (bmcwebEnableHealthPopulate)
+    {
+        health->populate();
+    }
 
-        for (const std::string& drive : driveList)
-        {
-            sdbusplus::message::object_path object(drive);
-            if (object.filename().empty())
-            {
-                BMCWEB_LOG_ERROR << "Failed to find filename in " << drive;
-                return;
-            }
-
-            nlohmann::json::object_t driveJson;
-            driveJson["@odata.id"] = boost::urls::format(
-                "/redfish/v1/Systems/system/Storage/1/Drives/{}",
-                object.filename());
-            driveArray.emplace_back(std::move(driveJson));
-        }
-
-        count = driveArray.size();
-        });
+    getDrives(asyncResp, health);
+    asyncResp->res.jsonValue["Controllers"]["@odata.id"] =
+        "/redfish/v1/Systems/system/Storage/1/Controllers";
 }
 
 inline void requestRoutesStorage(App& app)
@@ -125,29 +160,7 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/")
         .privileges(redfish::privileges::getStorage)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_13_0.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);
-        if constexpr (bmcwebEnableHealthPopulate)
-        {
-            health->populate();
-        }
-
-        getDrives(asyncResp, health);
-        asyncResp->res.jsonValue["Controllers"]["@odata.id"] =
-            "/redfish/v1/Systems/system/Storage/1/Controllers";
-        });
+            std::bind_front(handleSystemsStorageGet, std::ref(app)));
 }
 
 inline void getDriveAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -491,96 +504,175 @@
     }
 }
 
+inline void afterGetSubtreeSystemsStorageDrive(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& driveId, const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreeResponse& subtree)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_ERROR << "Drive mapper call error";
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    auto drive = std::find_if(
+        subtree.begin(), subtree.end(),
+        [&driveId](const std::pair<std::string,
+                                   dbus::utility::MapperServiceMap>& object) {
+        return sdbusplus::message::object_path(object.first).filename() ==
+               driveId;
+        });
+
+    if (drive == subtree.end())
+    {
+        messages::resourceNotFound(asyncResp->res, "Drive", driveId);
+        return;
+    }
+
+    const std::string& path = drive->first;
+    const dbus::utility::MapperServiceMap& connectionNames = drive->second;
+
+    asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive";
+    asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+        "/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()
+                         << ", not equal to 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"] =
+            boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
+    });
+
+    // default it to Enabled
+    asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
+
+    if constexpr (bmcwebEnableHealthPopulate)
+    {
+        auto health = std::make_shared<HealthPopulate>(asyncResp);
+        health->inventory.emplace_back(path);
+        health->populate();
+    }
+
+    addAllDriveInfo(asyncResp, connectionNames[0].first, path,
+                    connectionNames[0].second);
+}
+
+inline void handleSystemsStorageDriveGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& systemName, const std::string& driveId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+    if (systemName != "system")
+    {
+        messages::resourceNotFound(asyncResp->res, "ComputerSystem",
+                                   systemName);
+        return;
+    }
+
+    constexpr std::array<std::string_view, 1> interfaces = {
+        "xyz.openbmc_project.Inventory.Item.Drive"};
+    dbus::utility::getSubTree(
+        "/xyz/openbmc_project/inventory", 0, interfaces,
+        std::bind_front(afterGetSubtreeSystemsStorageDrive, asyncResp,
+                        driveId));
+}
+
 inline void requestRoutesDrive(App& app)
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/1/Drives/<str>/")
         .privileges(redfish::privileges::getDrive)
         .methods(boost::beast::http::verb::get)(
-            [&app](const crow::Request& req,
-                   const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                   const std::string& systemName, const std::string& driveId) {
-        if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-        {
-            return;
-        }
-        if (systemName != "system")
-        {
-            messages::resourceNotFound(asyncResp->res, "ComputerSystem",
-                                       systemName);
-            return;
-        }
-
-        constexpr std::array<std::string_view, 1> interfaces = {
-            "xyz.openbmc_project.Inventory.Item.Drive"};
-        dbus::utility::getSubTree(
-            "/xyz/openbmc_project/inventory", 0, interfaces,
-            [asyncResp,
-             driveId](const boost::system::error_code& ec,
-                      const dbus::utility::MapperGetSubTreeResponse& subtree) {
-            if (ec)
-            {
-                BMCWEB_LOG_ERROR << "Drive mapper call error";
-                messages::internalError(asyncResp->res);
-                return;
-            }
-
-            auto drive = std::find_if(
-                subtree.begin(), subtree.end(),
-                [&driveId](
-                    const std::pair<std::string,
-                                    dbus::utility::MapperServiceMap>& object) {
-                return sdbusplus::message::object_path(object.first)
-                           .filename() == driveId;
-                });
-
-            if (drive == subtree.end())
-            {
-                messages::resourceNotFound(asyncResp->res, "Drive", driveId);
-                return;
-            }
-
-            const std::string& path = drive->first;
-            const dbus::utility::MapperServiceMap& connectionNames =
-                drive->second;
-
-            asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive";
-            asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
-                "/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()
-                                 << ", not equal to 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"] =
-                    boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
-                });
-
-            // default it to Enabled
-            asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
-
-            if constexpr (bmcwebEnableHealthPopulate)
-            {
-                auto health = std::make_shared<HealthPopulate>(asyncResp);
-                health->inventory.emplace_back(path);
-                health->populate();
-            }
-
-            addAllDriveInfo(asyncResp, connectionNames[0].first, path,
-                            connectionNames[0].second);
-            });
-        });
+            std::bind_front(handleSystemsStorageDriveGet, std::ref(app)));
 }
 
+inline void afterChassisDriveCollectionSubtreeGet(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& chassisId, const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreeResponse& subtree)
+{
+    if (ec)
+    {
+        if (ec == boost::system::errc::host_unreachable)
+        {
+            messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+            return;
+        }
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    // Iterate over all retrieved ObjectPaths.
+    for (const auto& [path, connectionNames] : subtree)
+    {
+        sdbusplus::message::object_path objPath(path);
+        if (objPath.filename() != chassisId)
+        {
+            continue;
+        }
+
+        if (connectionNames.empty())
+        {
+            BMCWEB_LOG_ERROR << "Got 0 Connection names";
+            continue;
+        }
+
+        asyncResp->res.jsonValue["@odata.type"] =
+            "#DriveCollection.DriveCollection";
+        asyncResp->res.jsonValue["@odata.id"] =
+            boost::urls::format("/redfish/v1/Chassis/{}/Drives", chassisId);
+        asyncResp->res.jsonValue["Name"] = "Drive Collection";
+
+        // Association lambda
+        dbus::utility::getAssociationEndPoints(
+            path + "/drive",
+            [asyncResp, chassisId](const boost::system::error_code& ec3,
+                                   const dbus::utility::MapperEndPoints& resp) {
+            if (ec3)
+            {
+                BMCWEB_LOG_ERROR << "Error in chassis Drive association ";
+            }
+            nlohmann::json& members = asyncResp->res.jsonValue["Members"];
+            // important if array is empty
+            members = nlohmann::json::array();
+
+            std::vector<std::string> leafNames;
+            for (const auto& drive : resp)
+            {
+                sdbusplus::message::object_path drivePath(drive);
+                leafNames.push_back(drivePath.filename());
+            }
+
+            std::sort(leafNames.begin(), leafNames.end(),
+                      AlphanumLess<std::string>());
+
+            for (const auto& leafName : leafNames)
+            {
+                nlohmann::json::object_t member;
+                member["@odata.id"] = boost::urls::format(
+                    "/redfish/v1/Chassis/{}/Drives/{}", chassisId, leafName);
+                members.emplace_back(std::move(member));
+                // navigation links will be registered in next patch set
+            }
+            asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
+            }); // end association lambda
+
+    }           // end Iterate over all retrieved ObjectPaths
+}
 /**
  * Chassis drives, this URL will show all the DriveCollection
  * information
@@ -601,80 +693,8 @@
         "xyz.openbmc_project.Inventory.Item.Chassis"};
     dbus::utility::getSubTree(
         "/xyz/openbmc_project/inventory", 0, interfaces,
-        [asyncResp,
-         chassisId](const boost::system::error_code& ec,
-                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
-        if (ec)
-        {
-            if (ec == boost::system::errc::host_unreachable)
-            {
-                messages::resourceNotFound(asyncResp->res, "Chassis",
-                                           chassisId);
-                return;
-            }
-            messages::internalError(asyncResp->res);
-            return;
-        }
-
-        // Iterate over all retrieved ObjectPaths.
-        for (const auto& [path, connectionNames] : subtree)
-        {
-            sdbusplus::message::object_path objPath(path);
-            if (objPath.filename() != chassisId)
-            {
-                continue;
-            }
-
-            if (connectionNames.empty())
-            {
-                BMCWEB_LOG_ERROR << "Got 0 Connection names";
-                continue;
-            }
-
-            asyncResp->res.jsonValue["@odata.type"] =
-                "#DriveCollection.DriveCollection";
-            asyncResp->res.jsonValue["@odata.id"] =
-                boost::urls::format("/redfish/v1/Chassis/{}/Drives", chassisId);
-            asyncResp->res.jsonValue["Name"] = "Drive Collection";
-
-            // Association lambda
-            dbus::utility::getAssociationEndPoints(
-                path + "/drive",
-                [asyncResp,
-                 chassisId](const boost::system::error_code& ec3,
-                            const dbus::utility::MapperEndPoints& resp) {
-                if (ec3)
-                {
-                    BMCWEB_LOG_ERROR << "Error in chassis Drive association ";
-                }
-                nlohmann::json& members = asyncResp->res.jsonValue["Members"];
-                // important if array is empty
-                members = nlohmann::json::array();
-
-                std::vector<std::string> leafNames;
-                for (const auto& drive : resp)
-                {
-                    sdbusplus::message::object_path drivePath(drive);
-                    leafNames.push_back(drivePath.filename());
-                }
-
-                std::sort(leafNames.begin(), leafNames.end(),
-                          AlphanumLess<std::string>());
-
-                for (const auto& leafName : leafNames)
-                {
-                    nlohmann::json::object_t member;
-                    member["@odata.id"] =
-                        boost::urls::format("/redfish/v1/Chassis/{}/Drives/{}",
-                                            chassisId, leafName);
-                    members.emplace_back(std::move(member));
-                    // navigation links will be registered in next patch set
-                }
-                asyncResp->res.jsonValue["Members@odata.count"] = resp.size();
-                }); // end association lambda
-
-        }           // end Iterate over all retrieved ObjectPaths
-        });
+        std::bind_front(afterChassisDriveCollectionSubtreeGet, asyncResp,
+                        chassisId));
 }
 
 inline void requestRoutesChassisDrive(App& app)
@@ -986,7 +1006,7 @@
     asyncResp->res.jsonValue["Members"] = std::move(members);
 }
 
-inline void storageControllerCollectionHandler(
+inline void handleSystemsStorageControllerCollectionGet(
     App& app, const crow::Request& req,
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     const std::string& systemName)
@@ -1022,7 +1042,7 @@
         });
 }
 
-inline void storageControllerHandler(
+inline void handleSystemsStorageControllerGet(
     App& app, const crow::Request& req,
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     const std::string& systemName, const std::string& controllerId)
@@ -1055,8 +1075,8 @@
 {
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/1/Controllers/")
         .privileges(redfish::privileges::getStorageControllerCollection)
-        .methods(boost::beast::http::verb::get)(
-            std::bind_front(storageControllerCollectionHandler, std::ref(app)));
+        .methods(boost::beast::http::verb::get)(std::bind_front(
+            handleSystemsStorageControllerCollectionGet, std::ref(app)));
 }
 
 inline void requestRoutesStorageController(App& app)
@@ -1064,7 +1084,7 @@
     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/Storage/1/Controllers/<str>")
         .privileges(redfish::privileges::getStorageController)
         .methods(boost::beast::http::verb::get)(
-            std::bind_front(storageControllerHandler, std::ref(app)));
+            std::bind_front(handleSystemsStorageControllerGet, std::ref(app)));
 }
 
 } // namespace redfish