xref: /openbmc/bmcweb/redfish-core/include/utils/systems_utils.hpp (revision 6b90272cda54bfb04a59062ce8bf20e89d244855)
1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 #pragma once
4 
5 #include "bmcweb_config.h"
6 
7 #include "async_resp.hpp"
8 #include "dbus_utility.hpp"
9 #include "error_messages.hpp"
10 #include "human_sort.hpp"
11 #include "logging.hpp"
12 #include "utility.hpp"
13 
14 #include <boost/url/format.hpp>
15 #include <boost/url/url.hpp>
16 #include <sdbusplus/message/native_types.hpp>
17 
18 #include <algorithm>
19 #include <array>
20 #include <functional>
21 #include <memory>
22 #include <string>
23 #include <string_view>
24 #include <utility>
25 #include <vector>
26 
27 namespace redfish
28 {
29 
handleSystemCollectionMembers(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const boost::system::error_code & ec,const dbus::utility::MapperGetSubTreePathsResponse & objects)30 inline void handleSystemCollectionMembers(
31     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
32     const boost::system::error_code& ec,
33     const dbus::utility::MapperGetSubTreePathsResponse& objects)
34 {
35     if (ec == boost::system::errc::io_error)
36     {
37         asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
38         asyncResp->res.jsonValue["Members@odata.count"] = 0;
39         return;
40     }
41 
42     if (ec)
43     {
44         BMCWEB_LOG_ERROR("DBUS response error {}", ec.value());
45         messages::internalError(asyncResp->res);
46         return;
47     }
48 
49     nlohmann::json& membersArray = asyncResp->res.jsonValue["Members"];
50     membersArray = nlohmann::json::array();
51 
52     // consider an empty result as single-host, since single-host systems
53     // do not populate the ManagedHost dbus interface
54     if (objects.empty())
55     {
56         asyncResp->res.jsonValue["Members@odata.count"] = 1;
57         nlohmann::json::object_t system;
58         system["@odata.id"] = boost::urls::format(
59             "/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
60         membersArray.emplace_back(std::move(system));
61 
62         if constexpr (BMCWEB_HYPERVISOR_COMPUTER_SYSTEM)
63         {
64             BMCWEB_LOG_DEBUG("Hypervisor is available");
65             asyncResp->res.jsonValue["Members@odata.count"] = 2;
66 
67             nlohmann::json::object_t hypervisor;
68             hypervisor["@odata.id"] = "/redfish/v1/Systems/hypervisor";
69             membersArray.emplace_back(std::move(hypervisor));
70         }
71 
72         return;
73     }
74 
75     std::vector<std::string> pathNames;
76     for (const auto& object : objects)
77     {
78         sdbusplus::message::object_path path(object);
79         std::string leaf = path.filename();
80         if (leaf.empty())
81         {
82             continue;
83         }
84         pathNames.emplace_back(leaf);
85     }
86     std::ranges::sort(pathNames, AlphanumLess<std::string>());
87 
88     for (const std::string& systemName : pathNames)
89     {
90         nlohmann::json::object_t member;
91         member["@odata.id"] =
92             boost::urls::format("/redfish/v1/Systems/{}", systemName);
93         membersArray.emplace_back(std::move(member));
94     }
95     asyncResp->res.jsonValue["Members@odata.count"] = membersArray.size();
96 }
97 
98 /**
99  * @brief Populate the system collection members from a GetSubTreePaths search
100  * of the inventory based of the ManagedHost dbus interface
101  *
102  * @param[i] asyncResp  Async response object
103  *
104  * @return None
105  */
getSystemCollectionMembers(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)106 inline void getSystemCollectionMembers(
107     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
108 {
109     constexpr std::array<std::string_view, 1> interfaces{
110         "xyz.openbmc_project.Inventory.Decorator.ManagedHost",
111     };
112 
113     BMCWEB_LOG_DEBUG("Get system collection members for /redfish/v1/Systems");
114 
115     dbus::utility::getSubTreePaths(
116         "/xyz/openbmc_project/inventory", 0, interfaces,
117         std::bind_front(handleSystemCollectionMembers, asyncResp));
118 }
119 } // namespace redfish
120