blob: a1e273aae9f932ea96d1e26524d65b02925e85df [file] [log] [blame]
Sunny Srivastava31791052021-03-12 10:39:16 -06001#pragma once
2
3#include "app.hpp"
4#include "dbus_utility.hpp"
Ed Tanousa8e884f2023-01-13 17:40:03 -08005#include "query.hpp"
6#include "registries/privilege_registry.hpp"
Sunny Srivastava31791052021-03-12 10:39:16 -06007#include "utils/collection.hpp"
8#include "utils/json_utils.hpp"
9
10#include <boost/system/error_code.hpp>
11
12#include <array>
13#include <functional>
14#include <memory>
15#include <string>
16#include <string_view>
17
18namespace redfish
19{
20
21inline void handleAdapterError(const boost::system::error_code& ec,
22 crow::Response& res,
23 const std::string& adapterId)
24{
25
26 if (ec.value() == boost::system::errc::io_error)
27 {
28 messages::resourceNotFound(res, "#FabricAdapter.v1_0_0.FabricAdapter",
29 adapterId);
30 return;
31 }
32
33 BMCWEB_LOG_ERROR << "DBus method call failed with error " << ec.value();
34 messages::internalError(res);
35}
36
37inline void doAdapterGet(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
38 const std::string& systemName,
39 const std::string& adapterId)
40{
41 aResp->res.addHeader(
42 boost::beast::http::field::link,
43 "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
44 aResp->res.jsonValue["@odata.type"] = "#FabricAdapter.v1_0_0.FabricAdapter";
45 aResp->res.jsonValue["Name"] = "Fabric Adapter";
46 aResp->res.jsonValue["Id"] = adapterId;
47 aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
48 "redfish", "v1", "Systems", systemName, "FabricAdapters", adapterId);
49}
50
51inline bool checkFabricAdapterId(const std::string& adapterPath,
52 const std::string& adapterId)
53{
54 std::string fabricAdapterName =
55 sdbusplus::message::object_path(adapterPath).filename();
56
57 return !(fabricAdapterName.empty() || fabricAdapterName != adapterId);
58}
59
60inline void getValidFabricAdapterPath(
61 const std::string& adapterId, const std::string& systemName,
62 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
63 std::function<void(const std::string& fabricAdapterPath,
64 const std::string& serviceName)>&& callback)
65{
66 if (systemName != "system")
67 {
68 messages::resourceNotFound(aResp->res, "ComputerSystem", systemName);
69 return;
70 }
71 constexpr std::array<std::string_view, 1> interfaces{
72 "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
73
74 dbus::utility::getSubTree(
75 "/xyz/openbmc_project/inventory", 0, interfaces,
76 [adapterId, aResp,
77 callback](const boost::system::error_code& ec,
78 const dbus::utility::MapperGetSubTreeResponse& subtree) {
79 if (ec)
80 {
81 handleAdapterError(ec, aResp->res, adapterId);
82 return;
83 }
84 for (const auto& [adapterPath, serviceMap] : subtree)
85 {
86 if (checkFabricAdapterId(adapterPath, adapterId))
87 {
88 callback(adapterPath, serviceMap.begin()->first);
89 return;
90 }
91 }
92 BMCWEB_LOG_WARNING << "Adapter not found";
93 messages::resourceNotFound(aResp->res, "FabricAdapter", adapterId);
94 });
95}
96
97inline void
98 handleFabricAdapterGet(App& app, const crow::Request& req,
99 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
100 const std::string& systemName,
101 const std::string& adapterId)
102{
103 if (!redfish::setUpRedfishRoute(app, req, aResp))
104 {
105 return;
106 }
107
108 getValidFabricAdapterPath(
109 adapterId, systemName, aResp,
110 [aResp, systemName, adapterId](const std::string&, const std::string&) {
111 doAdapterGet(aResp, systemName, adapterId);
112 });
113}
114
115inline void handleFabricAdapterCollectionGet(
116 crow::App& app, const crow::Request& req,
117 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
118 const std::string& systemName)
119{
120 if (!redfish::setUpRedfishRoute(app, req, aResp))
121 {
122 return;
123 }
124 if (systemName != "system")
125 {
126 messages::resourceNotFound(aResp->res, "ComputerSystem", systemName);
127 return;
128 }
129
130 aResp->res.addHeader(
131 boost::beast::http::field::link,
132 "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
133 aResp->res.jsonValue["@odata.type"] =
134 "#FabricAdapterCollection.FabricAdapterCollection";
135 aResp->res.jsonValue["Name"] = "Fabric Adapter Collection";
136 aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
137 "redfish", "v1", "Systems", systemName, "FabricAdapters");
138
139 constexpr std::array<std::string_view, 1> interfaces{
140 "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
141 collection_util::getCollectionMembers(
142 aResp, boost::urls::url("/redfish/v1/Systems/system/FabricAdapters"),
143 interfaces);
144}
145
146inline void handleFabricAdapterCollectionHead(
147 crow::App& app, const crow::Request& req,
148 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
149 const std::string& systemName)
150{
151 if (!redfish::setUpRedfishRoute(app, req, aResp))
152 {
153 return;
154 }
155 if (systemName != "system")
156 {
157 messages::resourceNotFound(aResp->res, "ComputerSystem", systemName);
158 return;
159 }
160 aResp->res.addHeader(
161 boost::beast::http::field::link,
162 "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
163}
164
165inline void
166 handleFabricAdapterHead(crow::App& app, const crow::Request& req,
167 const std::shared_ptr<bmcweb::AsyncResp>& aResp,
168 const std::string& systemName,
169 const std::string& adapterId)
170{
171 if (!redfish::setUpRedfishRoute(app, req, aResp))
172 {
173 return;
174 }
175
176 getValidFabricAdapterPath(
177 adapterId, systemName, aResp,
178 [aResp, systemName, adapterId](const std::string&, const std::string&) {
179 aResp->res.addHeader(
180 boost::beast::http::field::link,
181 "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
182 });
183}
184
185inline void requestRoutesFabricAdapterCollection(App& app)
186{
187 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
188 .privileges(redfish::privileges::getFabricAdapterCollection)
189 .methods(boost::beast::http::verb::get)(
190 std::bind_front(handleFabricAdapterCollectionGet, std::ref(app)));
191
192 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
193 .privileges(redfish::privileges::headFabricAdapterCollection)
194 .methods(boost::beast::http::verb::head)(
195 std::bind_front(handleFabricAdapterCollectionHead, std::ref(app)));
196}
197
198inline void requestRoutesFabricAdapters(App& app)
199{
200 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
201 .privileges(redfish::privileges::getFabricAdapter)
202 .methods(boost::beast::http::verb::get)(
203 std::bind_front(handleFabricAdapterGet, std::ref(app)));
204
205 BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
206 .privileges(redfish::privileges::headFabricAdapter)
207 .methods(boost::beast::http::verb::head)(
208 std::bind_front(handleFabricAdapterHead, std::ref(app)));
209}
210} // namespace redfish