xref: /openbmc/bmcweb/features/redfish/lib/fabric_adapters.hpp (revision a8e884fc4e2fae0c79454ee865c9b9e0534f6763)
13179105bSSunny Srivastava #pragma once
23179105bSSunny Srivastava 
33179105bSSunny Srivastava #include "app.hpp"
43179105bSSunny Srivastava #include "dbus_utility.hpp"
5*a8e884fcSEd Tanous #include "query.hpp"
6*a8e884fcSEd Tanous #include "registries/privilege_registry.hpp"
73179105bSSunny Srivastava #include "utils/collection.hpp"
83179105bSSunny Srivastava #include "utils/json_utils.hpp"
93179105bSSunny Srivastava 
103179105bSSunny Srivastava #include <boost/system/error_code.hpp>
113179105bSSunny Srivastava 
123179105bSSunny Srivastava #include <array>
133179105bSSunny Srivastava #include <functional>
143179105bSSunny Srivastava #include <memory>
153179105bSSunny Srivastava #include <string>
163179105bSSunny Srivastava #include <string_view>
173179105bSSunny Srivastava 
183179105bSSunny Srivastava namespace redfish
193179105bSSunny Srivastava {
203179105bSSunny Srivastava 
213179105bSSunny Srivastava inline void handleAdapterError(const boost::system::error_code& ec,
223179105bSSunny Srivastava                                crow::Response& res,
233179105bSSunny Srivastava                                const std::string& adapterId)
243179105bSSunny Srivastava {
253179105bSSunny Srivastava 
263179105bSSunny Srivastava     if (ec.value() == boost::system::errc::io_error)
273179105bSSunny Srivastava     {
283179105bSSunny Srivastava         messages::resourceNotFound(res, "#FabricAdapter.v1_0_0.FabricAdapter",
293179105bSSunny Srivastava                                    adapterId);
303179105bSSunny Srivastava         return;
313179105bSSunny Srivastava     }
323179105bSSunny Srivastava 
333179105bSSunny Srivastava     BMCWEB_LOG_ERROR << "DBus method call failed with error " << ec.value();
343179105bSSunny Srivastava     messages::internalError(res);
353179105bSSunny Srivastava }
363179105bSSunny Srivastava 
373179105bSSunny Srivastava inline void doAdapterGet(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
383179105bSSunny Srivastava                          const std::string& systemName,
393179105bSSunny Srivastava                          const std::string& adapterId)
403179105bSSunny Srivastava {
413179105bSSunny Srivastava     aResp->res.addHeader(
423179105bSSunny Srivastava         boost::beast::http::field::link,
433179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
443179105bSSunny Srivastava     aResp->res.jsonValue["@odata.type"] = "#FabricAdapter.v1_0_0.FabricAdapter";
453179105bSSunny Srivastava     aResp->res.jsonValue["Name"] = "Fabric Adapter";
463179105bSSunny Srivastava     aResp->res.jsonValue["Id"] = adapterId;
473179105bSSunny Srivastava     aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
483179105bSSunny Srivastava         "redfish", "v1", "Systems", systemName, "FabricAdapters", adapterId);
493179105bSSunny Srivastava }
503179105bSSunny Srivastava 
513179105bSSunny Srivastava inline bool checkFabricAdapterId(const std::string& adapterPath,
523179105bSSunny Srivastava                                  const std::string& adapterId)
533179105bSSunny Srivastava {
543179105bSSunny Srivastava     std::string fabricAdapterName =
553179105bSSunny Srivastava         sdbusplus::message::object_path(adapterPath).filename();
563179105bSSunny Srivastava 
573179105bSSunny Srivastava     return !(fabricAdapterName.empty() || fabricAdapterName != adapterId);
583179105bSSunny Srivastava }
593179105bSSunny Srivastava 
603179105bSSunny Srivastava inline void getValidFabricAdapterPath(
613179105bSSunny Srivastava     const std::string& adapterId, const std::string& systemName,
623179105bSSunny Srivastava     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
633179105bSSunny Srivastava     std::function<void(const std::string& fabricAdapterPath,
643179105bSSunny Srivastava                        const std::string& serviceName)>&& callback)
653179105bSSunny Srivastava {
663179105bSSunny Srivastava     if (systemName != "system")
673179105bSSunny Srivastava     {
683179105bSSunny Srivastava         messages::resourceNotFound(aResp->res, "ComputerSystem", systemName);
693179105bSSunny Srivastava         return;
703179105bSSunny Srivastava     }
713179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
723179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
733179105bSSunny Srivastava 
743179105bSSunny Srivastava     dbus::utility::getSubTree(
753179105bSSunny Srivastava         "/xyz/openbmc_project/inventory", 0, interfaces,
763179105bSSunny Srivastava         [adapterId, aResp,
773179105bSSunny Srivastava          callback](const boost::system::error_code& ec,
783179105bSSunny Srivastava                    const dbus::utility::MapperGetSubTreeResponse& subtree) {
793179105bSSunny Srivastava         if (ec)
803179105bSSunny Srivastava         {
813179105bSSunny Srivastava             handleAdapterError(ec, aResp->res, adapterId);
823179105bSSunny Srivastava             return;
833179105bSSunny Srivastava         }
843179105bSSunny Srivastava         for (const auto& [adapterPath, serviceMap] : subtree)
853179105bSSunny Srivastava         {
863179105bSSunny Srivastava             if (checkFabricAdapterId(adapterPath, adapterId))
873179105bSSunny Srivastava             {
883179105bSSunny Srivastava                 callback(adapterPath, serviceMap.begin()->first);
893179105bSSunny Srivastava                 return;
903179105bSSunny Srivastava             }
913179105bSSunny Srivastava         }
923179105bSSunny Srivastava         BMCWEB_LOG_WARNING << "Adapter not found";
933179105bSSunny Srivastava         messages::resourceNotFound(aResp->res, "FabricAdapter", adapterId);
943179105bSSunny Srivastava         });
953179105bSSunny Srivastava }
963179105bSSunny Srivastava 
973179105bSSunny Srivastava inline void
983179105bSSunny Srivastava     handleFabricAdapterGet(App& app, const crow::Request& req,
993179105bSSunny Srivastava                            const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1003179105bSSunny Srivastava                            const std::string& systemName,
1013179105bSSunny Srivastava                            const std::string& adapterId)
1023179105bSSunny Srivastava {
1033179105bSSunny Srivastava     if (!redfish::setUpRedfishRoute(app, req, aResp))
1043179105bSSunny Srivastava     {
1053179105bSSunny Srivastava         return;
1063179105bSSunny Srivastava     }
1073179105bSSunny Srivastava 
1083179105bSSunny Srivastava     getValidFabricAdapterPath(
1093179105bSSunny Srivastava         adapterId, systemName, aResp,
1103179105bSSunny Srivastava         [aResp, systemName, adapterId](const std::string&, const std::string&) {
1113179105bSSunny Srivastava         doAdapterGet(aResp, systemName, adapterId);
1123179105bSSunny Srivastava         });
1133179105bSSunny Srivastava }
1143179105bSSunny Srivastava 
1153179105bSSunny Srivastava inline void handleFabricAdapterCollectionGet(
1163179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
1173179105bSSunny Srivastava     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1183179105bSSunny Srivastava     const std::string& systemName)
1193179105bSSunny Srivastava {
1203179105bSSunny Srivastava     if (!redfish::setUpRedfishRoute(app, req, aResp))
1213179105bSSunny Srivastava     {
1223179105bSSunny Srivastava         return;
1233179105bSSunny Srivastava     }
1243179105bSSunny Srivastava     if (systemName != "system")
1253179105bSSunny Srivastava     {
1263179105bSSunny Srivastava         messages::resourceNotFound(aResp->res, "ComputerSystem", systemName);
1273179105bSSunny Srivastava         return;
1283179105bSSunny Srivastava     }
1293179105bSSunny Srivastava 
1303179105bSSunny Srivastava     aResp->res.addHeader(
1313179105bSSunny Srivastava         boost::beast::http::field::link,
1323179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
1333179105bSSunny Srivastava     aResp->res.jsonValue["@odata.type"] =
1343179105bSSunny Srivastava         "#FabricAdapterCollection.FabricAdapterCollection";
1353179105bSSunny Srivastava     aResp->res.jsonValue["Name"] = "Fabric Adapter Collection";
1363179105bSSunny Srivastava     aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces(
1373179105bSSunny Srivastava         "redfish", "v1", "Systems", systemName, "FabricAdapters");
1383179105bSSunny Srivastava 
1393179105bSSunny Srivastava     constexpr std::array<std::string_view, 1> interfaces{
1403179105bSSunny Srivastava         "xyz.openbmc_project.Inventory.Item.FabricAdapter"};
1413179105bSSunny Srivastava     collection_util::getCollectionMembers(
1423179105bSSunny Srivastava         aResp, boost::urls::url("/redfish/v1/Systems/system/FabricAdapters"),
1433179105bSSunny Srivastava         interfaces);
1443179105bSSunny Srivastava }
1453179105bSSunny Srivastava 
1463179105bSSunny Srivastava inline void handleFabricAdapterCollectionHead(
1473179105bSSunny Srivastava     crow::App& app, const crow::Request& req,
1483179105bSSunny Srivastava     const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1493179105bSSunny Srivastava     const std::string& systemName)
1503179105bSSunny Srivastava {
1513179105bSSunny Srivastava     if (!redfish::setUpRedfishRoute(app, req, aResp))
1523179105bSSunny Srivastava     {
1533179105bSSunny Srivastava         return;
1543179105bSSunny Srivastava     }
1553179105bSSunny Srivastava     if (systemName != "system")
1563179105bSSunny Srivastava     {
1573179105bSSunny Srivastava         messages::resourceNotFound(aResp->res, "ComputerSystem", systemName);
1583179105bSSunny Srivastava         return;
1593179105bSSunny Srivastava     }
1603179105bSSunny Srivastava     aResp->res.addHeader(
1613179105bSSunny Srivastava         boost::beast::http::field::link,
1623179105bSSunny Srivastava         "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby");
1633179105bSSunny Srivastava }
1643179105bSSunny Srivastava 
1653179105bSSunny Srivastava inline void
1663179105bSSunny Srivastava     handleFabricAdapterHead(crow::App& app, const crow::Request& req,
1673179105bSSunny Srivastava                             const std::shared_ptr<bmcweb::AsyncResp>& aResp,
1683179105bSSunny Srivastava                             const std::string& systemName,
1693179105bSSunny Srivastava                             const std::string& adapterId)
1703179105bSSunny Srivastava {
1713179105bSSunny Srivastava     if (!redfish::setUpRedfishRoute(app, req, aResp))
1723179105bSSunny Srivastava     {
1733179105bSSunny Srivastava         return;
1743179105bSSunny Srivastava     }
1753179105bSSunny Srivastava 
1763179105bSSunny Srivastava     getValidFabricAdapterPath(
1773179105bSSunny Srivastava         adapterId, systemName, aResp,
1783179105bSSunny Srivastava         [aResp, systemName, adapterId](const std::string&, const std::string&) {
1793179105bSSunny Srivastava         aResp->res.addHeader(
1803179105bSSunny Srivastava             boost::beast::http::field::link,
1813179105bSSunny Srivastava             "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby");
1823179105bSSunny Srivastava         });
1833179105bSSunny Srivastava }
1843179105bSSunny Srivastava 
1853179105bSSunny Srivastava inline void requestRoutesFabricAdapterCollection(App& app)
1863179105bSSunny Srivastava {
1873179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
1883179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapterCollection)
1893179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
1903179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionGet, std::ref(app)));
1913179105bSSunny Srivastava 
1923179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/")
1933179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapterCollection)
1943179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
1953179105bSSunny Srivastava             std::bind_front(handleFabricAdapterCollectionHead, std::ref(app)));
1963179105bSSunny Srivastava }
1973179105bSSunny Srivastava 
1983179105bSSunny Srivastava inline void requestRoutesFabricAdapters(App& app)
1993179105bSSunny Srivastava {
2003179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
2013179105bSSunny Srivastava         .privileges(redfish::privileges::getFabricAdapter)
2023179105bSSunny Srivastava         .methods(boost::beast::http::verb::get)(
2033179105bSSunny Srivastava             std::bind_front(handleFabricAdapterGet, std::ref(app)));
2043179105bSSunny Srivastava 
2053179105bSSunny Srivastava     BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/")
2063179105bSSunny Srivastava         .privileges(redfish::privileges::headFabricAdapter)
2073179105bSSunny Srivastava         .methods(boost::beast::http::verb::head)(
2083179105bSSunny Srivastava             std::bind_front(handleFabricAdapterHead, std::ref(app)));
2093179105bSSunny Srivastava }
2103179105bSSunny Srivastava } // namespace redfish
211