summaryrefslogtreecommitdiff
path: root/redfish-core/lib/processor.hpp
diff options
context:
space:
mode:
authorJohn Edward Broadbent <jebr@google.com>2021-04-09 01:57:16 +0300
committerEd Tanous <ed@tanous.net>2021-06-03 21:18:02 +0300
commit7e860f1550c8686eec42f7a75bc5f2ef51e756ad (patch)
tree989da47a8427bc1a60119f480e2523151b1433aa /redfish-core/lib/processor.hpp
parenteb75770c6c4369984cb150ded4f5ace410ed24a9 (diff)
downloadbmcweb-7e860f1550c8686eec42f7a75bc5f2ef51e756ad.tar.xz
Remove Redfish Node class
Reduces the total number of lines and will allow for easier testing of the redfish responses. A main purpose of the node class was to set app.routeDynamic(). However now app.routeDynamic can handle the complexity that was once in critical to node. The macro app.routeDynamic() provides a shorter cleaner interface to the unerlying app.routeDyanic call. The old pattern set permissions for 6 interfaces (get, head, patch, put, delete_, and post) even if only one interface is created. That pattern creates unneeded code that can be safely removed with no effect. Unit test for the responses would have to mock the node the class in order to fully test responses. see https://github.com/openbmc/bmcweb/issues/181 The following files still need node to be extracted. virtual_media.hpp account_service.hpp redfish_sessions.hpp ethernet.hpp The files above use a pattern that is not trivial to address. Often their responses call an async lambda capturing the inherited class. ie (https://github.com/openbmc/bmcweb/blob/ffed87b5ad1797ca966d030e7f979770 28d258fa/redfish-core/lib/account_service.hpp#L1393) At a later point I plan to remove node from the files above. Tested: I ran the docker unit test with the following command. WORKSPACE=$(pwd) UNIT_TEST_PKG=bmcweb ./openbmc-build-scripts/run-unit-test-docker.sh I ran the validator and this change did not create any issues. python3 RedfishServiceValidator.py -c config.ini Signed-off-by: John Edward Broadbent <jebr@google.com> Signed-off-by: Ed Tanous <edtanous@google.com> Change-Id: I147a0289c52cb4198345b1ad9bfe6fdddf57f3df
Diffstat (limited to 'redfish-core/lib/processor.hpp')
-rw-r--r--redfish-core/lib/processor.hpp443
1 files changed, 187 insertions, 256 deletions
diff --git a/redfish-core/lib/processor.hpp b/redfish-core/lib/processor.hpp
index 49e04e296e..8127510848 100644
--- a/redfish-core/lib/processor.hpp
+++ b/redfish-core/lib/processor.hpp
@@ -17,8 +17,8 @@
#include "health.hpp"
+#include <app.hpp>
#include <boost/container/flat_map.hpp>
-#include <node.hpp>
#include <sdbusplus/message/native_types.hpp>
#include <sdbusplus/utility/dedup_variant.hpp>
#include <utils/collection.hpp>
@@ -981,281 +981,212 @@ inline void patchAppliedOperatingConfig(
std::variant<sdbusplus::message::object_path>(std::move(configPath)));
}
-class OperatingConfigCollection : public Node
+inline void requestRoutesOperatingConfigCollection(App& app)
{
- public:
- OperatingConfigCollection(App& app) :
- Node(app,
- "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/",
- std::string())
- {
- // Defined by Redfish spec privilege registry
- 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:
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
- {
- if (params.size() != 1)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- const std::string& cpuName = params[0];
- asyncResp->res.jsonValue["@odata.type"] =
- "#OperatingConfigCollection.OperatingConfigCollection";
- asyncResp->res.jsonValue["@odata.id"] = req.url;
- asyncResp->res.jsonValue["Name"] = "Operating Config Collection";
-
- // First find the matching CPU object so we know how to constrain our
- // search for related Config objects.
- crow::connections::systemBus->async_method_call(
- [asyncResp, cpuName](const boost::system::error_code ec,
- const std::vector<std::string>& objects) {
- if (ec)
- {
- BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
- << ec.message();
- messages::internalError(asyncResp->res);
- return;
- }
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& cpuName) {
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#OperatingConfigCollection.OperatingConfigCollection";
+ asyncResp->res.jsonValue["@odata.id"] = req.url;
+ asyncResp->res.jsonValue["Name"] =
+ "Operating Config Collection";
+
+ // First find the matching CPU object so we know how to
+ // constrain our search for related Config objects.
+ crow::connections::systemBus->async_method_call(
+ [asyncResp,
+ cpuName](const boost::system::error_code ec,
+ const std::vector<std::string>& objects) {
+ if (ec)
+ {
+ BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
+ << ec.message();
+ messages::internalError(asyncResp->res);
+ return;
+ }
- for (const std::string& object : objects)
- {
- if (!boost::ends_with(object, cpuName))
- {
- continue;
- }
+ for (const std::string& object : objects)
+ {
+ if (!boost::ends_with(object, cpuName))
+ {
+ continue;
+ }
- // Not expected that there will be multiple matching CPU
- // objects, but if there are just use the first one.
-
- // Use the common search routine to construct the Collection
- // of all Config objects under this CPU.
- collection_util::getCollectionMembers(
- asyncResp,
- "/redfish/v1/Systems/system/Processors/" + cpuName +
- "/OperatingConfigs",
- {"xyz.openbmc_project.Inventory.Item.Cpu."
- "OperatingConfig"},
- object.c_str());
- return;
- }
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
- "/xyz/openbmc_project/inventory", 0,
- std::array<const char*, 1>{"xyz.openbmc_project.Control.Processor."
- "CurrentOperatingConfig"});
- }
-};
+ // Not expected that there will be multiple matching
+ // CPU objects, but if there are just use the first
+ // one.
+
+ // Use the common search routine to construct the
+ // Collection of all Config objects under this CPU.
+ collection_util::getCollectionMembers(
+ asyncResp,
+ "/redfish/v1/Systems/system/Processors/" +
+ cpuName + "/OperatingConfigs",
+ {"xyz.openbmc_project.Inventory.Item.Cpu."
+ "OperatingConfig"},
+ object.c_str());
+ return;
+ }
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
+ "/xyz/openbmc_project/inventory", 0,
+ std::array<const char*, 1>{
+ "xyz.openbmc_project.Control.Processor."
+ "CurrentOperatingConfig"});
+ });
+}
-class OperatingConfig : public Node
+inline void requestRoutesOperatingConfig(App& app)
{
- public:
- OperatingConfig(App& app) :
- Node(app,
- "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/"
- "<str>/",
- std::string(), std::string())
- {
- // Defined by Redfish spec privilege registry
- 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:
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
- {
- if (params.size() != 2)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- const std::string& cpuName = params[0];
- const std::string& configName = params[1];
-
- // Ask for all objects implementing OperatingConfig so we can search for
- // one with a matching name
- crow::connections::systemBus->async_method_call(
- [asyncResp, cpuName, configName,
- reqUrl{req.url}](boost::system::error_code ec,
- const MapperGetSubTreeResponse& subtree) {
- if (ec)
- {
- BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
- << ec.message();
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string expectedEnding = cpuName + '/' + configName;
- for (const auto& [objectPath, serviceMap] : subtree)
- {
- // Ignore any configs without matching cpuX/configY
- if (!boost::ends_with(objectPath, expectedEnding) ||
- serviceMap.empty())
+ BMCWEB_ROUTE(
+ app,
+ "/redfish/v1/Systems/system/Processors/<str>/OperatingConfigs/<str>/")
+ .privileges({"Login"})
+ .methods(
+ boost::beast::http::verb::get)([](const crow::Request& req,
+ const std::shared_ptr<
+ bmcweb::AsyncResp>& asyncResp,
+ const std::string& cpuName,
+ const std::string& configName) {
+ // Ask for all objects implementing OperatingConfig so we can search
+ // for one with a matching name
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, cpuName, configName,
+ reqUrl{req.url}](boost::system::error_code ec,
+ const MapperGetSubTreeResponse& subtree) {
+ if (ec)
{
- continue;
+ BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", "
+ << ec.message();
+ messages::internalError(asyncResp->res);
+ return;
}
+ const std::string expectedEnding =
+ cpuName + '/' + configName;
+ for (const auto& [objectPath, serviceMap] : subtree)
+ {
+ // Ignore any configs without matching cpuX/configY
+ if (!boost::ends_with(objectPath, expectedEnding) ||
+ serviceMap.empty())
+ {
+ continue;
+ }
- nlohmann::json& json = asyncResp->res.jsonValue;
- json["@odata.type"] =
- "#OperatingConfig.v1_0_0.OperatingConfig";
- json["@odata.id"] = reqUrl;
- json["Name"] = "Processor Profile";
- json["Id"] = configName;
-
- // Just use the first implementation of the object - not
- // expected that there would be multiple matching services
- getOperatingConfigData(asyncResp, serviceMap.begin()->first,
- objectPath);
- return;
- }
- messages::resourceNotFound(asyncResp->res, "OperatingConfig",
- configName);
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTree",
- "/xyz/openbmc_project/inventory", 0,
- std::array<const char*, 1>{
- "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"});
- }
-};
+ nlohmann::json& json = asyncResp->res.jsonValue;
+ json["@odata.type"] =
+ "#OperatingConfig.v1_0_0.OperatingConfig";
+ json["@odata.id"] = reqUrl;
+ json["Name"] = "Processor Profile";
+ json["Id"] = configName;
+
+ // Just use the first implementation of the object - not
+ // expected that there would be multiple matching
+ // services
+ getOperatingConfigData(
+ asyncResp, serviceMap.begin()->first, objectPath);
+ return;
+ }
+ messages::resourceNotFound(asyncResp->res,
+ "OperatingConfig", configName);
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", 0,
+ std::array<const char*, 1>{
+ "xyz.openbmc_project.Inventory.Item.Cpu.OperatingConfig"});
+ });
+}
-class ProcessorCollection : public Node
+inline void requestRoutesProcessorCollection(App& app)
{
- public:
- /*
- * Default Constructor
- */
- ProcessorCollection(App& app) :
- Node(app, "/redfish/v1/Systems/system/Processors/")
- {
- 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(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&, const std::vector<std::string>&) override
- {
- asyncResp->res.jsonValue["@odata.type"] =
- "#ProcessorCollection.ProcessorCollection";
- asyncResp->res.jsonValue["Name"] = "Processor Collection";
-
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/system/Processors";
-
- collection_util::getCollectionMembers(
- asyncResp, "/redfish/v1/Systems/system/Processors",
- std::vector<const char*>(processorInterfaces.begin(),
- processorInterfaces.end()));
- }
-};
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Processors/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request&,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#ProcessorCollection.ProcessorCollection";
+ asyncResp->res.jsonValue["Name"] = "Processor Collection";
+
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Systems/system/Processors";
+
+ collection_util::getCollectionMembers(
+ asyncResp, "/redfish/v1/Systems/system/Processors",
+ std::vector<const char*>(processorInterfaces.begin(),
+ processorInterfaces.end()));
+ });
+}
-class Processor : public Node
+inline void requestRoutesProcessor(App& app)
{
- public:
- /*
- * Default Constructor
- */
- Processor(App& app) :
- Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
- {
- 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(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&,
- const std::vector<std::string>& params) override
- {
- // Check if there is required param, truly entering this shall be
- // impossible
- if (params.size() != 1)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& processorId = params[0];
- asyncResp->res.jsonValue["@odata.type"] =
- "#Processor.v1_11_0.Processor";
- asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/system/Processors/" + processorId;
- getProcessorObject(asyncResp, processorId, getProcessorData);
- }
-
- void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
- {
- std::optional<nlohmann::json> appliedConfigJson;
- if (!json_util::readJson(req, asyncResp->res, "AppliedOperatingConfig",
- appliedConfigJson))
- {
- return;
- }
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Processors/<str>/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request&,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& processorId) {
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Processor.v1_11_0.Processor";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Systems/system/Processors/" + processorId;
+
+ getProcessorObject(asyncResp, processorId, getProcessorData);
+ });
+
+ BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Processors/<str>/")
+ .privileges({"ConfigureComponents"})
+ .methods(boost::beast::http::verb::patch)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& processorId) {
+ std::optional<nlohmann::json> appliedConfigJson;
+ if (!json_util::readJson(req, asyncResp->res,
+ "AppliedOperatingConfig",
+ appliedConfigJson))
+ {
+ return;
+ }
- std::string appliedConfigUri;
- if (appliedConfigJson)
- {
- if (!json_util::readJson(*appliedConfigJson, asyncResp->res,
- "@odata.id", appliedConfigUri))
- {
- return;
- }
- // Check for 404 and find matching D-Bus object, then run property
- // patch handlers if that all succeeds.
- getProcessorObject(
- asyncResp, params[0],
- [appliedConfigUri = std::move(appliedConfigUri)](
- const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& processorId,
- const std::string& objectPath,
- const MapperServiceMap& serviceMap) {
- patchAppliedOperatingConfig(asyncResp, processorId,
- appliedConfigUri, objectPath,
- serviceMap);
- });
- }
- }
-};
+ std::string appliedConfigUri;
+ if (appliedConfigJson)
+ {
+ if (!json_util::readJson(*appliedConfigJson, asyncResp->res,
+ "@odata.id", appliedConfigUri))
+ {
+ return;
+ }
+ // Check for 404 and find matching D-Bus object, then run
+ // property patch handlers if that all succeeds.
+ getProcessorObject(
+ asyncResp, processorId,
+ [appliedConfigUri = std::move(appliedConfigUri)](
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& processorId,
+ const std::string& objectPath,
+ const MapperServiceMap& serviceMap) {
+ patchAppliedOperatingConfig(asyncResp, processorId,
+ appliedConfigUri,
+ objectPath, serviceMap);
+ });
+ }
+ });
+}
} // namespace redfish