1 #pragma once
2 
3 #include "async_resp.hpp"
4 #include "dbus_utility.hpp"
5 #include "error_messages.hpp"
6 #include "http/utility.hpp"
7 #include "human_sort.hpp"
8 
9 #include <boost/url/url.hpp>
10 #include <nlohmann/json.hpp>
11 
12 #include <ranges>
13 #include <span>
14 #include <string>
15 #include <string_view>
16 #include <vector>
17 
18 namespace redfish
19 {
20 namespace collection_util
21 {
22 
23 inline void handleCollectionMembers(
24     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
25     const boost::urls::url& collectionPath, const boost::system::error_code& ec,
26     const dbus::utility::MapperGetSubTreePathsResponse& objects)
27 {
28     if (ec == boost::system::errc::io_error)
29     {
30         asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
31         asyncResp->res.jsonValue["Members@odata.count"] = 0;
32         return;
33     }
34 
35     if (ec)
36     {
37         BMCWEB_LOG_DEBUG("DBUS response error {}", ec.value());
38         messages::internalError(asyncResp->res);
39         return;
40     }
41 
42     std::vector<std::string> pathNames;
43     for (const auto& object : objects)
44     {
45         sdbusplus::message::object_path path(object);
46         std::string leaf = path.filename();
47         if (leaf.empty())
48         {
49             continue;
50         }
51         pathNames.push_back(leaf);
52     }
53     std::ranges::sort(pathNames, AlphanumLess<std::string>());
54 
55     nlohmann::json& members = asyncResp->res.jsonValue["Members"];
56     members = nlohmann::json::array();
57     for (const std::string& leaf : pathNames)
58     {
59         boost::urls::url url = collectionPath;
60         crow::utility::appendUrlPieces(url, leaf);
61         nlohmann::json::object_t member;
62         member["@odata.id"] = std::move(url);
63         members.emplace_back(std::move(member));
64     }
65     asyncResp->res.jsonValue["Members@odata.count"] = members.size();
66 }
67 
68 /**
69  * @brief Populate the collection "Members" from a GetSubTreePaths search of
70  *        inventory
71  *
72  * @param[i,o] asyncResp  Async response object
73  * @param[i]   collectionPath  Redfish collection path which is used for the
74  *             Members Redfish Path
75  * @param[i]   interfaces  List of interfaces to constrain the GetSubTree search
76  * @param[in]  subtree     D-Bus base path to constrain search to.
77  *
78  * @return void
79  */
80 inline void
81     getCollectionMembers(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
82                          const boost::urls::url& collectionPath,
83                          std::span<const std::string_view> interfaces,
84                          const std::string& subtree)
85 {
86     BMCWEB_LOG_DEBUG("Get collection members for: {}", collectionPath.buffer());
87     dbus::utility::getSubTreePaths(
88         subtree, 0, interfaces,
89         std::bind_front(handleCollectionMembers, asyncResp, collectionPath));
90 }
91 
92 } // namespace collection_util
93 } // namespace redfish
94