diff options
author | George Liu <liuxiwei@inspur.com> | 2022-09-29 12:21:41 +0300 |
---|---|---|
committer | Gunnar Mills <gmills@us.ibm.com> | 2023-07-13 06:01:21 +0300 |
commit | 9516f41f9295170ad5d59ded36584d22776417d5 (patch) | |
tree | 6e7289ba637b4c9e4be8bd13d436aea0eb63faa1 /redfish-core/lib/fan.hpp | |
parent | 2c6ffdb08b2207ff7c31041f77cc3755508d45c4 (diff) | |
download | bmcweb-9516f41f9295170ad5d59ded36584d22776417d5.tar.xz |
Implements FanCollection schema
The FanCollection schema is a resource in Redifsh version 2022.2 [1]
that represents the management properties for the monitoring and
management of cooling fans implemented by Redfish [2].
This commit retrieves the fan collection by obtaining the endpoints of
the `cooled_by` association. The `cooled_by` association represents the
relationship between a chassis and the fans responsible for providing
cooling to the chassis.
ref:
[1] https://www.dmtf.org/sites/default/files/standards/documents/DSP0268_2022.2.pdf
[2] http://redfish.dmtf.org/schemas/v1/Fan.v1_3_0.json
Redfish validator is currently failing. In order for the validator to
pass, it is necessary to merge this commit with
https://gerrit.openbmc.org/c/openbmc/bmcweb/+/57559
Tested:
1. doGet method to get FanCollection
```
curl -k -H "X-Auth-Token: $token" -X GET
https://${bmc}/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans
{
"@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans",
"@odata.type": "#FanCollection.FanCollection",
"Description": "The collection of Fan resource instances chassis",
"Members": [
{
"@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan5"
},
{
"@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan4"
},
{
"@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan3"
},
{
"@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan2"
},
{
"@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan1"
},
{
"@odata.id": "/redfish/v1/Chassis/chassis/ThermalSubsystem/Fans/fan0"
}
],
"Members@odata.count": 6,
"Name": "Fan Collection"
}
2. Input the wrong chassisId with the doGet method
curl -k https://${bmc}/redfish/v1/Chassis/chassis11/ThermalSubsystem/Fans
{
"error": {
"@Message.ExtendedInfo": [
{
"@odata.type": "#Message.v1_1_1.Message",
"Message": "The requested resource of type Chassis
named 'chassis11' was not found.",
"MessageArgs": [
"Chassis",
"chassis11"
],
"MessageId": "Base.1.13.0.ResourceNotFound",
"MessageSeverity": "Critical",
"Resolution": "Provide a valid resource identifier and
resubmit the request."
}
],
"code": "Base.1.13.0.ResourceNotFound",
"message": "The requested resource of type Chassis named
'chassis11' was not found."
}
}
```
Signed-off-by: George Liu <liuxiwei@inspur.com>
Change-Id: If5e9ff5655f444694c7ca1aea95d45e2c9222625
Signed-off-by: Lakshmi Yadlapati <lakshmiy@us.ibm.com>
Diffstat (limited to 'redfish-core/lib/fan.hpp')
-rw-r--r-- | redfish-core/lib/fan.hpp | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/redfish-core/lib/fan.hpp b/redfish-core/lib/fan.hpp new file mode 100644 index 0000000000..3a9572ffcd --- /dev/null +++ b/redfish-core/lib/fan.hpp @@ -0,0 +1,159 @@ +#pragma once + +#include "app.hpp" +#include "dbus_utility.hpp" +#include "error_messages.hpp" +#include "query.hpp" +#include "registries/privilege_registry.hpp" +#include "utils/chassis_utils.hpp" + +#include <boost/url/format.hpp> +#include <sdbusplus/message/types.hpp> + +#include <functional> +#include <memory> +#include <optional> +#include <string> +#include <string_view> + +namespace redfish +{ +constexpr std::array<std::string_view, 1> fanInterface = { + "xyz.openbmc_project.Inventory.Item.Fan"}; + +inline void + updateFanList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId, + const dbus::utility::MapperGetSubTreePathsResponse& fanPaths) +{ + nlohmann::json& fanList = asyncResp->res.jsonValue["Members"]; + for (const std::string& fanPath : fanPaths) + { + std::string fanName = + sdbusplus::message::object_path(fanPath).filename(); + if (fanName.empty()) + { + continue; + } + + nlohmann::json item = nlohmann::json::object(); + item["@odata.id"] = boost::urls::format( + "/redfish/v1/Chassis/{}/ThermalSubsystem/Fans/{}", chassisId, + fanName); + + fanList.emplace_back(std::move(item)); + } + asyncResp->res.jsonValue["Members@odata.count"] = fanList.size(); +} + +inline void getFanPaths( + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::optional<std::string>& validChassisPath, + const std::function<void(const dbus::utility::MapperGetSubTreePathsResponse& + fanPaths)>& callback) +{ + sdbusplus::message::object_path endpointPath{*validChassisPath}; + endpointPath /= "cooled_by"; + + dbus::utility::getAssociatedSubTreePaths( + endpointPath, + sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0, + fanInterface, + [asyncResp, callback]( + const boost::system::error_code& ec, + const dbus::utility::MapperGetSubTreePathsResponse& subtreePaths) { + if (ec) + { + if (ec.value() != EBADR) + { + BMCWEB_LOG_ERROR + << "DBUS response error for getAssociatedSubTreePaths " + << ec.value(); + messages::internalError(asyncResp->res); + } + return; + } + callback(subtreePaths); + }); +} + +inline void doFanCollection(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId, + const std::optional<std::string>& validChassisPath) +{ + if (!validChassisPath) + { + messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); + return; + } + + asyncResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/FanCollection/FanCollection.json>; rel=describedby"); + asyncResp->res.jsonValue["@odata.type"] = "#FanCollection.FanCollection"; + asyncResp->res.jsonValue["@odata.id"] = boost::urls::format( + "/redfish/v1/Chassis/{}/ThermalSubsystem/Fans", chassisId); + asyncResp->res.jsonValue["Name"] = "Fan Collection"; + asyncResp->res.jsonValue["Description"] = + "The collection of Fan resource instances " + chassisId; + asyncResp->res.jsonValue["Members"] = nlohmann::json::array(); + asyncResp->res.jsonValue["Members@odata.count"] = 0; + + getFanPaths(asyncResp, validChassisPath, + std::bind_front(updateFanList, asyncResp, chassisId)); +} + +inline void + handleFanCollectionHead(App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + redfish::chassis_utils::getValidChassisPath( + asyncResp, chassisId, + [asyncResp, + chassisId](const std::optional<std::string>& validChassisPath) { + if (!validChassisPath) + { + messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); + return; + } + asyncResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/FanCollection/FanCollection.json>; rel=describedby"); + }); +} + +inline void + handleFanCollectionGet(App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, + const std::string& chassisId) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + redfish::chassis_utils::getValidChassisPath( + asyncResp, chassisId, + std::bind_front(doFanCollection, asyncResp, chassisId)); +} + +inline void requestRoutesFanCollection(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ThermalSubsystem/Fans/") + .privileges(redfish::privileges::headFanCollection) + .methods(boost::beast::http::verb::head)( + std::bind_front(handleFanCollectionHead, std::ref(app))); + + BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ThermalSubsystem/Fans/") + .privileges(redfish::privileges::getFanCollection) + .methods(boost::beast::http::verb::get)( + std::bind_front(handleFanCollectionGet, std::ref(app))); +} + +} // namespace redfish |