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