diff options
Diffstat (limited to 'redfish-core/lib/chassis.hpp')
-rw-r--r-- | redfish-core/lib/chassis.hpp | 415 |
1 files changed, 224 insertions, 191 deletions
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp index b1c20a538a..7b68a270ad 100644 --- a/redfish-core/lib/chassis.hpp +++ b/redfish-core/lib/chassis.hpp @@ -16,9 +16,11 @@ #pragma once #include "node.hpp" + #include <boost/container/flat_map.hpp> -namespace redfish { +namespace redfish +{ /** * DBus types primitives for several generic DBus interfaces @@ -47,220 +49,251 @@ using PropertiesType = boost::container::flat_map<std::string, VariantType>; * This perhaps shall be different file, which has to be chosen on compile time * depending on OEM needs */ -class OnDemandChassisProvider { - public: - /** - * Function that retrieves all Chassis available through EntityManager. - * @param callback a function that shall be called to convert Dbus output into - * JSON. - */ - template <typename CallbackFunc> - void getChassisList(CallbackFunc &&callback) { - const std::array<const char *, 4> interfaces = { - "xyz.openbmc_project.Inventory.Item.Board", - "xyz.openbmc_project.Inventory.Item.Chassis", - "xyz.openbmc_project.Inventory.Item.PowerSupply", - "xyz.openbmc_project.Inventory.Item.System", +class OnDemandChassisProvider +{ + public: + /** + * Function that retrieves all Chassis available through EntityManager. + * @param callback a function that shall be called to convert Dbus output + * into JSON. + */ + template <typename CallbackFunc> + void getChassisList(CallbackFunc &&callback) + { + const std::array<const char *, 4> interfaces = { + "xyz.openbmc_project.Inventory.Item.Board", + "xyz.openbmc_project.Inventory.Item.Chassis", + "xyz.openbmc_project.Inventory.Item.PowerSupply", + "xyz.openbmc_project.Inventory.Item.System", + }; + crow::connections::systemBus->async_method_call( + [callback{std::move(callback)}]( + const boost::system::error_code error_code, + const std::vector<std::string> &resp) { + // Callback requires vector<string> to retrieve all available + // chassis list. + std::vector<std::string> chassisList; + if (error_code) + { + // Something wrong on DBus, the error_code is not important + // at this moment, just return success=false, and empty + // output. Since size of vector may vary depending on + // information from Entity Manager, and empty output could + // not be treated same way as error. + callback(false, chassisList); + return; + } + // Iterate over all retrieved ObjectPaths. + for (const std::string &objpath : resp) + { + std::size_t lastPos = objpath.rfind("/"); + if (lastPos != std::string::npos) + { + // and put it into output vector. + chassisList.emplace_back(objpath.substr(lastPos + 1)); + } + } + // Finally make a callback with useful data + callback(true, chassisList); + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", + "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", + "/xyz/openbmc_project/inventory", int32_t(3), interfaces); }; - crow::connections::systemBus->async_method_call( - [callback{std::move(callback)}]( - const boost::system::error_code error_code, - const std::vector<std::string> &resp) { - // Callback requires vector<string> to retrieve all available chassis - // list. - std::vector<std::string> chassisList; - if (error_code) { - // Something wrong on DBus, the error_code is not important at this - // moment, just return success=false, and empty output. Since size - // of vector may vary depending on information from Entity Manager, - // and empty output could not be treated same way as error. - callback(false, chassisList); - return; - } - // Iterate over all retrieved ObjectPaths. - for (const std::string &objpath : resp) { - std::size_t lastPos = objpath.rfind("/"); - if (lastPos != std::string::npos) { - // and put it into output vector. - chassisList.emplace_back(objpath.substr(lastPos + 1)); - } - } - // Finally make a callback with useful data - callback(true, chassisList); - }, - "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", - "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", - "/xyz/openbmc_project/inventory", int32_t(3), interfaces); - }; }; /** * ChassisCollection derived class for delivering Chassis Collection Schema */ -class ChassisCollection : public Node { - public: - ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/") { - Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection"; - Node::json["@odata.id"] = "/redfish/v1/Chassis"; - Node::json["@odata.context"] = - "/redfish/v1/$metadata#ChassisCollection.ChassisCollection"; - Node::json["Name"] = "Chassis Collection"; +class ChassisCollection : public Node +{ + public: + ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/") + { + Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection"; + Node::json["@odata.id"] = "/redfish/v1/Chassis"; + Node::json["@odata.context"] = + "/redfish/v1/$metadata#ChassisCollection.ChassisCollection"; + Node::json["Name"] = "Chassis Collection"; - entityPrivileges = { - {boost::beast::http::verb::get, {{"Login"}}}, - {boost::beast::http::verb::head, {{"Login"}}}, - {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; - } + entityPrivileges = { + {boost::beast::http::verb::get, {{"Login"}}}, + {boost::beast::http::verb::head, {{"Login"}}}, + {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; + } - private: - /** - * Functions triggers appropriate requests on DBus - */ - void doGet(crow::Response &res, const crow::Request &req, - const std::vector<std::string> ¶ms) override { - // get chassis list, and call the below callback for JSON preparation - chassisProvider.getChassisList( - [&](const bool &success, const std::vector<std::string> &output) { - if (success) { - // ... prepare json array with appropriate @odata.id links - nlohmann::json chassisArray = nlohmann::json::array(); - for (const std::string &chassisItem : output) { - chassisArray.push_back( - {{"@odata.id", "/redfish/v1/Chassis/" + chassisItem}}); - } - // Then attach members, count size and return, - Node::json["Members"] = chassisArray; - Node::json["Members@odata.count"] = chassisArray.size(); - res.jsonValue = Node::json; - } else { - // ... otherwise, return INTERNALL ERROR - res.result(boost::beast::http::status::internal_server_error); - } - res.end(); - }); - } + private: + /** + * Functions triggers appropriate requests on DBus + */ + void doGet(crow::Response &res, const crow::Request &req, + const std::vector<std::string> ¶ms) override + { + // get chassis list, and call the below callback for JSON preparation + chassisProvider.getChassisList( + [&](const bool &success, const std::vector<std::string> &output) { + if (success) + { + // ... prepare json array with appropriate @odata.id links + nlohmann::json chassisArray = nlohmann::json::array(); + for (const std::string &chassisItem : output) + { + chassisArray.push_back( + {{"@odata.id", + "/redfish/v1/Chassis/" + chassisItem}}); + } + // Then attach members, count size and return, + Node::json["Members"] = chassisArray; + Node::json["Members@odata.count"] = chassisArray.size(); + res.jsonValue = Node::json; + } + else + { + // ... otherwise, return INTERNALL ERROR + res.result( + boost::beast::http::status::internal_server_error); + } + res.end(); + }); + } - // Chassis Provider object - // TODO(Pawel) consider move it to singleton - OnDemandChassisProvider chassisProvider; + // Chassis Provider object + // TODO(Pawel) consider move it to singleton + OnDemandChassisProvider chassisProvider; }; /** * Chassis override class for delivering Chassis Schema */ -class Chassis : public Node { - public: - Chassis(CrowApp &app) - : Node(app, "/redfish/v1/Chassis/<str>/", std::string()) { - Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis"; - Node::json["@odata.id"] = "/redfish/v1/Chassis"; - Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis"; - Node::json["Name"] = "Chassis Collection"; - Node::json["ChassisType"] = "RackMount"; - - entityPrivileges = { - {boost::beast::http::verb::get, {{"Login"}}}, - {boost::beast::http::verb::head, {{"Login"}}}, - {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, - {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; - } +class Chassis : public Node +{ + public: + Chassis(CrowApp &app) : + Node(app, "/redfish/v1/Chassis/<str>/", std::string()) + { + Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis"; + Node::json["@odata.id"] = "/redfish/v1/Chassis"; + Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis"; + Node::json["Name"] = "Chassis Collection"; + Node::json["ChassisType"] = "RackMount"; - private: - /** - * Functions triggers appropriate requests on DBus - */ - void doGet(crow::Response &res, const crow::Request &req, - const std::vector<std::string> ¶ms) override { - // Check if there is required param, truly entering this shall be - // impossible. - if (params.size() != 1) { - res.result(boost::beast::http::status::internal_server_error); - res.end(); - return; + entityPrivileges = { + {boost::beast::http::verb::get, {{"Login"}}}, + {boost::beast::http::verb::head, {{"Login"}}}, + {boost::beast::http::verb::patch, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::put, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}}, + {boost::beast::http::verb::post, {{"ConfigureComponents"}}}}; } - res.jsonValue = Node::json; - const std::string &chassisId = params[0]; - crow::connections::systemBus->async_method_call( - [&res, chassisId(std::string(chassisId)) ]( - const boost::system::error_code error_code, - const std::vector<std::pair< - std::string, - std::vector<std::pair<std::string, std::vector<std::string>>>>> - &subtree) { - if (error_code) { - res.jsonValue = {}; + private: + /** + * Functions triggers appropriate requests on DBus + */ + void doGet(crow::Response &res, const crow::Request &req, + const std::vector<std::string> ¶ms) override + { + // Check if there is required param, truly entering this shall be + // impossible. + if (params.size() != 1) + { res.result(boost::beast::http::status::internal_server_error); res.end(); return; - } - // Iterate over all retrieved ObjectPaths. - for (const std::pair<std::string, - std::vector<std::pair<std::string, - std::vector<std::string>>>> - &object : subtree) { - const std::string &path = object.first; - const std::vector<std::pair<std::string, std::vector<std::string>>> - &connectionNames = object.second; + } - if (!boost::ends_with(path, chassisId)) { - continue; - } - if (connectionNames.size() < 1) { - BMCWEB_LOG_ERROR << "Only got " << connectionNames.size() - << " Connection names"; - continue; - } + res.jsonValue = Node::json; + const std::string &chassisId = params[0]; + crow::connections::systemBus->async_method_call( + [&res, chassisId(std::string(chassisId))]( + const boost::system::error_code error_code, + const std::vector<std::pair< + std::string, std::vector<std::pair< + std::string, std::vector<std::string>>>>> + &subtree) { + if (error_code) + { + res.jsonValue = {}; + res.result( + boost::beast::http::status::internal_server_error); + res.end(); + return; + } + // Iterate over all retrieved ObjectPaths. + for (const std::pair< + std::string, + std::vector< + std::pair<std::string, std::vector<std::string>>>> + &object : subtree) + { + const std::string &path = object.first; + const std::vector< + std::pair<std::string, std::vector<std::string>>> + &connectionNames = object.second; - const std::string connectionName = connectionNames[0].first; - crow::connections::systemBus->async_method_call( - [&res, chassisId(std::string(chassisId)) ]( - const boost::system::error_code error_code, - const std::vector<std::pair<std::string, VariantType>> - &propertiesList) { - for (const std::pair<std::string, VariantType> &property : - propertiesList) { - const std::string *value = - mapbox::getPtr<const std::string>(property.second); - if (value != nullptr) { - res.jsonValue[property.first] = *value; + if (!boost::ends_with(path, chassisId)) + { + continue; } - } - res.jsonValue["Name"] = chassisId; - res.jsonValue["Id"] = chassisId; - res.jsonValue["Thermal"] = { - {"@odata.id", - "/redfish/v1/Chassis/" + chassisId + "/Thermal"}}; - res.end(); - }, - connectionName, path, "org.freedesktop.DBus.Properties", - "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset"); - // Found the Connection we were looking for, return - return; - } + if (connectionNames.size() < 1) + { + BMCWEB_LOG_ERROR << "Only got " + << connectionNames.size() + << " Connection names"; + continue; + } + + const std::string connectionName = connectionNames[0].first; + crow::connections::systemBus->async_method_call( + [&res, chassisId(std::string(chassisId))]( + const boost::system::error_code error_code, + const std::vector<std::pair< + std::string, VariantType>> &propertiesList) { + for (const std::pair<std::string, VariantType> + &property : propertiesList) + { + const std::string *value = + mapbox::getPtr<const std::string>( + property.second); + if (value != nullptr) + { + res.jsonValue[property.first] = *value; + } + } + res.jsonValue["Name"] = chassisId; + res.jsonValue["Id"] = chassisId; + res.jsonValue["Thermal"] = { + {"@odata.id", "/redfish/v1/Chassis/" + + chassisId + "/Thermal"}}; + res.end(); + }, + connectionName, path, "org.freedesktop.DBus.Properties", + "GetAll", + "xyz.openbmc_project.Inventory.Decorator.Asset"); + // Found the Connection we were looking for, return + return; + } - // Couldn't find an object with that name. return an error - res.result(boost::beast::http::status::not_found); + // Couldn't find an object with that name. return an error + res.result(boost::beast::http::status::not_found); - res.end(); - }, - "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", - "xyz.openbmc_project.ObjectMapper", "GetSubTree", - "/xyz/openbmc_project/inventory", int32_t(0), - std::array<const char *, 1>{ - "xyz.openbmc_project.Inventory.Decorator.Asset"}); - } + res.end(); + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", + "xyz.openbmc_project.ObjectMapper", "GetSubTree", + "/xyz/openbmc_project/inventory", int32_t(0), + std::array<const char *, 1>{ + "xyz.openbmc_project.Inventory.Decorator.Asset"}); + } - // Chassis Provider object - // TODO(Pawel) consider move it to singleton - OnDemandChassisProvider chassisProvider; -}; // namespace redfish + // Chassis Provider object + // TODO(Pawel) consider move it to singleton + OnDemandChassisProvider chassisProvider; +}; // namespace redfish -} // namespace redfish +} // namespace redfish |