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