blob: fc5cd640edea7ebf0e6bbe4e1e229dcaa815deca [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
Gunnar Mills116bcc52020-10-14 15:23:42 -05003#pragma once
4
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "async_resp.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +08006#include "dbus_utility.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08007#include "error_messages.hpp"
8#include "http/utility.hpp"
9#include "human_sort.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080010#include "logging.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080011
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include <boost/url/url.hpp>
13#include <nlohmann/json.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080014#include <sdbusplus/message/native_types.hpp>
Gunnar Mills116bcc52020-10-14 15:23:42 -050015
Ed Tanousd7857202025-01-28 15:32:26 -080016#include <algorithm>
17#include <functional>
18#include <memory>
Ed Tanous3544d2a2023-08-06 18:12:20 -070019#include <ranges>
George Liu7a1dbc42022-12-07 16:03:22 +080020#include <span>
Gunnar Mills116bcc52020-10-14 15:23:42 -050021#include <string>
George Liu7a1dbc42022-12-07 16:03:22 +080022#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080023#include <utility>
Gunnar Mills116bcc52020-10-14 15:23:42 -050024#include <vector>
25
26namespace redfish
27{
28namespace collection_util
29{
30
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -050031inline void handleCollectionMembers(
32 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050033 const boost::urls::url& collectionPath,
34 const nlohmann::json::json_pointer& jsonKeyName,
35 const boost::system::error_code& ec,
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -050036 const dbus::utility::MapperGetSubTreePathsResponse& objects)
37{
Ed Tanous1aa375b2024-04-13 11:51:10 -070038 if (jsonKeyName.empty())
39 {
40 messages::internalError(asyncResp->res);
41 BMCWEB_LOG_ERROR("Json Key called empty. Did you mean /Members?");
42 return;
43 }
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050044 nlohmann::json::json_pointer jsonCountKeyName = jsonKeyName;
45 std::string back = jsonCountKeyName.back();
46 jsonCountKeyName.pop_back();
Myung Baec48377d2023-12-19 10:50:32 -050047 jsonCountKeyName /= back + "@odata.count";
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050048
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -050049 if (ec == boost::system::errc::io_error)
50 {
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050051 asyncResp->res.jsonValue[jsonKeyName] = nlohmann::json::array();
52 asyncResp->res.jsonValue[jsonCountKeyName] = 0;
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -050053 return;
54 }
55
56 if (ec)
57 {
58 BMCWEB_LOG_DEBUG("DBUS response error {}", ec.value());
59 messages::internalError(asyncResp->res);
60 return;
61 }
62
63 std::vector<std::string> pathNames;
64 for (const auto& object : objects)
65 {
66 sdbusplus::message::object_path path(object);
67 std::string leaf = path.filename();
68 if (leaf.empty())
69 {
70 continue;
71 }
72 pathNames.push_back(leaf);
73 }
74 std::ranges::sort(pathNames, AlphanumLess<std::string>());
75
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050076 nlohmann::json& members = asyncResp->res.jsonValue[jsonKeyName];
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -050077 members = nlohmann::json::array();
78 for (const std::string& leaf : pathNames)
79 {
80 boost::urls::url url = collectionPath;
81 crow::utility::appendUrlPieces(url, leaf);
82 nlohmann::json::object_t member;
83 member["@odata.id"] = std::move(url);
84 members.emplace_back(std::move(member));
85 }
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050086 asyncResp->res.jsonValue[jsonCountKeyName] = members.size();
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -050087}
88
Gunnar Mills05030b82020-10-14 15:51:31 -050089/**
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050090 * @brief Populate the collection members from a GetSubTreePaths search of
Gunnar Mills05030b82020-10-14 15:51:31 -050091 * inventory
92 *
Ed Tanousac106bf2023-06-07 09:24:59 -070093 * @param[i,o] asyncResp Async response object
Gunnar Mills05030b82020-10-14 15:51:31 -050094 * @param[i] collectionPath Redfish collection path which is used for the
95 * Members Redfish Path
96 * @param[i] interfaces List of interfaces to constrain the GetSubTree search
Jonathan Domandea43dd2020-12-02 15:21:24 -080097 * @param[in] subtree D-Bus base path to constrain search to.
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -050098 * @param[in] jsonKeyName Key name in which the collection members will be
99 * stored.
Gunnar Mills05030b82020-10-14 15:51:31 -0500100 *
101 * @return void
102 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400103inline void getCollectionToKey(
104 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
105 const boost::urls::url& collectionPath,
106 std::span<const std::string_view> interfaces, const std::string& subtree,
107 const nlohmann::json::json_pointer& jsonKeyName)
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -0500108{
109 BMCWEB_LOG_DEBUG("Get collection members for: {}", collectionPath.buffer());
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400110 dbus::utility::getSubTreePaths(
111 subtree, 0, interfaces,
112 std::bind_front(handleCollectionMembers, asyncResp, collectionPath,
113 jsonKeyName));
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -0500114}
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400115inline void getCollectionMembers(
116 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
117 const boost::urls::url& collectionPath,
118 std::span<const std::string_view> interfaces, const std::string& subtree)
Gunnar Mills116bcc52020-10-14 15:23:42 -0500119{
Lakshmi Yadlapati70c4d542023-06-08 04:37:18 -0500120 getCollectionToKey(asyncResp, collectionPath, interfaces, subtree,
121 nlohmann::json::json_pointer("/Members"));
Gunnar Mills116bcc52020-10-14 15:23:42 -0500122}
123
124} // namespace collection_util
125} // namespace redfish