Revert "Refactor Managers with getValidManagerPath"

This reverts commit 0775449c62385f163a207d0f0c8e1f6338de1062.

CI bumps are failing. Romulus is failing [1].

(UTC) 2025/09/07 07:28:06.903907 -    0.212714 - Executing:
get('/redfish/v1/Managers/bmc')

[1]: https://discord.com/channels/775381525260664832/855566794994221117/1414329724477636649

Change-Id: I0ff80780cf1eb2f14484fdd0a521f90cc15e914b
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index 698f697..5932eb9 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -41,6 +41,7 @@
 #include <sdbusplus/message/native_types.hpp>
 #include <sdbusplus/unpack_properties.hpp>
 
+#include <array>
 #include <cstddef>
 #include <cstdint>
 #include <format>
@@ -56,6 +57,44 @@
 namespace redfish
 {
 
+inline void handleSetLocationIndicatorActive(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    bool locationIndicatorActive, const std::string& managerId,
+    const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths)
+{
+    if (ec)
+    {
+        if (ec == boost::system::errc::io_error)
+        {
+            // Not found
+            BMCWEB_LOG_WARNING("Manager {} not found", managerId);
+            messages::resourceNotFound(asyncResp->res, "Manager", managerId);
+            return;
+        }
+        BMCWEB_LOG_ERROR("D-Bus response error {}", ec.value());
+        messages::internalError(asyncResp->res);
+        return;
+    }
+    if (subtreePaths.empty())
+    {
+        BMCWEB_LOG_WARNING("Manager {} not found", managerId);
+        messages::resourceNotFound(asyncResp->res, "Manager", managerId);
+        return;
+    }
+    // Assume only 1 bmc D-Bus object
+    // Throw an error if there is more than 1
+    if (subtreePaths.size() != 1)
+    {
+        BMCWEB_LOG_ERROR("Found {} Bmc D-Bus paths", subtreePaths.size());
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    setLocationIndicatorActive(asyncResp, subtreePaths[0],
+                               locationIndicatorActive);
+}
+
 /**
  * Set the locationIndicatorActive.
  *
@@ -66,20 +105,13 @@
     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
     bool locationIndicatorActive, const std::string& managerId)
 {
-    manager_utils::getValidManagerPath(
-        asyncResp, managerId,
-        [asyncResp, locationIndicatorActive](
-            const std::string& managerPath,
-            const dbus::utility::MapperServiceMap& serviceMap) {
-            if (managerPath.empty() || serviceMap.size() != 1)
-            {
-                BMCWEB_LOG_DEBUG("Error getting bmc D-Bus object!");
-                messages::internalError(asyncResp->res);
-                return;
-            }
-            setLocationIndicatorActive(asyncResp, managerPath,
-                                       locationIndicatorActive);
-        });
+    // GetSubTree on all interfaces which provide info about a Manager
+    constexpr std::array<std::string_view, 1> interfaces = {
+        "xyz.openbmc_project.Inventory.Item.Bmc"};
+    dbus::utility::getSubTreePaths(
+        "/xyz/openbmc_project/inventory", 0, interfaces,
+        std::bind_front(handleSetLocationIndicatorActive, asyncResp,
+                        locationIndicatorActive, managerId));
 }
 
 inline std::string getBMCUpdateServiceName()
@@ -619,7 +651,6 @@
 }
 
 inline void getManagerData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-                           const std::string& managerId,
                            const std::string& managerPath,
                            const dbus::utility::MapperServiceMap& serviceMap)
 {
@@ -630,12 +661,102 @@
         return;
     }
 
+    for (const auto& [connectionName, interfaces] : serviceMap)
+    {
+        for (const auto& interfaceName : interfaces)
+        {
+            if (interfaceName ==
+                "xyz.openbmc_project.Inventory.Decorator.Asset")
+            {
+                dbus::utility::getAllProperties(
+                    *crow::connections::systemBus, connectionName, managerPath,
+                    "xyz.openbmc_project.Inventory.Decorator.Asset",
+                    std::bind_front(getPhysicalAssets, asyncResp));
+            }
+            else if (interfaceName ==
+                     "xyz.openbmc_project.Inventory.Decorator.LocationCode")
+            {
+                getLocation(asyncResp, connectionName, managerPath);
+            }
+            else if (interfaceName ==
+                     "xyz.openbmc_project.Association.Definitions")
+            {
+                getLocationIndicatorActive(asyncResp, managerPath);
+            }
+        }
+    }
+}
+
+inline void afterGetManagerObject(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const boost::system::error_code& ec,
+    const dbus::utility::MapperGetSubTreeResponse& subtree,
+    const std::function<
+        void(const std::string& managerPath,
+             const dbus::utility::MapperServiceMap& serviceMap)>& callback)
+{
+    if (ec)
+    {
+        BMCWEB_LOG_DEBUG("D-Bus response error on GetSubTree {}", ec);
+        return;
+    }
+    if (subtree.empty())
+    {
+        BMCWEB_LOG_DEBUG("Can't find bmc D-Bus object!");
+        return;
+    }
+    // Assume only 1 bmc D-Bus object
+    // Throw an error if there is more than 1
+    if (subtree.size() > 1)
+    {
+        BMCWEB_LOG_ERROR("Found more than 1 bmc D-Bus object!");
+        messages::internalError(asyncResp->res);
+        return;
+    }
+
+    callback(subtree[0].first, subtree[0].second);
+}
+
+inline void getManagerObject(
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& /* managerId */,
+    std::function<void(const std::string& managerPath,
+                       const dbus::utility::MapperServiceMap& serviceMap)>&&
+        callback)
+{
+    constexpr std::array<std::string_view, 1> interfaces = {
+        "xyz.openbmc_project.Inventory.Item.Bmc"};
+    dbus::utility::getSubTree(
+        "/xyz/openbmc_project/inventory", 0, interfaces,
+        [asyncResp, callback{std::move(callback)}](
+            const boost::system::error_code& ec,
+            const dbus::utility::MapperGetSubTreeResponse& subtree) {
+            afterGetManagerObject(asyncResp, ec, subtree, callback);
+        });
+}
+
+inline void handleManagerGet(
+    App& app, const crow::Request& req,
+    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+    const std::string& managerId)
+{
+    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+    {
+        return;
+    }
+
+    if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
+    {
+        messages::resourceNotFound(asyncResp->res, "Manager", managerId);
+        return;
+    }
+
     std::string uuid = persistent_data::getConfig().systemUuid;
 
-    asyncResp->res.jsonValue["@odata.id"] =
-        boost::urls::format("/redfish/v1/Managers/{}", managerId);
+    asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+        "/redfish/v1/Managers/{}", BMCWEB_REDFISH_MANAGER_URI_NAME);
     asyncResp->res.jsonValue["@odata.type"] = "#Manager.v1_15_0.Manager";
-    asyncResp->res.jsonValue["Id"] = managerId;
+    asyncResp->res.jsonValue["Id"] = BMCWEB_REDFISH_MANAGER_URI_NAME;
     asyncResp->res.jsonValue["Name"] = "OpenBmc Manager";
     asyncResp->res.jsonValue["Description"] = "Baseboard Management Controller";
     asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On;
@@ -645,14 +766,14 @@
     asyncResp->res.jsonValue["ServiceEntryPointUUID"] = uuid;
     asyncResp->res.jsonValue["Model"] = "OpenBmc"; // TODO(ed), get model
 
-    asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
-        boost::urls::format("/redfish/v1/Managers/{}/LogServices", managerId);
+    asyncResp->res.jsonValue["LogServices"]["@odata.id"] = boost::urls::format(
+        "/redfish/v1/Managers/{}/LogServices", BMCWEB_REDFISH_MANAGER_URI_NAME);
     asyncResp->res.jsonValue["NetworkProtocol"]["@odata.id"] =
         boost::urls::format("/redfish/v1/Managers/{}/NetworkProtocol",
-                            managerId);
+                            BMCWEB_REDFISH_MANAGER_URI_NAME);
     asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
         boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces",
-                            managerId);
+                            BMCWEB_REDFISH_MANAGER_URI_NAME);
 
     manager_utils::getServiceIdentification(asyncResp, false);
 
@@ -660,17 +781,19 @@
     {
         asyncResp->res.jsonValue["VirtualMedia"]["@odata.id"] =
             boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia",
-                                managerId);
+                                BMCWEB_REDFISH_MANAGER_URI_NAME);
     }
 
     // Manager.Reset (an action) can be many values, OpenBMC only
     // supports BMC reboot.
     nlohmann::json& managerReset =
         asyncResp->res.jsonValue["Actions"]["#Manager.Reset"];
-    managerReset["target"] = boost::urls::format(
-        "/redfish/v1/Managers/{}/Actions/Manager.Reset", managerId);
-    managerReset["@Redfish.ActionInfo"] = boost::urls::format(
-        "/redfish/v1/Managers/{}/ResetActionInfo", managerId);
+    managerReset["target"] =
+        boost::urls::format("/redfish/v1/Managers/{}/Actions/Manager.Reset",
+                            BMCWEB_REDFISH_MANAGER_URI_NAME);
+    managerReset["@Redfish.ActionInfo"] =
+        boost::urls::format("/redfish/v1/Managers/{}/ResetActionInfo",
+                            BMCWEB_REDFISH_MANAGER_URI_NAME);
 
     // ResetToDefaults (Factory Reset) has values like
     // PreserveNetworkAndUsers and PreserveNetwork that aren't supported
@@ -678,7 +801,8 @@
     nlohmann::json& resetToDefaults =
         asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
     resetToDefaults["target"] = boost::urls::format(
-        "/redfish/v1/Managers/{}/Actions/Manager.ResetToDefaults", managerId);
+        "/redfish/v1/Managers/{}/Actions/Manager.ResetToDefaults",
+        BMCWEB_REDFISH_MANAGER_URI_NAME);
     resetToDefaults["ResetType@Redfish.AllowableValues"] =
         nlohmann::json::array_t({"ResetAll"});
 
@@ -720,8 +844,9 @@
     // ManagerDiagnosticData is added for all BMCs.
     nlohmann::json& managerDiagnosticData =
         asyncResp->res.jsonValue["ManagerDiagnosticData"];
-    managerDiagnosticData["@odata.id"] = boost::urls::format(
-        "/redfish/v1/Managers/{}/ManagerDiagnosticData", managerId);
+    managerDiagnosticData["@odata.id"] =
+        boost::urls::format("/redfish/v1/Managers/{}/ManagerDiagnosticData",
+                            BMCWEB_REDFISH_MANAGER_URI_NAME);
 
     getMainChassisId(
         asyncResp, [](const std::string& chassisId,
@@ -760,51 +885,8 @@
             checkForQuiesced(asyncResp);
         });
 
-    for (const auto& [connectionName, interfaces] : serviceMap)
-    {
-        for (const auto& interfaceName : interfaces)
-        {
-            if (interfaceName ==
-                "xyz.openbmc_project.Inventory.Decorator.Asset")
-            {
-                dbus::utility::getAllProperties(
-                    *crow::connections::systemBus, connectionName, managerPath,
-                    "xyz.openbmc_project.Inventory.Decorator.Asset",
-                    std::bind_front(getPhysicalAssets, asyncResp));
-            }
-            else if (interfaceName ==
-                     "xyz.openbmc_project.Inventory.Decorator.LocationCode")
-            {
-                getLocation(asyncResp, connectionName, managerPath);
-            }
-            else if (interfaceName ==
-                     "xyz.openbmc_project.Association.Definitions")
-            {
-                getLocationIndicatorActive(asyncResp, managerPath);
-            }
-        }
-    }
-}
-
-inline void handleManagerGet(
-    App& app, const crow::Request& req,
-    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
-    const std::string& managerId)
-{
-    if (!redfish::setUpRedfishRoute(app, req, asyncResp))
-    {
-        return;
-    }
-
-    if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
-    {
-        messages::resourceNotFound(asyncResp->res, "Manager", managerId);
-        return;
-    }
-
-    manager_utils::getValidManagerPath(
-        asyncResp, managerId,
-        std::bind_front(getManagerData, asyncResp, managerId));
+    getManagerObject(asyncResp, managerId,
+                     std::bind_front(getManagerData, asyncResp));
 
     RedfishService::getInstance(app).handleSubRoute(req, asyncResp);
 }