diff options
-rw-r--r-- | Redfish.md | 6 | ||||
-rw-r--r-- | redfish-core/include/redfish.hpp | 1 | ||||
-rw-r--r-- | redfish-core/lib/power_supply.hpp | 170 |
3 files changed, 171 insertions, 6 deletions
diff --git a/Redfish.md b/Redfish.md index 9fec4ed4b6..1cdce980aa 100644 --- a/Redfish.md +++ b/Redfish.md @@ -371,6 +371,12 @@ Fields common to all schemas ##### PowerSupplies - Description +- Members +- Members@odata.count + +#### /redfish/v1/Chassis/{ChassisId}/PowerSubsystem/PowerSupplies/{PowerSupplyId} + +##### PowerSupply ### /redfish/v1/EventService/ diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp index ce09531c42..2bf0f4578e 100644 --- a/redfish-core/include/redfish.hpp +++ b/redfish-core/include/redfish.hpp @@ -91,6 +91,7 @@ class RedfishService #ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM requestRoutesEnvironmentMetrics(app); requestRoutesPowerSubsystem(app); + requestRoutesPowerSupply(app); requestRoutesPowerSupplyCollection(app); requestRoutesThermalSubsystem(app); #endif diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp index 430a29a632..ebc61c50ab 100644 --- a/redfish-core/lib/power_supply.hpp +++ b/redfish-core/lib/power_supply.hpp @@ -15,13 +15,26 @@ namespace redfish { -inline void updatePowerSupplyList( - const std::shared_ptr<bmcweb::AsyncResp>& /* asyncResp */, - const std::string& /* chassisId */, - const std::string& /* powerSupplyPath */) +inline void + updatePowerSupplyList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId, + const std::string& powerSupplyPath) { - // TODO In order for the validator to pass, the Members property will be - // implemented on the next commit + std::string powerSupplyName = + sdbusplus::message::object_path(powerSupplyPath).filename(); + if (powerSupplyName.empty()) + { + return; + } + + nlohmann::json item = nlohmann::json::object(); + item["@odata.id"] = boost::urls::format( + "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId, + powerSupplyName); + + nlohmann::json& powerSupplyList = asyncResp->res.jsonValue["Members"]; + powerSupplyList.emplace_back(std::move(item)); + asyncResp->res.jsonValue["Members@odata.count"] = powerSupplyList.size(); } inline void @@ -123,4 +136,149 @@ inline void requestRoutesPowerSupplyCollection(App& app) std::bind_front(handlePowerSupplyCollectionGet, std::ref(app))); } +inline bool checkPowerSupplyId(const std::string& powerSupplyPath, + const std::string& powerSupplyId) +{ + std::string powerSupplyName = + sdbusplus::message::object_path(powerSupplyPath).filename(); + + return !(powerSupplyName.empty() || powerSupplyName != powerSupplyId); +} + +inline void + getValidPowerSupplyPath(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& validChassisPath, + const std::string& powerSupplyId, + std::function<void()>&& callback) +{ + std::string powerPath = validChassisPath + "/powered_by"; + dbus::utility::getAssociationEndPoints( + powerPath, [asyncResp, powerSupplyId, callback{std::move(callback)}]( + const boost::system::error_code& ec, + const dbus::utility::MapperEndPoints& endpoints) { + if (ec) + { + if (ec.value() != EBADR) + { + BMCWEB_LOG_ERROR + << "DBUS response error for getAssociationEndPoints" + << ec.value(); + messages::internalError(asyncResp->res); + return; + } + messages::resourceNotFound(asyncResp->res, "PowerSupplies", + powerSupplyId); + return; + } + + for (const auto& endpoint : endpoints) + { + if (checkPowerSupplyId(endpoint, powerSupplyId)) + { + callback(); + return; + } + } + + if (!endpoints.empty()) + { + BMCWEB_LOG_WARNING << "Power supply not found: " + << powerSupplyId; + messages::resourceNotFound(asyncResp->res, "PowerSupplies", + powerSupplyId); + return; + } + }); +} + +inline void + doPowerSupplyGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId, + const std::string& powerSupplyId, + const std::optional<std::string>& validChassisPath) +{ + if (!validChassisPath) + { + messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); + return; + } + + // Get the correct Path and Service that match the input parameters + getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId, + [asyncResp, chassisId, powerSupplyId]() { + asyncResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby"); + asyncResp->res.jsonValue["@odata.type"] = + "#PowerSupply.v1_5_0.PowerSupply"; + asyncResp->res.jsonValue["Name"] = "Power Supply"; + asyncResp->res.jsonValue["Id"] = powerSupplyId; + asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( + "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId, + powerSupplyId); + }); +} + +inline void + handlePowerSupplyHead(App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId, + const std::string& powerSupplyId) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + redfish::chassis_utils::getValidChassisPath( + asyncResp, chassisId, + [asyncResp, chassisId, + powerSupplyId](const std::optional<std::string>& validChassisPath) { + if (!validChassisPath) + { + messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); + return; + } + + // Get the correct Path and Service that match the input parameters + getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId, + [asyncResp]() { + asyncResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby"); + }); + }); +} + +inline void + handlePowerSupplyGet(App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId, + const std::string& powerSupplyId) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + redfish::chassis_utils::getValidChassisPath( + asyncResp, chassisId, + std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId)); +} + +inline void requestRoutesPowerSupply(App& app) +{ + BMCWEB_ROUTE( + app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/") + .privileges(redfish::privileges::headPowerSupply) + .methods(boost::beast::http::verb::head)( + std::bind_front(handlePowerSupplyHead, std::ref(app))); + + BMCWEB_ROUTE( + app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/") + .privileges(redfish::privileges::getPowerSupply) + .methods(boost::beast::http::verb::get)( + std::bind_front(handlePowerSupplyGet, std::ref(app))); +} + } // namespace redfish |