diff options
author | John Edward Broadbent <jebr@google.com> | 2021-04-09 01:57:16 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2021-06-03 21:18:02 +0300 |
commit | 7e860f1550c8686eec42f7a75bc5f2ef51e756ad (patch) | |
tree | 989da47a8427bc1a60119f480e2523151b1433aa /redfish-core/lib/storage.hpp | |
parent | eb75770c6c4369984cb150ded4f5ace410ed24a9 (diff) | |
download | bmcweb-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/storage.hpp')
-rw-r--r-- | redfish-core/lib/storage.hpp | 749 |
1 files changed, 366 insertions, 383 deletions
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp index 34ef39a2f8..0c3d9fd08a 100644 --- a/redfish-core/lib/storage.hpp +++ b/redfish-core/lib/storage.hpp @@ -18,197 +18,325 @@ #include "health.hpp" #include "openbmc_dbus_rest.hpp" -#include <node.hpp> +#include <app.hpp> namespace redfish { -class StorageCollection : public Node +inline void requestRoutesStorageCollection(App& app) { - public: - StorageCollection(App& app) : - Node(app, "/redfish/v1/Systems/system/Storage/") - { - 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&, const std::vector<std::string>&) override - { - asyncResp->res.jsonValue["@odata.type"] = - "#StorageCollection.StorageCollection"; - asyncResp->res.jsonValue["@odata.id"] = - "/redfish/v1/Systems/system/Storage"; - asyncResp->res.jsonValue["Name"] = "Storage Collection"; - asyncResp->res.jsonValue["Members"] = { - {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}}; - asyncResp->res.jsonValue["Members@odata.count"] = 1; - } -}; - -class Storage : public Node + BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/") + .privileges({"Login"}) + .methods(boost::beast::http::verb::get)( + [](const crow::Request&, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { + asyncResp->res.jsonValue["@odata.type"] = + "#StorageCollection.StorageCollection"; + asyncResp->res.jsonValue["@odata.id"] = + "/redfish/v1/Systems/system/Storage"; + asyncResp->res.jsonValue["Name"] = "Storage Collection"; + asyncResp->res.jsonValue["Members"] = { + {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}}; + asyncResp->res.jsonValue["Members@odata.count"] = 1; + }); +} + +inline void requestRoutesStorage(App& app) { - public: - Storage(App& app) : Node(app, "/redfish/v1/Systems/system/Storage/1/") - { - 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&, const std::vector<std::string>&) override - { - asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage"; - asyncResp->res.jsonValue["@odata.id"] = - "/redfish/v1/Systems/system/Storage/1"; - asyncResp->res.jsonValue["Name"] = "Storage"; - asyncResp->res.jsonValue["Id"] = "1"; - asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; - - auto health = std::make_shared<HealthPopulate>(asyncResp); - health->populate(); - - crow::connections::systemBus->async_method_call( - [asyncResp, health](const boost::system::error_code ec, - const std::vector<std::string>& storageList) { - nlohmann::json& storageArray = - asyncResp->res.jsonValue["Drives"]; - storageArray = nlohmann::json::array(); - auto& count = asyncResp->res.jsonValue["Drives@odata.count"]; - count = 0; - - if (ec) - { - BMCWEB_LOG_ERROR << "Drive mapper call error"; - messages::internalError(asyncResp->res); - return; - } - - health->inventory.insert(health->inventory.end(), - storageList.begin(), - storageList.end()); - - for (const std::string& objpath : storageList) - { - std::size_t lastPos = objpath.rfind('/'); - if (lastPos == std::string::npos || - (objpath.size() <= lastPos + 1)) + BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/") + .privileges({"Login"}) + .methods( + boost::beast::http::verb:: + get)([](const crow::Request&, + const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) { + asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage"; + asyncResp->res.jsonValue["@odata.id"] = + "/redfish/v1/Systems/system/Storage/1"; + asyncResp->res.jsonValue["Name"] = "Storage"; + asyncResp->res.jsonValue["Id"] = "1"; + asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; + + auto health = std::make_shared<HealthPopulate>(asyncResp); + health->populate(); + + crow::connections::systemBus->async_method_call( + [asyncResp, + health](const boost::system::error_code ec, + const std::vector<std::string>& storageList) { + nlohmann::json& storageArray = + asyncResp->res.jsonValue["Drives"]; + storageArray = nlohmann::json::array(); + auto& count = + asyncResp->res.jsonValue["Drives@odata.count"]; + count = 0; + + if (ec) + { + BMCWEB_LOG_ERROR << "Drive mapper call error"; + messages::internalError(asyncResp->res); + return; + } + + health->inventory.insert(health->inventory.end(), + storageList.begin(), + storageList.end()); + + for (const std::string& objpath : storageList) { - BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath; - continue; + std::size_t lastPos = objpath.rfind('/'); + if (lastPos == std::string::npos || + (objpath.size() <= lastPos + 1)) + { + BMCWEB_LOG_ERROR << "Failed to find '/' in " + << objpath; + continue; + } + + storageArray.push_back( + {{"@odata.id", + "/redfish/v1/Systems/system/Storage/1/Drives/" + + objpath.substr(lastPos + 1)}}); } - storageArray.push_back( - {{"@odata.id", - "/redfish/v1/Systems/system/Storage/1/Drives/" + - objpath.substr(lastPos + 1)}}); - } - - count = storageArray.size(); - }, - "xyz.openbmc_project.ObjectMapper", - "/xyz/openbmc_project/object_mapper", - "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", - "/xyz/openbmc_project/inventory", int32_t(0), - std::array<const char*, 1>{ - "xyz.openbmc_project.Inventory.Item.Drive"}); - - crow::connections::systemBus->async_method_call( - [asyncResp, - health](const boost::system::error_code ec, - const crow::openbmc_mapper::GetSubTreeType& subtree) { - if (ec || !subtree.size()) - { - // doesn't have to be there - return; - } - - nlohmann::json& root = - asyncResp->res.jsonValue["StorageControllers"]; - root = nlohmann::json::array(); - for (const auto& [path, interfaceDict] : subtree) - { - std::size_t lastPos = path.rfind('/'); - if (lastPos == std::string::npos || - (path.size() <= lastPos + 1)) + count = storageArray.size(); + }, + "xyz.openbmc_project.ObjectMapper", + "/xyz/openbmc_project/object_mapper", + "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths", + "/xyz/openbmc_project/inventory", int32_t(0), + std::array<const char*, 1>{ + "xyz.openbmc_project.Inventory.Item.Drive"}); + + crow::connections::systemBus->async_method_call( + [asyncResp, + health](const boost::system::error_code ec, + const crow::openbmc_mapper::GetSubTreeType& subtree) { + if (ec || !subtree.size()) { - BMCWEB_LOG_ERROR << "Failed to find '/' in " << path; + // doesn't have to be there return; } - if (interfaceDict.size() != 1) + nlohmann::json& root = + asyncResp->res.jsonValue["StorageControllers"]; + root = nlohmann::json::array(); + for (const auto& [path, interfaceDict] : subtree) { - BMCWEB_LOG_ERROR << "Connection size " - << interfaceDict.size() - << ", greater than 1"; + std::size_t lastPos = path.rfind('/'); + if (lastPos == std::string::npos || + (path.size() <= lastPos + 1)) + { + BMCWEB_LOG_ERROR << "Failed to find '/' in " + << path; + return; + } + + if (interfaceDict.size() != 1) + { + BMCWEB_LOG_ERROR << "Connection size " + << interfaceDict.size() + << ", greater than 1"; + messages::internalError(asyncResp->res); + return; + } + + const std::string& connectionName = + interfaceDict.front().first; + + size_t index = root.size(); + nlohmann::json& storageController = + root.emplace_back(nlohmann::json::object()); + + std::string id = path.substr(lastPos + 1); + + storageController["@odata.type"] = + "#Storage.v1_7_0.StorageController"; + storageController["@odata.id"] = + "/redfish/v1/Systems/system/Storage/1" + "#/StorageControllers/" + + std::to_string(index); + storageController["Name"] = id; + storageController["MemberId"] = id; + storageController["Status"]["State"] = "Enabled"; + + crow::connections::systemBus->async_method_call( + [asyncResp, + index](const boost::system::error_code ec2, + const std::variant<bool> present) { + // this interface isn't necessary, only check it + // if we get a good return + if (ec2) + { + return; + } + const bool* enabled = + std::get_if<bool>(&present); + if (enabled == nullptr) + { + BMCWEB_LOG_DEBUG + << "Illegal property present"; + messages::internalError(asyncResp->res); + return; + } + if (!(*enabled)) + { + asyncResp->res + .jsonValue["StorageControllers"][index] + ["Status"]["State"] = + "Disabled"; + } + }, + connectionName, path, + "org.freedesktop.DBus.Properties", "Get", + "xyz.openbmc_project.Inventory.Item", "Present"); + + crow::connections::systemBus->async_method_call( + [asyncResp, index]( + const boost::system::error_code ec2, + const std::vector<std::pair< + std::string, + std::variant<bool, std::string, uint64_t>>>& + propertiesList) { + if (ec2) + { + // this interface isn't necessary + return; + } + for (const std::pair< + std::string, + std::variant<bool, std::string, + uint64_t>>& property : + propertiesList) + { + // Store DBus properties that are also + // Redfish properties with same name and a + // string value + const std::string& propertyName = + property.first; + nlohmann::json& object = + asyncResp->res + .jsonValue["StorageControllers"] + [index]; + if ((propertyName == "PartNumber") || + (propertyName == "SerialNumber") || + (propertyName == "Manufacturer") || + (propertyName == "Model")) + { + const std::string* value = + std::get_if<std::string>( + &property.second); + if (value == nullptr) + { + // illegal property + messages::internalError( + asyncResp->res); + return; + } + object[propertyName] = *value; + } + } + }, + connectionName, path, + "org.freedesktop.DBus.Properties", "GetAll", + "xyz.openbmc_project.Inventory.Decorator.Asset"); + } + + // this is done after we know the json array will no longer + // be resized, as json::array uses vector underneath and we + // need references to its members that won't change + size_t count = 0; + for (const auto& [path, interfaceDict] : subtree) + { + auto subHealth = std::make_shared<HealthPopulate>( + asyncResp, root[count]["Status"]); + subHealth->inventory.emplace_back(path); + health->inventory.emplace_back(path); + health->children.emplace_back(subHealth); + count++; + } + }, + "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.Item.StorageController"}); + }); +} + +inline void requestRoutesDrive(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/") + .privileges({"Login"}) + .methods( + boost::beast::http::verb::get)([](const crow::Request&, + const std::shared_ptr< + bmcweb::AsyncResp>& asyncResp, + const std::string& driveId) { + crow::connections::systemBus->async_method_call( + [asyncResp, + driveId](const boost::system::error_code ec, + const crow::openbmc_mapper::GetSubTreeType& subtree) { + if (ec) + { + BMCWEB_LOG_ERROR << "Drive mapper call error"; messages::internalError(asyncResp->res); return; } - const std::string& connectionName = - interfaceDict.front().first; + auto object2 = std::find_if( + subtree.begin(), subtree.end(), + [&driveId](auto& object) { + const std::string& path = object.first; + return boost::ends_with(path, "/" + driveId); + }); - size_t index = root.size(); - nlohmann::json& storageController = - root.emplace_back(nlohmann::json::object()); + if (object2 == subtree.end()) + { + messages::resourceNotFound(asyncResp->res, "Drive", + driveId); + return; + } - std::string id = path.substr(lastPos + 1); + const std::string& path = object2->first; + const std::vector< + std::pair<std::string, std::vector<std::string>>>& + connectionNames = object2->second; - storageController["@odata.type"] = - "#Storage.v1_7_0.StorageController"; - storageController["@odata.id"] = - "/redfish/v1/Systems/system/Storage/1" - "#/StorageControllers/" + - std::to_string(index); - storageController["Name"] = id; - storageController["MemberId"] = id; - storageController["Status"]["State"] = "Enabled"; + asyncResp->res.jsonValue["@odata.type"] = + "#Drive.v1_7_0.Drive"; + asyncResp->res.jsonValue["@odata.id"] = + "/redfish/v1/Systems/system/Storage/1/Drives/" + + driveId; + asyncResp->res.jsonValue["Name"] = driveId; + asyncResp->res.jsonValue["Id"] = driveId; - crow::connections::systemBus->async_method_call( - [asyncResp, index](const boost::system::error_code ec2, - const std::variant<bool> present) { - // this interface isn't necessary, only check it if - // we get a good return - if (ec2) - { - return; - } - const bool* enabled = std::get_if<bool>(&present); - if (enabled == nullptr) - { - BMCWEB_LOG_DEBUG << "Illegal property present"; - messages::internalError(asyncResp->res); - return; - } - if (!(*enabled)) - { - asyncResp->res - .jsonValue["StorageControllers"][index] - ["Status"]["State"] = "Disabled"; - } - }, - connectionName, path, "org.freedesktop.DBus.Properties", - "Get", "xyz.openbmc_project.Inventory.Item", "Present"); + if (connectionNames.size() != 1) + { + BMCWEB_LOG_ERROR << "Connection size " + << connectionNames.size() + << ", greater than 1"; + messages::internalError(asyncResp->res); + return; + } + getMainChassisId( + asyncResp, + [](const std::string& chassisId, + const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { + aRsp->res.jsonValue["Links"]["Chassis"] = { + {"@odata.id", + "/redfish/v1/Chassis/" + chassisId}}; + }); + + const std::string& connectionName = + connectionNames[0].first; crow::connections::systemBus->async_method_call( - [asyncResp, - index](const boost::system::error_code ec2, - const std::vector<std::pair< - std::string, - std::variant<bool, std::string, uint64_t>>>& - propertiesList) { + [asyncResp]( + const boost::system::error_code ec2, + const std::vector<std::pair< + std::string, + std::variant<bool, std::string, uint64_t>>>& + propertiesList) { if (ec2) { // this interface isn't necessary @@ -224,9 +352,6 @@ class Storage : public Node // string value const std::string& propertyName = property.first; - nlohmann::json& object = - asyncResp->res - .jsonValue["StorageControllers"][index]; if ((propertyName == "PartNumber") || (propertyName == "SerialNumber") || (propertyName == "Manufacturer") || @@ -241,226 +366,84 @@ class Storage : public Node messages::internalError(asyncResp->res); return; } - object[propertyName] = *value; + asyncResp->res.jsonValue[propertyName] = + *value; } } }, connectionName, path, "org.freedesktop.DBus.Properties", "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset"); - } - - // this is done after we know the json array will no longer be - // resized, as json::array uses vector underneath and we need - // references to its members that won't change - size_t count = 0; - for (const auto& [path, interfaceDict] : subtree) - { - auto subHealth = std::make_shared<HealthPopulate>( - asyncResp, root[count]["Status"]); - subHealth->inventory.emplace_back(path); + + // default it to Enabled + asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; + + auto health = std::make_shared<HealthPopulate>(asyncResp); health->inventory.emplace_back(path); - health->children.emplace_back(subHealth); - count++; - } - }, - "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.Item.StorageController"}); - } -}; - -class Drive : public Node -{ - public: - Drive(App& app) : - Node(app, "/redfish/v1/Systems/system/Storage/1/Drives/<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: - void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, - const crow::Request&, - const std::vector<std::string>& params) override - { - if (params.size() != 1) - { - messages::internalError(asyncResp->res); - return; - } - const std::string& driveId = params[0]; - - crow::connections::systemBus->async_method_call( - [asyncResp, - driveId](const boost::system::error_code ec, - const crow::openbmc_mapper::GetSubTreeType& subtree) { - if (ec) - { - BMCWEB_LOG_ERROR << "Drive mapper call error"; - messages::internalError(asyncResp->res); - return; - } - - auto object2 = std::find_if( - subtree.begin(), subtree.end(), [&driveId](auto& object) { - const std::string& path = object.first; - return boost::ends_with(path, "/" + driveId); - }); - - if (object2 == subtree.end()) - { - messages::resourceNotFound(asyncResp->res, "Drive", - driveId); - return; - } - - const std::string& path = object2->first; - const std::vector< - std::pair<std::string, std::vector<std::string>>>& - connectionNames = object2->second; - - asyncResp->res.jsonValue["@odata.type"] = "#Drive.v1_7_0.Drive"; - asyncResp->res.jsonValue["@odata.id"] = - "/redfish/v1/Systems/system/Storage/1/Drives/" + driveId; - asyncResp->res.jsonValue["Name"] = driveId; - asyncResp->res.jsonValue["Id"] = driveId; - - if (connectionNames.size() != 1) - { - BMCWEB_LOG_ERROR << "Connection size " - << connectionNames.size() - << ", greater than 1"; - messages::internalError(asyncResp->res); - return; - } - - getMainChassisId( - asyncResp, - [](const std::string& chassisId, - const std::shared_ptr<bmcweb::AsyncResp>& aRsp) { - aRsp->res.jsonValue["Links"]["Chassis"] = { - {"@odata.id", "/redfish/v1/Chassis/" + chassisId}}; - }); - - const std::string& connectionName = connectionNames[0].first; - crow::connections::systemBus->async_method_call( - [asyncResp](const boost::system::error_code ec2, - const std::vector<std::pair< - std::string, - std::variant<bool, std::string, uint64_t>>>& - propertiesList) { - if (ec2) - { - // this interface isn't necessary - return; - } - for (const std::pair<std::string, - std::variant<bool, std::string, - uint64_t>>& property : - propertiesList) - { - // Store DBus properties that are also - // Redfish properties with same name and a - // string value - const std::string& propertyName = property.first; - if ((propertyName == "PartNumber") || - (propertyName == "SerialNumber") || - (propertyName == "Manufacturer") || - (propertyName == "Model")) + health->populate(); + + crow::connections::systemBus->async_method_call( + [asyncResp, path](const boost::system::error_code ec2, + const std::variant<bool> present) { + // this interface isn't necessary, only check it if + // we get a good return + if (ec2) { - const std::string* value = - std::get_if<std::string>(&property.second); - if (value == nullptr) - { - // illegal property - messages::internalError(asyncResp->res); - return; - } - asyncResp->res.jsonValue[propertyName] = *value; + return; } - } - }, - connectionName, path, "org.freedesktop.DBus.Properties", - "GetAll", "xyz.openbmc_project.Inventory.Decorator.Asset"); - - // default it to Enabled - asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; - - auto health = std::make_shared<HealthPopulate>(asyncResp); - health->inventory.emplace_back(path); - health->populate(); - - crow::connections::systemBus->async_method_call( - [asyncResp, path](const boost::system::error_code ec2, - const std::variant<bool> present) { - // this interface isn't necessary, only check it if we - // get a good return - if (ec2) - { - return; - } - const bool* enabled = std::get_if<bool>(&present); - if (enabled == nullptr) - { - BMCWEB_LOG_DEBUG << "Illegal property present"; - messages::internalError(asyncResp->res); - return; - } - if (!(*enabled)) - { - asyncResp->res.jsonValue["Status"]["State"] = - "Disabled"; - } - }, - connectionName, path, "org.freedesktop.DBus.Properties", - "Get", "xyz.openbmc_project.Inventory.Item", "Present"); - - crow::connections::systemBus->async_method_call( - [asyncResp](const boost::system::error_code ec2, - const std::variant<bool> rebuilding) { - // this interface isn't necessary, only check it if we - // get a good return - if (ec2) - { - return; - } - const bool* updating = std::get_if<bool>(&rebuilding); - if (updating == nullptr) - { - BMCWEB_LOG_DEBUG << "Illegal property present"; - messages::internalError(asyncResp->res); - return; - } + const bool* enabled = std::get_if<bool>(&present); + if (enabled == nullptr) + { + BMCWEB_LOG_DEBUG << "Illegal property present"; + messages::internalError(asyncResp->res); + return; + } + if (!(*enabled)) + { + asyncResp->res.jsonValue["Status"]["State"] = + "Disabled"; + } + }, + connectionName, path, "org.freedesktop.DBus.Properties", + "Get", "xyz.openbmc_project.Inventory.Item", "Present"); - // updating and disabled in the backend shouldn't be - // able to be set at the same time, so we don't need to - // check for the race condition of these two calls - if ((*updating)) - { - asyncResp->res.jsonValue["Status"]["State"] = - "Updating"; - } - }, - connectionName, path, "org.freedesktop.DBus.Properties", - "Get", "xyz.openbmc_project.State.Drive", "Rebuilding"); - }, - "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.Item.Drive"}); - } -}; + crow::connections::systemBus->async_method_call( + [asyncResp](const boost::system::error_code ec2, + const std::variant<bool> rebuilding) { + // this interface isn't necessary, only check it if + // we get a good return + if (ec2) + { + return; + } + const bool* updating = + std::get_if<bool>(&rebuilding); + if (updating == nullptr) + { + BMCWEB_LOG_DEBUG << "Illegal property present"; + messages::internalError(asyncResp->res); + return; + } + + // updating and disabled in the backend shouldn't be + // able to be set at the same time, so we don't need + // to check for the race condition of these two + // calls + if ((*updating)) + { + asyncResp->res.jsonValue["Status"]["State"] = + "Updating"; + } + }, + connectionName, path, "org.freedesktop.DBus.Properties", + "Get", "xyz.openbmc_project.State.Drive", "Rebuilding"); + }, + "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.Item.Drive"}); + }); +} } // namespace redfish |