xref: /openbmc/bmcweb/features/redfish/include/utils/collection.hpp (revision 3544d2a719c8bb7b07f9a39f61a3770ec84b909f)
1116bcc5cSGunnar Mills #pragma once
2116bcc5cSGunnar Mills 
33ccb3adbSEd Tanous #include "async_resp.hpp"
47a1dbc48SGeorge Liu #include "dbus_utility.hpp"
53ccb3adbSEd Tanous #include "error_messages.hpp"
63ccb3adbSEd Tanous #include "http/utility.hpp"
73ccb3adbSEd Tanous #include "human_sort.hpp"
87a1dbc48SGeorge Liu 
93ccb3adbSEd Tanous #include <boost/url/url.hpp>
103ccb3adbSEd Tanous #include <nlohmann/json.hpp>
11116bcc5cSGunnar Mills 
12*3544d2a7SEd Tanous #include <ranges>
137a1dbc48SGeorge Liu #include <span>
14116bcc5cSGunnar Mills #include <string>
157a1dbc48SGeorge Liu #include <string_view>
16116bcc5cSGunnar Mills #include <vector>
17116bcc5cSGunnar Mills 
18116bcc5cSGunnar Mills namespace redfish
19116bcc5cSGunnar Mills {
20116bcc5cSGunnar Mills namespace collection_util
21116bcc5cSGunnar Mills {
22116bcc5cSGunnar Mills 
2305030b8eSGunnar Mills /**
24dea43dd4SJonathan Doman  * @brief Populate the collection "Members" from a GetSubTreePaths search of
2505030b8eSGunnar Mills  *        inventory
2605030b8eSGunnar Mills  *
27ac106bf6SEd Tanous  * @param[i,o] asyncResp  Async response object
2805030b8eSGunnar Mills  * @param[i]   collectionPath  Redfish collection path which is used for the
2905030b8eSGunnar Mills  *             Members Redfish Path
3005030b8eSGunnar Mills  * @param[i]   interfaces  List of interfaces to constrain the GetSubTree search
31dea43dd4SJonathan Doman  * @param[in]  subtree     D-Bus base path to constrain search to.
3205030b8eSGunnar Mills  *
3305030b8eSGunnar Mills  * @return void
3405030b8eSGunnar Mills  */
35dea43dd4SJonathan Doman inline void
36ac106bf6SEd Tanous     getCollectionMembers(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
37ae9031f0SWilly Tu                          const boost::urls::url& collectionPath,
387a1dbc48SGeorge Liu                          std::span<const std::string_view> interfaces,
39dea43dd4SJonathan Doman                          const char* subtree = "/xyz/openbmc_project/inventory")
40116bcc5cSGunnar Mills {
4162598e31SEd Tanous     BMCWEB_LOG_DEBUG("Get collection members for: {}", collectionPath.buffer());
427a1dbc48SGeorge Liu     dbus::utility::getSubTreePaths(
437a1dbc48SGeorge Liu         subtree, 0, interfaces,
44ac106bf6SEd Tanous         [collectionPath, asyncResp{std::move(asyncResp)}](
457a1dbc48SGeorge Liu             const boost::system::error_code& ec,
46b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreePathsResponse& objects) {
4727ea7db1SEd Tanous         if (ec == boost::system::errc::io_error)
4827ea7db1SEd Tanous         {
49ac106bf6SEd Tanous             asyncResp->res.jsonValue["Members"] = nlohmann::json::array();
50ac106bf6SEd Tanous             asyncResp->res.jsonValue["Members@odata.count"] = 0;
5127ea7db1SEd Tanous             return;
5227ea7db1SEd Tanous         }
5327ea7db1SEd Tanous 
54116bcc5cSGunnar Mills         if (ec)
55116bcc5cSGunnar Mills         {
5662598e31SEd Tanous             BMCWEB_LOG_DEBUG("DBUS response error {}", ec.value());
57ac106bf6SEd Tanous             messages::internalError(asyncResp->res);
58116bcc5cSGunnar Mills             return;
59116bcc5cSGunnar Mills         }
60116bcc5cSGunnar Mills 
6192409d0eSEd Tanous         std::vector<std::string> pathNames;
62dea43dd4SJonathan Doman         for (const auto& object : objects)
63116bcc5cSGunnar Mills         {
642dfd18efSEd Tanous             sdbusplus::message::object_path path(object);
652dfd18efSEd Tanous             std::string leaf = path.filename();
662dfd18efSEd Tanous             if (leaf.empty())
67116bcc5cSGunnar Mills             {
682dfd18efSEd Tanous                 continue;
69116bcc5cSGunnar Mills             }
7092409d0eSEd Tanous             pathNames.push_back(leaf);
7192409d0eSEd Tanous         }
72*3544d2a7SEd Tanous         std::ranges::sort(pathNames, AlphanumLess<std::string>());
7392409d0eSEd Tanous 
74ac106bf6SEd Tanous         nlohmann::json& members = asyncResp->res.jsonValue["Members"];
7592409d0eSEd Tanous         members = nlohmann::json::array();
7692409d0eSEd Tanous         for (const std::string& leaf : pathNames)
7792409d0eSEd Tanous         {
78ae9031f0SWilly Tu             boost::urls::url url = collectionPath;
79ae9031f0SWilly Tu             crow::utility::appendUrlPieces(url, leaf);
801476687dSEd Tanous             nlohmann::json::object_t member;
81ae9031f0SWilly Tu             member["@odata.id"] = std::move(url);
82b2ba3072SPatrick Williams             members.emplace_back(std::move(member));
83116bcc5cSGunnar Mills         }
84ac106bf6SEd Tanous         asyncResp->res.jsonValue["Members@odata.count"] = members.size();
857a1dbc48SGeorge Liu         });
86116bcc5cSGunnar Mills }
87116bcc5cSGunnar Mills 
88116bcc5cSGunnar Mills } // namespace collection_util
89116bcc5cSGunnar Mills } // namespace redfish
90