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