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 123544d2a7SEd 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 2336b5f1edSLakshmi Yadlapati inline void handleCollectionMembers( 2436b5f1edSLakshmi Yadlapati const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 25*70c4d545SLakshmi Yadlapati const boost::urls::url& collectionPath, 26*70c4d545SLakshmi Yadlapati const nlohmann::json::json_pointer& jsonKeyName, 27*70c4d545SLakshmi Yadlapati const boost::system::error_code& ec, 2836b5f1edSLakshmi Yadlapati const dbus::utility::MapperGetSubTreePathsResponse& objects) 29116bcc5cSGunnar Mills { 30*70c4d545SLakshmi Yadlapati nlohmann::json::json_pointer jsonCountKeyName = jsonKeyName; 31*70c4d545SLakshmi Yadlapati std::string back = jsonCountKeyName.back(); 32*70c4d545SLakshmi Yadlapati jsonCountKeyName.pop_back(); 33*70c4d545SLakshmi Yadlapati jsonCountKeyName /= back + "@data.count"; 34*70c4d545SLakshmi Yadlapati 3527ea7db1SEd Tanous if (ec == boost::system::errc::io_error) 3627ea7db1SEd Tanous { 37*70c4d545SLakshmi Yadlapati asyncResp->res.jsonValue[jsonKeyName] = nlohmann::json::array(); 38*70c4d545SLakshmi Yadlapati asyncResp->res.jsonValue[jsonCountKeyName] = 0; 3927ea7db1SEd Tanous return; 4027ea7db1SEd Tanous } 4127ea7db1SEd Tanous 42116bcc5cSGunnar Mills if (ec) 43116bcc5cSGunnar Mills { 4462598e31SEd Tanous BMCWEB_LOG_DEBUG("DBUS response error {}", ec.value()); 45ac106bf6SEd Tanous messages::internalError(asyncResp->res); 46116bcc5cSGunnar Mills return; 47116bcc5cSGunnar Mills } 48116bcc5cSGunnar Mills 4992409d0eSEd Tanous std::vector<std::string> pathNames; 50dea43dd4SJonathan Doman for (const auto& object : objects) 51116bcc5cSGunnar Mills { 522dfd18efSEd Tanous sdbusplus::message::object_path path(object); 532dfd18efSEd Tanous std::string leaf = path.filename(); 542dfd18efSEd Tanous if (leaf.empty()) 55116bcc5cSGunnar Mills { 562dfd18efSEd Tanous continue; 57116bcc5cSGunnar Mills } 5892409d0eSEd Tanous pathNames.push_back(leaf); 5992409d0eSEd Tanous } 603544d2a7SEd Tanous std::ranges::sort(pathNames, AlphanumLess<std::string>()); 6192409d0eSEd Tanous 62*70c4d545SLakshmi Yadlapati nlohmann::json& members = asyncResp->res.jsonValue[jsonKeyName]; 6392409d0eSEd Tanous members = nlohmann::json::array(); 6492409d0eSEd Tanous for (const std::string& leaf : pathNames) 6592409d0eSEd Tanous { 66ae9031f0SWilly Tu boost::urls::url url = collectionPath; 67ae9031f0SWilly Tu crow::utility::appendUrlPieces(url, leaf); 681476687dSEd Tanous nlohmann::json::object_t member; 69ae9031f0SWilly Tu member["@odata.id"] = std::move(url); 70b2ba3072SPatrick Williams members.emplace_back(std::move(member)); 71116bcc5cSGunnar Mills } 72*70c4d545SLakshmi Yadlapati asyncResp->res.jsonValue[jsonCountKeyName] = members.size(); 7336b5f1edSLakshmi Yadlapati } 7436b5f1edSLakshmi Yadlapati 7536b5f1edSLakshmi Yadlapati /** 76*70c4d545SLakshmi Yadlapati * @brief Populate the collection members from a GetSubTreePaths search of 7736b5f1edSLakshmi Yadlapati * inventory 7836b5f1edSLakshmi Yadlapati * 7936b5f1edSLakshmi Yadlapati * @param[i,o] asyncResp Async response object 8036b5f1edSLakshmi Yadlapati * @param[i] collectionPath Redfish collection path which is used for the 8136b5f1edSLakshmi Yadlapati * Members Redfish Path 8236b5f1edSLakshmi Yadlapati * @param[i] interfaces List of interfaces to constrain the GetSubTree search 8336b5f1edSLakshmi Yadlapati * @param[in] subtree D-Bus base path to constrain search to. 84*70c4d545SLakshmi Yadlapati * @param[in] jsonKeyName Key name in which the collection members will be 85*70c4d545SLakshmi Yadlapati * stored. 8636b5f1edSLakshmi Yadlapati * 8736b5f1edSLakshmi Yadlapati * @return void 8836b5f1edSLakshmi Yadlapati */ 8936b5f1edSLakshmi Yadlapati inline void 90*70c4d545SLakshmi Yadlapati getCollectionToKey(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 91*70c4d545SLakshmi Yadlapati const boost::urls::url& collectionPath, 92*70c4d545SLakshmi Yadlapati std::span<const std::string_view> interfaces, 93*70c4d545SLakshmi Yadlapati const std::string& subtree, 94*70c4d545SLakshmi Yadlapati const nlohmann::json::json_pointer& jsonKeyName) 95*70c4d545SLakshmi Yadlapati { 96*70c4d545SLakshmi Yadlapati BMCWEB_LOG_DEBUG("Get collection members for: {}", collectionPath.buffer()); 97*70c4d545SLakshmi Yadlapati dbus::utility::getSubTreePaths(subtree, 0, interfaces, 98*70c4d545SLakshmi Yadlapati std::bind_front(handleCollectionMembers, 99*70c4d545SLakshmi Yadlapati asyncResp, collectionPath, 100*70c4d545SLakshmi Yadlapati jsonKeyName)); 101*70c4d545SLakshmi Yadlapati } 102*70c4d545SLakshmi Yadlapati inline void 10336b5f1edSLakshmi Yadlapati getCollectionMembers(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 10436b5f1edSLakshmi Yadlapati const boost::urls::url& collectionPath, 10536b5f1edSLakshmi Yadlapati std::span<const std::string_view> interfaces, 10636b5f1edSLakshmi Yadlapati const std::string& subtree) 10736b5f1edSLakshmi Yadlapati { 108*70c4d545SLakshmi Yadlapati getCollectionToKey(asyncResp, collectionPath, interfaces, subtree, 109*70c4d545SLakshmi Yadlapati nlohmann::json::json_pointer("/Members")); 110116bcc5cSGunnar Mills } 111116bcc5cSGunnar Mills 112116bcc5cSGunnar Mills } // namespace collection_util 113116bcc5cSGunnar Mills } // namespace redfish 114