xref: /openbmc/bmcweb/features/redfish/include/utils/collection.hpp (revision 7a1dbc4803bf78bfc0c574e6676b3c5def4cdae3)
1116bcc5cSGunnar Mills #pragma once
2116bcc5cSGunnar Mills 
3*7a1dbc48SGeorge Liu #include "dbus_utility.hpp"
4*7a1dbc48SGeorge Liu 
592409d0eSEd Tanous #include <human_sort.hpp>
6116bcc5cSGunnar Mills 
7*7a1dbc48SGeorge Liu #include <span>
8116bcc5cSGunnar Mills #include <string>
9*7a1dbc48SGeorge Liu #include <string_view>
10116bcc5cSGunnar Mills #include <vector>
11116bcc5cSGunnar Mills 
12116bcc5cSGunnar Mills namespace redfish
13116bcc5cSGunnar Mills {
14116bcc5cSGunnar Mills namespace collection_util
15116bcc5cSGunnar Mills {
16116bcc5cSGunnar Mills 
1705030b8eSGunnar Mills /**
18dea43dd4SJonathan Doman  * @brief Populate the collection "Members" from a GetSubTreePaths search of
1905030b8eSGunnar Mills  *        inventory
2005030b8eSGunnar Mills  *
2105030b8eSGunnar Mills  * @param[i,o] aResp  Async response object
2205030b8eSGunnar Mills  * @param[i]   collectionPath  Redfish collection path which is used for the
2305030b8eSGunnar Mills  *             Members Redfish Path
2405030b8eSGunnar Mills  * @param[i]   interfaces  List of interfaces to constrain the GetSubTree search
25dea43dd4SJonathan Doman  * @param[in]  subtree     D-Bus base path to constrain search to.
2605030b8eSGunnar Mills  *
2705030b8eSGunnar Mills  * @return void
2805030b8eSGunnar Mills  */
29dea43dd4SJonathan Doman inline void
308d1b46d7Szhanghch05     getCollectionMembers(std::shared_ptr<bmcweb::AsyncResp> aResp,
31ae9031f0SWilly Tu                          const boost::urls::url& collectionPath,
32*7a1dbc48SGeorge Liu                          std::span<const std::string_view> interfaces,
33dea43dd4SJonathan Doman                          const char* subtree = "/xyz/openbmc_project/inventory")
34116bcc5cSGunnar Mills {
35ae9031f0SWilly Tu     BMCWEB_LOG_DEBUG << "Get collection members for: "
36079360aeSEd Tanous                      << collectionPath.buffer();
37*7a1dbc48SGeorge Liu     dbus::utility::getSubTreePaths(
38*7a1dbc48SGeorge Liu         subtree, 0, interfaces,
39b9d36b47SEd Tanous         [collectionPath, aResp{std::move(aResp)}](
40*7a1dbc48SGeorge Liu             const boost::system::error_code& ec,
41b9d36b47SEd Tanous             const dbus::utility::MapperGetSubTreePathsResponse& objects) {
4227ea7db1SEd Tanous         if (ec == boost::system::errc::io_error)
4327ea7db1SEd Tanous         {
4427ea7db1SEd Tanous             aResp->res.jsonValue["Members"] = nlohmann::json::array();
4527ea7db1SEd Tanous             aResp->res.jsonValue["Members@odata.count"] = 0;
4627ea7db1SEd Tanous             return;
4727ea7db1SEd Tanous         }
4827ea7db1SEd Tanous 
49116bcc5cSGunnar Mills         if (ec)
50116bcc5cSGunnar Mills         {
5127ea7db1SEd Tanous             BMCWEB_LOG_DEBUG << "DBUS response error " << ec.value();
52116bcc5cSGunnar Mills             messages::internalError(aResp->res);
53116bcc5cSGunnar Mills             return;
54116bcc5cSGunnar Mills         }
55116bcc5cSGunnar Mills 
5692409d0eSEd Tanous         std::vector<std::string> pathNames;
57dea43dd4SJonathan Doman         for (const auto& object : objects)
58116bcc5cSGunnar Mills         {
592dfd18efSEd Tanous             sdbusplus::message::object_path path(object);
602dfd18efSEd Tanous             std::string leaf = path.filename();
612dfd18efSEd Tanous             if (leaf.empty())
62116bcc5cSGunnar Mills             {
632dfd18efSEd Tanous                 continue;
64116bcc5cSGunnar Mills             }
6592409d0eSEd Tanous             pathNames.push_back(leaf);
6692409d0eSEd Tanous         }
6792409d0eSEd Tanous         std::sort(pathNames.begin(), pathNames.end(),
6892409d0eSEd Tanous                   AlphanumLess<std::string>());
6992409d0eSEd Tanous 
7092409d0eSEd Tanous         nlohmann::json& members = aResp->res.jsonValue["Members"];
7192409d0eSEd Tanous         members = nlohmann::json::array();
7292409d0eSEd Tanous         for (const std::string& leaf : pathNames)
7392409d0eSEd Tanous         {
74ae9031f0SWilly Tu             boost::urls::url url = collectionPath;
75ae9031f0SWilly Tu             crow::utility::appendUrlPieces(url, leaf);
761476687dSEd Tanous             nlohmann::json::object_t member;
77ae9031f0SWilly Tu             member["@odata.id"] = std::move(url);
781476687dSEd Tanous             members.push_back(std::move(member));
79116bcc5cSGunnar Mills         }
80116bcc5cSGunnar Mills         aResp->res.jsonValue["Members@odata.count"] = members.size();
81*7a1dbc48SGeorge Liu         });
82116bcc5cSGunnar Mills }
83116bcc5cSGunnar Mills 
84116bcc5cSGunnar Mills } // namespace collection_util
85116bcc5cSGunnar Mills } // namespace redfish
86