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