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