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