xref: /openbmc/bmcweb/features/redfish/include/utils/systems_utils.hpp (revision 3577e44683a5ade8ad02a6418984b56f4ca2bcac)
11bb1a50fSOliver Brewka // SPDX-License-Identifier: Apache-2.0
21bb1a50fSOliver Brewka // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3fc5ae94dSOliver Brewka #pragma once
4fc5ae94dSOliver Brewka 
5fc5ae94dSOliver Brewka #include "bmcweb_config.h"
6fc5ae94dSOliver Brewka 
7fc5ae94dSOliver Brewka #include "async_resp.hpp"
8fc5ae94dSOliver Brewka #include "dbus_utility.hpp"
9fc5ae94dSOliver Brewka #include "error_messages.hpp"
10fc5ae94dSOliver Brewka #include "human_sort.hpp"
11fc5ae94dSOliver Brewka #include "logging.hpp"
12fc5ae94dSOliver Brewka 
13fc5ae94dSOliver Brewka #include <boost/url/format.hpp>
14fc5ae94dSOliver Brewka #include <sdbusplus/message/native_types.hpp>
15fc5ae94dSOliver Brewka 
16fc5ae94dSOliver Brewka #include <algorithm>
17fc5ae94dSOliver Brewka #include <array>
182fdbc1f3SOliver Brewka #include <cstdint>
19fc5ae94dSOliver Brewka #include <functional>
20fc5ae94dSOliver Brewka #include <memory>
21fc5ae94dSOliver Brewka #include <string>
22fc5ae94dSOliver Brewka #include <string_view>
23fc5ae94dSOliver Brewka #include <utility>
24fc5ae94dSOliver Brewka #include <vector>
25fc5ae94dSOliver Brewka 
26fc5ae94dSOliver Brewka namespace redfish
27fc5ae94dSOliver Brewka {
28fc5ae94dSOliver Brewka 
29fc5ae94dSOliver Brewka inline void handleSystemCollectionMembers(
30fc5ae94dSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
31fc5ae94dSOliver Brewka     const boost::system::error_code& ec,
32fc5ae94dSOliver Brewka     const dbus::utility::MapperGetSubTreePathsResponse& objects)
33fc5ae94dSOliver Brewka {
34fc5ae94dSOliver Brewka     if (ec == boost::system::errc::io_error)
35fc5ae94dSOliver Brewka     {
36fc5ae94dSOliver Brewka         asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
37fc5ae94dSOliver Brewka         asyncResp->res.jsonValue["Members@odata.count"] = 0;
38fc5ae94dSOliver Brewka         return;
39fc5ae94dSOliver Brewka     }
40fc5ae94dSOliver Brewka 
41fc5ae94dSOliver Brewka     if (ec)
42fc5ae94dSOliver Brewka     {
43fc5ae94dSOliver Brewka         BMCWEB_LOG_ERROR("DBUS response error {}", ec.value());
44fc5ae94dSOliver Brewka         messages::internalError(asyncResp->res);
45fc5ae94dSOliver Brewka         return;
46fc5ae94dSOliver Brewka     }
47fc5ae94dSOliver Brewka 
48fc5ae94dSOliver Brewka     nlohmann::json& membersArray = asyncResp->res.jsonValue["Members"];
49fc5ae94dSOliver Brewka     membersArray = nlohmann::json::array();
50fc5ae94dSOliver Brewka 
51fc5ae94dSOliver Brewka     // consider an empty result as single-host, since single-host systems
52fc5ae94dSOliver Brewka     // do not populate the ManagedHost dbus interface
53fc5ae94dSOliver Brewka     if (objects.empty())
54fc5ae94dSOliver Brewka     {
55fc5ae94dSOliver Brewka         asyncResp->res.jsonValue["Members@odata.count"] = 1;
56fc5ae94dSOliver Brewka         nlohmann::json::object_t system;
57fc5ae94dSOliver Brewka         system["@odata.id"] = boost::urls::format(
58fc5ae94dSOliver Brewka             "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
59fc5ae94dSOliver Brewka         membersArray.emplace_back(std::move(system));
60fc5ae94dSOliver Brewka 
61fc5ae94dSOliver Brewka         if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
62fc5ae94dSOliver Brewka         {
63fc5ae94dSOliver Brewka             BMCWEB_LOG_DEBUG("Hypervisor is available");
64fc5ae94dSOliver Brewka             asyncResp->res.jsonValue["Members@odata.count"] = 2;
65fc5ae94dSOliver Brewka 
66fc5ae94dSOliver Brewka             nlohmann::json::object_t hypervisor;
67fc5ae94dSOliver Brewka             hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
68fc5ae94dSOliver Brewka             membersArray.emplace_back(std::move(hypervisor));
69fc5ae94dSOliver Brewka         }
70fc5ae94dSOliver Brewka 
71fc5ae94dSOliver Brewka         return;
72fc5ae94dSOliver Brewka     }
73fc5ae94dSOliver Brewka 
74fc5ae94dSOliver Brewka     std::vector<std::string> pathNames;
75fc5ae94dSOliver Brewka     for (const auto& object : objects)
76fc5ae94dSOliver Brewka     {
77fc5ae94dSOliver Brewka         sdbusplus::message::object_path path(object);
78fc5ae94dSOliver Brewka         std::string leaf = path.filename();
79fc5ae94dSOliver Brewka         if (leaf.empty())
80fc5ae94dSOliver Brewka         {
81fc5ae94dSOliver Brewka             continue;
82fc5ae94dSOliver Brewka         }
83fc5ae94dSOliver Brewka         pathNames.emplace_back(leaf);
84fc5ae94dSOliver Brewka     }
85fc5ae94dSOliver Brewka     std::ranges::sort(pathNames, AlphanumLess<std::string>());
86fc5ae94dSOliver Brewka 
87fc5ae94dSOliver Brewka     for (const std::string& systemName : pathNames)
88fc5ae94dSOliver Brewka     {
89fc5ae94dSOliver Brewka         nlohmann::json::object_t member;
906b90272cSOliver Brewka         member["@odata.id"] =
916b90272cSOliver Brewka             boost::urls::format("/redfish/v1/Systems/{}", systemName);
92fc5ae94dSOliver Brewka         membersArray.emplace_back(std::move(member));
93fc5ae94dSOliver Brewka     }
94fc5ae94dSOliver Brewka     asyncResp->res.jsonValue["Members@odata.count"] = membersArray.size();
95fc5ae94dSOliver Brewka }
96fc5ae94dSOliver Brewka 
97fc5ae94dSOliver Brewka /**
98fc5ae94dSOliver Brewka  * @brief Populate the system collection members from a GetSubTreePaths search
99fc5ae94dSOliver Brewka  * of the inventory based of the ManagedHost dbus interface
100fc5ae94dSOliver Brewka  *
101fc5ae94dSOliver Brewka  * @param[i] asyncResp  Async response object
102fc5ae94dSOliver Brewka  *
103fc5ae94dSOliver Brewka  * @return None
104fc5ae94dSOliver Brewka  */
105fc5ae94dSOliver Brewka inline void getSystemCollectionMembers(
106fc5ae94dSOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
107fc5ae94dSOliver Brewka {
108fc5ae94dSOliver Brewka     constexpr std::array<std::string_view, 1> interfaces{
109fc5ae94dSOliver Brewka         "xyz.openbmc_project.Inventory.Decorator.ManagedHost",
110fc5ae94dSOliver Brewka     };
111fc5ae94dSOliver Brewka 
112fc5ae94dSOliver Brewka     BMCWEB_LOG_DEBUG("Get system collection members for /redfish/v1/Systems");
113fc5ae94dSOliver Brewka 
114fc5ae94dSOliver Brewka     dbus::utility::getSubTreePaths(
115fc5ae94dSOliver Brewka         "/xyz/openbmc_project/inventory", 0, interfaces,
116fc5ae94dSOliver Brewka         std::bind_front(handleSystemCollectionMembers, asyncResp));
117fc5ae94dSOliver Brewka }
1182fdbc1f3SOliver Brewka 
1192fdbc1f3SOliver Brewka inline void getManagedHostProperty(
1202fdbc1f3SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1212fdbc1f3SOliver Brewka     const std::string& systemName, const std::string& systemPath,
1222fdbc1f3SOliver Brewka     std::function<void(const uint64_t computerSystemIndex)> callback)
1232fdbc1f3SOliver Brewka {
1242fdbc1f3SOliver Brewka     dbus::utility::getProperty<uint64_t>(
1252fdbc1f3SOliver Brewka         "xyz.openbmc_project.EntityManager", systemPath,
1262fdbc1f3SOliver Brewka         "xyz.openbmc_project.Inventory.Decorator.ManagedHost", "HostIndex",
1272fdbc1f3SOliver Brewka         [asyncResp, systemName, systemPath, callback = std::move(callback)](
1282fdbc1f3SOliver Brewka             const boost::system::error_code& ec, const uint64_t hostIndex) {
1292fdbc1f3SOliver Brewka             if (ec)
1302fdbc1f3SOliver Brewka             {
1312fdbc1f3SOliver Brewka                 BMCWEB_LOG_WARNING("DBUS response error {}", ec);
1322fdbc1f3SOliver Brewka                 messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1332fdbc1f3SOliver Brewka                                            systemName);
1342fdbc1f3SOliver Brewka                 return;
1352fdbc1f3SOliver Brewka             }
1362fdbc1f3SOliver Brewka             BMCWEB_LOG_DEBUG("Got index {} for path {}", hostIndex, systemPath);
1372fdbc1f3SOliver Brewka             callback(hostIndex);
1382fdbc1f3SOliver Brewka         });
1392fdbc1f3SOliver Brewka }
1402fdbc1f3SOliver Brewka 
1412fdbc1f3SOliver Brewka inline void afterGetComputerSystemSubTreePaths(
1422fdbc1f3SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1432fdbc1f3SOliver Brewka     const std::string& systemName,
1442fdbc1f3SOliver Brewka     std::function<void(const uint64_t computerSystemIndex)>& callback,
1452fdbc1f3SOliver Brewka     const boost::system::error_code& ec,
1462fdbc1f3SOliver Brewka     const dbus::utility::MapperGetSubTreePathsResponse& objects)
1472fdbc1f3SOliver Brewka {
1482fdbc1f3SOliver Brewka     sdbusplus::message::object_path systemPath;
1492fdbc1f3SOliver Brewka     if (ec)
1502fdbc1f3SOliver Brewka     {
1512fdbc1f3SOliver Brewka         if (ec.value() == boost::system::errc::io_error)
1522fdbc1f3SOliver Brewka         {
1532fdbc1f3SOliver Brewka             BMCWEB_LOG_WARNING("EIO - System not found");
1542fdbc1f3SOliver Brewka             messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1552fdbc1f3SOliver Brewka                                        systemName);
1562fdbc1f3SOliver Brewka             return;
1572fdbc1f3SOliver Brewka         }
1582fdbc1f3SOliver Brewka 
1592fdbc1f3SOliver Brewka         BMCWEB_LOG_ERROR("DBus method call failed with error {}", ec.value());
1602fdbc1f3SOliver Brewka         messages::internalError(asyncResp->res);
1612fdbc1f3SOliver Brewka         return;
1622fdbc1f3SOliver Brewka     }
1632fdbc1f3SOliver Brewka 
1642fdbc1f3SOliver Brewka     const auto& found = std::ranges::find_if(
1652fdbc1f3SOliver Brewka         objects, [systemName](const sdbusplus::message::object_path& path) {
1662fdbc1f3SOliver Brewka             return path.filename() == systemName;
1672fdbc1f3SOliver Brewka         });
1682fdbc1f3SOliver Brewka 
1692fdbc1f3SOliver Brewka     if (found == objects.end())
1702fdbc1f3SOliver Brewka     {
1712fdbc1f3SOliver Brewka         BMCWEB_LOG_WARNING("Failed to match systemName: {}", systemName);
1722fdbc1f3SOliver Brewka         messages::resourceNotFound(asyncResp->res, "ComputerSystem",
1732fdbc1f3SOliver Brewka                                    systemName);
1742fdbc1f3SOliver Brewka         return;
1752fdbc1f3SOliver Brewka     }
1762fdbc1f3SOliver Brewka 
1772fdbc1f3SOliver Brewka     systemPath = *found;
1782fdbc1f3SOliver Brewka 
1792fdbc1f3SOliver Brewka     getManagedHostProperty(asyncResp, systemName, systemPath,
1802fdbc1f3SOliver Brewka                            std::move(callback));
1812fdbc1f3SOliver Brewka }
1822fdbc1f3SOliver Brewka 
1832fdbc1f3SOliver Brewka /**
1842fdbc1f3SOliver Brewka  * @brief Retrieve the index associated with the requested system based on the
1852fdbc1f3SOliver Brewka  * ManagedHost interface
1862fdbc1f3SOliver Brewka  *
1872fdbc1f3SOliver Brewka  * @param[i] asyncResp  Async response object
1882fdbc1f3SOliver Brewka  * @param[i] systemName The requested system
1892fdbc1f3SOliver Brewka  * @param[i] callback   Callback to call once the index has been found
1902fdbc1f3SOliver Brewka  *
1912fdbc1f3SOliver Brewka  * @return None
1922fdbc1f3SOliver Brewka  */
1932fdbc1f3SOliver Brewka inline void getComputerSystemIndex(
1942fdbc1f3SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1952fdbc1f3SOliver Brewka     const std::string& systemName,
1962fdbc1f3SOliver Brewka     std::function<void(const uint64_t computerSystemIndex)>&& callback)
1972fdbc1f3SOliver Brewka {
1982fdbc1f3SOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
1992fdbc1f3SOliver Brewka     {
2002fdbc1f3SOliver Brewka         constexpr std::array<std::string_view, 1> interfaces{
2012fdbc1f3SOliver Brewka             "xyz.openbmc_project.Inventory.Decorator.ManagedHost"};
2022fdbc1f3SOliver Brewka         dbus::utility::getSubTreePaths(
2032fdbc1f3SOliver Brewka             "/xyz/openbmc_project/inventory", 0, interfaces,
2042fdbc1f3SOliver Brewka             std::bind_front(afterGetComputerSystemSubTreePaths, asyncResp,
2052fdbc1f3SOliver Brewka                             systemName, std::move(callback)));
2062fdbc1f3SOliver Brewka     }
2072fdbc1f3SOliver Brewka     else
2082fdbc1f3SOliver Brewka     {
2092fdbc1f3SOliver Brewka         // on single-host, fallback to index 0
2102fdbc1f3SOliver Brewka         BMCWEB_LOG_DEBUG(
2112fdbc1f3SOliver Brewka             "Single-host detected, fallback to computerSystemIndex 0");
2122fdbc1f3SOliver Brewka         callback(0);
2132fdbc1f3SOliver Brewka     }
2142fdbc1f3SOliver Brewka }
2152fdbc1f3SOliver Brewka 
2162fdbc1f3SOliver Brewka inline sdbusplus::message::object_path getHostStateObjectPath(
2172fdbc1f3SOliver Brewka     const uint64_t computerSystemIndex)
2182fdbc1f3SOliver Brewka {
2192fdbc1f3SOliver Brewka     const sdbusplus::message::object_path hostStatePath(
2202fdbc1f3SOliver Brewka         "/xyz/openbmc_project/state/host" +
2212fdbc1f3SOliver Brewka         std::to_string(computerSystemIndex));
2222fdbc1f3SOliver Brewka 
2232fdbc1f3SOliver Brewka     return hostStatePath;
2242fdbc1f3SOliver Brewka }
2252fdbc1f3SOliver Brewka 
2262fdbc1f3SOliver Brewka inline std::string getHostStateServiceName(const uint64_t computerSystemIndex)
2272fdbc1f3SOliver Brewka {
2282fdbc1f3SOliver Brewka     std::string hostStateService = "xyz.openbmc_project.State.Host";
2292fdbc1f3SOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2302fdbc1f3SOliver Brewka     {
2312fdbc1f3SOliver Brewka         hostStateService += std::to_string(computerSystemIndex);
2322fdbc1f3SOliver Brewka     }
2332fdbc1f3SOliver Brewka 
2342fdbc1f3SOliver Brewka     return hostStateService;
2352fdbc1f3SOliver Brewka }
2362fdbc1f3SOliver Brewka 
2372fdbc1f3SOliver Brewka inline sdbusplus::message::object_path getChassisStateObjectPath(
2382fdbc1f3SOliver Brewka     const uint64_t computerSystemIndex)
2392fdbc1f3SOliver Brewka {
2402fdbc1f3SOliver Brewka     const sdbusplus::message::object_path chassisStatePath(
2412fdbc1f3SOliver Brewka         "/xyz/openbmc_project/state/chassis" +
2422fdbc1f3SOliver Brewka         std::to_string(computerSystemIndex));
2432fdbc1f3SOliver Brewka 
2442fdbc1f3SOliver Brewka     return chassisStatePath;
2452fdbc1f3SOliver Brewka }
2462fdbc1f3SOliver Brewka 
2472fdbc1f3SOliver Brewka inline std::string getChassisStateServiceName(
2482fdbc1f3SOliver Brewka     const uint64_t computerSystemIndex)
2492fdbc1f3SOliver Brewka {
2502fdbc1f3SOliver Brewka     std::string chassisStateService = "xyz.openbmc_project.State.Chassis";
2512fdbc1f3SOliver Brewka     if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
2522fdbc1f3SOliver Brewka     {
2532fdbc1f3SOliver Brewka         chassisStateService += std::to_string(computerSystemIndex);
2542fdbc1f3SOliver Brewka     }
2552fdbc1f3SOliver Brewka 
2562fdbc1f3SOliver Brewka     return chassisStateService;
2572fdbc1f3SOliver Brewka }
2582eaa9279SJanet Adkins 
2592eaa9279SJanet Adkins namespace systems_utils
2602eaa9279SJanet Adkins {
2612eaa9279SJanet Adkins 
2622eaa9279SJanet Adkins inline void afterGetValidSystemsPath(
2632eaa9279SJanet Adkins     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2642eaa9279SJanet Adkins     const std::string& systemId,
2652eaa9279SJanet Adkins     const std::function<void(const std::optional<std::string>&)>& callback,
2662eaa9279SJanet Adkins     const boost::system::error_code& ec,
2672eaa9279SJanet Adkins     const dbus::utility::MapperGetSubTreePathsResponse& systemsPaths)
2682eaa9279SJanet Adkins {
2692eaa9279SJanet Adkins     if (ec)
2702eaa9279SJanet Adkins     {
2712eaa9279SJanet Adkins         if (ec == boost::system::errc::io_error)
2722eaa9279SJanet Adkins         {
2732eaa9279SJanet Adkins             BMCWEB_LOG_DEBUG("No systems found");
2742eaa9279SJanet Adkins             callback(std::nullopt);
2752eaa9279SJanet Adkins             return;
2762eaa9279SJanet Adkins         }
2772eaa9279SJanet Adkins         BMCWEB_LOG_ERROR("DBUS response error: {}", ec.value());
2782eaa9279SJanet Adkins         messages::internalError(asyncResp->res);
2792eaa9279SJanet Adkins         return;
2802eaa9279SJanet Adkins     }
2812eaa9279SJanet Adkins 
2822eaa9279SJanet Adkins     for (const std::string& system : systemsPaths)
2832eaa9279SJanet Adkins     {
2842eaa9279SJanet Adkins         sdbusplus::message::object_path path(system);
2852eaa9279SJanet Adkins         if (path.filename() == systemId)
2862eaa9279SJanet Adkins         {
2872eaa9279SJanet Adkins             callback(path);
2882eaa9279SJanet Adkins             return;
2892eaa9279SJanet Adkins         }
2902eaa9279SJanet Adkins     }
2912eaa9279SJanet Adkins     BMCWEB_LOG_DEBUG("No system named {} found", systemId);
2922eaa9279SJanet Adkins     callback(std::nullopt);
2932eaa9279SJanet Adkins }
2942eaa9279SJanet Adkins 
2952eaa9279SJanet Adkins inline void getValidSystemsPath(
2962eaa9279SJanet Adkins     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
2972eaa9279SJanet Adkins     const std::string& systemId,
2982eaa9279SJanet Adkins     std::function<void(const std::optional<std::string>&)>&& callback)
2992eaa9279SJanet Adkins {
3002eaa9279SJanet Adkins     BMCWEB_LOG_DEBUG("Get path for {}", systemId);
3012eaa9279SJanet Adkins 
3022eaa9279SJanet Adkins     constexpr std::array<std::string_view, 2> interfaces = {
3032eaa9279SJanet Adkins         "xyz.openbmc_project.Inventory.Decorator.ManagedHost",
3042eaa9279SJanet Adkins         "xyz.openbmc_project.Inventory.Item.System"};
3052eaa9279SJanet Adkins     dbus::utility::getSubTreePaths(
3062eaa9279SJanet Adkins         "/xyz/openbmc_project/inventory", 0, interfaces,
3072eaa9279SJanet Adkins         [asyncResp, systemId, callback{std::move(callback)}](
3082eaa9279SJanet Adkins             const boost::system::error_code& ec,
3092eaa9279SJanet Adkins             const dbus::utility::MapperGetSubTreePathsResponse& systemsPaths) {
3102eaa9279SJanet Adkins             afterGetValidSystemsPath(asyncResp, systemId, callback, ec,
3112eaa9279SJanet Adkins                                      systemsPaths);
3122eaa9279SJanet Adkins         });
3132eaa9279SJanet Adkins }
3142eaa9279SJanet Adkins 
3152eaa9279SJanet Adkins } // namespace systems_utils
316*5e7c1f31SOliver Brewka 
317*5e7c1f31SOliver Brewka /**
318*5e7c1f31SOliver Brewka  * @brief Match computerSystemIndex with index contained by an object path
319*5e7c1f31SOliver Brewka  *        i.e 1 in /xyz/openbmc/project/control/host1/policy/TPMEnable
320*5e7c1f31SOliver Brewka  *
321*5e7c1f31SOliver Brewka  * @param[i] asyncResp           Shared pointer for generating response
322*5e7c1f31SOliver Brewka  * @param[i] computerSystemIndex The index to match against
323*5e7c1f31SOliver Brewka  * @param[i] subtree             Mapper response object
324*5e7c1f31SOliver Brewka  * @param[o] objectPath          Buffer for matched object path
325*5e7c1f31SOliver Brewka  * @param[o] service             Buffer for service of matched object
326*5e7c1f31SOliver Brewka  *                               path
327*5e7c1f31SOliver Brewka  *
328*5e7c1f31SOliver Brewka  * @return true if match found, else false
329*5e7c1f31SOliver Brewka  */
330*5e7c1f31SOliver Brewka inline bool indexMatchingSubTreeMapObjectPath(
331*5e7c1f31SOliver Brewka     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
332*5e7c1f31SOliver Brewka     const uint64_t computerSystemIndex,
333*5e7c1f31SOliver Brewka     const dbus::utility::MapperGetSubTreeResponse& subtree,
334*5e7c1f31SOliver Brewka     std::string& objectPath, std::string& service)
335*5e7c1f31SOliver Brewka {
336*5e7c1f31SOliver Brewka     const std::string host = std::format("host{}", computerSystemIndex);
337*5e7c1f31SOliver Brewka 
338*5e7c1f31SOliver Brewka     for (const auto& obj : subtree)
339*5e7c1f31SOliver Brewka     {
340*5e7c1f31SOliver Brewka         std::string tmp = host;
341*5e7c1f31SOliver Brewka         const sdbusplus::message::object_path path{obj.first};
342*5e7c1f31SOliver Brewka         const std::string serv = obj.second.begin()->first;
343*5e7c1f31SOliver Brewka 
344*5e7c1f31SOliver Brewka         if (path.str.empty() || obj.second.size() != 1)
345*5e7c1f31SOliver Brewka         {
346*5e7c1f31SOliver Brewka             BMCWEB_LOG_DEBUG("Error finding index in object path");
347*5e7c1f31SOliver Brewka             messages::internalError(asyncResp->res);
348*5e7c1f31SOliver Brewka             return false;
349*5e7c1f31SOliver Brewka         }
350*5e7c1f31SOliver Brewka 
351*5e7c1f31SOliver Brewka         objectPath = path;
352*5e7c1f31SOliver Brewka         service = serv;
353*5e7c1f31SOliver Brewka 
354*5e7c1f31SOliver Brewka         if (path.filename() == host)
355*5e7c1f31SOliver Brewka         {
356*5e7c1f31SOliver Brewka             return true;
357*5e7c1f31SOliver Brewka         }
358*5e7c1f31SOliver Brewka 
359*5e7c1f31SOliver Brewka         tmp.insert(0, 1, '/');
360*5e7c1f31SOliver Brewka         tmp.append("/");
361*5e7c1f31SOliver Brewka         if (path.str.find(host) != std::string::npos)
362*5e7c1f31SOliver Brewka         {
363*5e7c1f31SOliver Brewka             return true;
364*5e7c1f31SOliver Brewka         }
365*5e7c1f31SOliver Brewka     }
366*5e7c1f31SOliver Brewka 
367*5e7c1f31SOliver Brewka     return false;
368*5e7c1f31SOliver Brewka }
369fc5ae94dSOliver Brewka } // namespace redfish
370