From 1827b4f1de1e42bb3e2f53f584f07bb7119a3ed2 Mon Sep 17 00:00:00 2001 From: Asmitha Karunanithi Date: Wed, 3 Apr 2024 11:44:22 +0000 Subject: Move to Redfish Action specific setProperty call This commit will migrate all the setProperty calls initiated by a redfish"Action" to "setDbusProperty" method in Redfish namespace that handles all DBuserrors in a consistent manner. This method will determine if a setProperty is called during redfish "Action" or just setting of a dbus property and internally call appropriate methods that handles different set of errors. All the Redfish action specific errors are defined in error_messages.hpp file. This specific change moves setProperty call in hypervisor_system.hpp and covers errors in the mentioned file only. Tested-By: Change-Id: I3da48fbeabcdcf088c4481021232f08a44797c86 Signed-off-by: Asmitha Karunanithi Signed-off-by: Ed Tanous --- redfish-core/include/error_messages.hpp | 15 ++++++++++ redfish-core/include/utils/dbus_utils.hpp | 36 ++++++++++++++++++++++- redfish-core/lib/hypervisor_system.hpp | 32 ++++---------------- redfish-core/src/error_messages.cpp | 23 +++++++++++++++ redfish-core/src/utils/dbus_utils.cpp | 49 ++++++++++++++++++++++++++++++- 5 files changed, 127 insertions(+), 28 deletions(-) (limited to 'redfish-core') diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp index 7adae19c87..91edc3c7cb 100644 --- a/redfish-core/include/error_messages.hpp +++ b/redfish-core/include/error_messages.hpp @@ -850,6 +850,21 @@ void actionParameterValueTypeError(crow::Response& res, std::string_view arg2, std::string_view arg3); +/** + * @brief Formats ActionParameterValueError message into JSON + * Message body: "Indicates that a parameter was given an invalid value." + * The value for the parameter %1 in the action %2 is invalid. + * + * @param[in] arg1 Parameter of message that will replace %1 in its body. + * @param[in] arg2 Parameter of message that will replace %2 in its body. + * + * @returns Message ActionParameterValueError formatted to JSON */ +nlohmann::json actionParameterValueError(const nlohmann::json& arg1, + std::string_view arg2); + +void actionParameterValueError(crow::Response& res, const nlohmann::json& arg1, + std::string_view arg2); + /** * @brief Formats SessionLimitExceeded message into JSON * Message body: "The session establishment failed due to the number of diff --git a/redfish-core/include/utils/dbus_utils.hpp b/redfish-core/include/utils/dbus_utils.hpp index cd7e0e2ca2..80571698a8 100644 --- a/redfish-core/include/utils/dbus_utils.hpp +++ b/redfish-core/include/utils/dbus_utils.hpp @@ -39,7 +39,13 @@ void afterSetProperty(const std::shared_ptr& asyncResp, const nlohmann::json& propertyValue, const boost::system::error_code& ec, const sdbusplus::message_t& msg); -} + +void afterSetPropertyAction(const std::shared_ptr& asyncResp, + const std::string& redfishActionName, + const std::string& redfishActionParameterName, + const boost::system::error_code& ec, + const sdbusplus::message_t& msg); +} // namespace details template void setDbusProperty(const std::shared_ptr& asyncResp, @@ -64,4 +70,32 @@ void setDbusProperty(const std::shared_ptr& asyncResp, }); } +template +void setDbusPropertyAction(const std::shared_ptr& asyncResp, + std::string_view processName, + const sdbusplus::message::object_path& path, + std::string_view interface, + std::string_view dbusProperty, + std::string_view redfishActionParameterName, + std::string_view redfishActionName, + const DbusPropertyType& prop) +{ + std::string processNameStr(processName); + std::string interfaceStr(interface); + std::string dbusPropertyStr(dbusProperty); + + sdbusplus::asio::setProperty( + *crow::connections::systemBus, processNameStr, path.str, interfaceStr, + dbusPropertyStr, prop, + [asyncResp, + redfishActionParameterName = std::string{redfishActionParameterName}, + jsonProp = nlohmann::json(prop), + redfishActionNameStr = std::string{redfishActionName}]( + const boost::system::error_code& ec, + const sdbusplus::message_t& msg) { + details::afterSetPropertyAction(asyncResp, redfishActionNameStr, + redfishActionParameterName, ec, msg); + }); +} + } // namespace redfish diff --git a/redfish-core/lib/hypervisor_system.hpp b/redfish-core/lib/hypervisor_system.hpp index 2b3714bae4..ad1fae8850 100644 --- a/redfish-core/lib/hypervisor_system.hpp +++ b/redfish-core/lib/hypervisor_system.hpp @@ -915,32 +915,12 @@ inline void handleHypervisorSystemResetPost( std::string command = "xyz.openbmc_project.State.Host.Transition.On"; - sdbusplus::asio::setProperty( - *crow::connections::systemBus, "xyz.openbmc_project.State.Hypervisor", - "/xyz/openbmc_project/state/hypervisor0", - "xyz.openbmc_project.State.Host", "RequestedHostTransition", command, - [asyncResp, resetType](const boost::system::error_code& ec) { - if (ec) - { - BMCWEB_LOG_ERROR("D-Bus responses error: {}", ec); - if (ec.value() == boost::asio::error::invalid_argument) - { - messages::actionParameterNotSupported(asyncResp->res, - *resetType, "Reset"); - return; - } - - if (ec.value() == boost::asio::error::host_unreachable) - { - messages::resourceNotFound(asyncResp->res, "Actions", "Reset"); - return; - } - - messages::internalError(asyncResp->res); - return; - } - messages::success(asyncResp->res); - }); + setDbusPropertyAction(asyncResp, "xyz.openbmc_project.State.Hypervisor", + sdbusplus::message::object_path( + "/xyz/openbmc_project/state/hypervisor0"), + "xyz.openbmc_project.State.Host", + "RequestedHostTransition", "ResetType", + "ComputerSystem.Reset", command); } inline void requestRoutesHypervisorSystems(App& app) diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp index 6c4282cc67..7b0251562d 100644 --- a/redfish-core/src/error_messages.cpp +++ b/redfish-core/src/error_messages.cpp @@ -1451,6 +1451,29 @@ void actionParameterValueTypeError(crow::Response& res, actionParameterValueTypeError(arg1, arg2, arg3)); } +/** + * @internal + * @brief Formats actionParameterValueError message into JSON + * + * See header file for more information + * @endinternal + */ +nlohmann::json actionParameterValueError(const nlohmann::json& arg1, + std::string_view arg2) +{ + std::string arg1Str = arg1.dump(2, ' ', true, + nlohmann::json::error_handler_t::replace); + return getLog(redfish::registries::base::Index::actionParameterValueError, + std::to_array({arg1Str, arg2})); +} + +void actionParameterValueError(crow::Response& res, const nlohmann::json& arg1, + std::string_view arg2) +{ + res.result(boost::beast::http::status::bad_request); + addMessageToErrorJson(res.jsonValue, actionParameterValueError(arg1, arg2)); +} + /** * @internal * @brief Formats SessionLimitExceeded message into JSON diff --git a/redfish-core/src/utils/dbus_utils.cpp b/redfish-core/src/utils/dbus_utils.cpp index 59ddb9d6ba..bffe7a867b 100644 --- a/redfish-core/src/utils/dbus_utils.cpp +++ b/redfish-core/src/utils/dbus_utils.cpp @@ -66,7 +66,54 @@ void afterSetProperty(const std::shared_ptr& asyncResp, messages::internalError(asyncResp->res); return; } - // Only set 204 if another erro hasn't already happened. + // Only set 204 if another error hasn't already happened. + if (asyncResp->res.result() == boost::beast::http::status::ok) + { + asyncResp->res.result(boost::beast::http::status::no_content); + } +}; + +void afterSetPropertyAction(const std::shared_ptr& asyncResp, + const std::string& redfishActionName, + const std::string& redfishActionParameterName, + const boost::system::error_code& ec, + const sdbusplus::message_t& /*msg*/) +{ + if (ec) + { + if (ec.value() == boost::asio::error::invalid_argument) + { + BMCWEB_LOG_WARNING( + "Resource {} is patched with invalid argument during action {}", + redfishActionParameterName, redfishActionName); + if (redfishActionParameterName.empty()) + { + messages::operationFailed(asyncResp->res); + } + else + { + messages::actionParameterValueError(asyncResp->res, + redfishActionParameterName, + redfishActionName); + } + return; + } + if (ec.value() == boost::asio::error::host_unreachable) + { + BMCWEB_LOG_WARNING( + "Resource {} is not found while performing action {}", + redfishActionParameterName, redfishActionName); + messages::resourceNotFound(asyncResp->res, "Actions", + redfishActionName); + return; + } + + BMCWEB_LOG_ERROR("D-Bus error setting Redfish Property {} ec={}", + redfishActionParameterName, ec); + messages::internalError(asyncResp->res); + return; + } + // Only set 204 if another error hasn't already happened. if (asyncResp->res.result() == boost::beast::http::status::ok) { asyncResp->res.result(boost::beast::http::status::no_content); -- cgit v1.2.3