summaryrefslogtreecommitdiff
path: root/redfish-core
diff options
context:
space:
mode:
authorEd Tanous <ed.tanous@intel.com>2018-09-21 23:38:49 +0300
committerEd Tanous <ed.tanous@intel.com>2018-10-22 19:04:10 +0300
commit9712f8ac42746e65f32c2bc3de0835846652568e (patch)
tree779224bc1c29105e0228626ea7335b610e266ddc /redfish-core
parent820ce598b31a6f9bf4d3715d337b8e5ee47196c7 (diff)
downloadbmcweb-9712f8ac42746e65f32c2bc3de0835846652568e.tar.xz
Implement a new way of unpacking json to structs
The existing way of decoding json structures, while fast has some disadvantages. 1. it's very verbose to write. 2. It requires in depth knowlege of redfish error messages to get correct. 3. It _can_ lead to undesired behavior, like half of a patch being applied, if only some of the values have bad types. This commit implements a new interface for decoding redfish json named.... readJson. It is a templated function, that lets you decode json values based on type easily, while still handling all the correct error codes that were handled previously. Use is done similar to the example below: std::string required; boost::optional<std::string> optional; if (!json_util::readJson(req, res, "OptionalParam", optional, "RequiredParam", required)) { return; } if (optional){ // optional param was given, take action. } As part of this patchset, the systems schema is moved to the new interface, which deletes some of the code involved and shows the improvement in clarity. Change-Id: I041a97c84d294df8cd4de4c2702e5ee22c0bc120 Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Diffstat (limited to 'redfish-core')
-rw-r--r--redfish-core/include/utils/json_utils.hpp124
-rw-r--r--redfish-core/lib/account_service.hpp235
-rw-r--r--redfish-core/lib/redfish_sessions.hpp46
-rw-r--r--redfish-core/lib/systems.hpp348
-rw-r--r--redfish-core/src/utils/json_utils.cpp3
5 files changed, 325 insertions, 431 deletions
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp
index bde81ce72d..3263c739a8 100644
--- a/redfish-core/include/utils/json_utils.hpp
+++ b/redfish-core/include/utils/json_utils.hpp
@@ -14,11 +14,13 @@
// limitations under the License.
*/
#pragma once
+
#include <crow/http_request.h>
#include <crow/http_response.h>
+#include <bitset>
+#include <error_messages.hpp>
#include <nlohmann/json.hpp>
-
namespace redfish
{
@@ -296,7 +298,125 @@ Result getDouble(const char* fieldName, const nlohmann::json& json,
*/
bool processJsonFromRequest(crow::Response& res, const crow::Request& req,
nlohmann::json& reqJson);
+namespace details
+{
+template <typename Type> struct unpackValue
+{
+ using isRequired = std::true_type;
+ using JsonType = std::add_const_t<std::add_pointer_t<Type>>;
+};
-} // namespace json_util
+template <typename OptionalType>
+struct unpackValue<boost::optional<OptionalType>>
+{
+ using isRequired = std::false_type;
+ using JsonType = std::add_const_t<std::add_pointer_t<OptionalType>>;
+};
+
+template <size_t Count, size_t Index>
+void readJsonValues(const std::string& key, nlohmann::json& jsonValue,
+ crow::Response& res, std::bitset<Count>& handled)
+{
+ BMCWEB_LOG_DEBUG << "Unable to find variable for key" << key;
+ messages::addMessageToErrorJson(res.jsonValue,
+ messages::propertyUnknown(key));
+ res.result(boost::beast::http::status::bad_request);
+}
+
+template <size_t Count, size_t Index, typename ValueType,
+ typename... UnpackTypes>
+void readJsonValues(const std::string& key, nlohmann::json& jsonValue,
+ crow::Response& res, std::bitset<Count>& handled,
+ const char* keyToCheck, ValueType& valueToFill,
+ UnpackTypes&... in)
+{
+ if (key != keyToCheck)
+ {
+ readJsonValues<Count, Index + 1>(key, jsonValue, res, handled, in...);
+ return;
+ }
+
+ handled.set(Index);
+
+ using UnpackType = typename unpackValue<ValueType>::JsonType;
+ UnpackType value = jsonValue.get_ptr<UnpackType>();
+ if (value == nullptr)
+ {
+ BMCWEB_LOG_DEBUG << "Value for key " << key
+ << " was incorrect type: " << jsonValue.type_name();
+ messages::addMessageToErrorJson(
+ res.jsonValue,
+ messages::propertyValueTypeError(jsonValue.dump(), key));
+ res.result(boost::beast::http::status::bad_request);
+ return;
+ }
+
+ valueToFill = *value;
+}
+
+template <size_t Index = 0, size_t Count>
+void handleMissing(std::bitset<Count>& handled, crow::Response& res)
+{
+}
+
+template <size_t Index = 0, size_t Count, typename ValueType,
+ typename... UnpackTypes>
+void handleMissing(std::bitset<Count>& handled, crow::Response& res,
+ const char* key, ValueType& unused, UnpackTypes&... in)
+{
+ if (!handled.test(Index) && unpackValue<ValueType>::isRequired::value)
+ {
+ messages::addMessageToErrorJson(res.jsonValue,
+ messages::propertyMissing(key));
+ res.result(boost::beast::http::status::bad_request);
+ }
+ details::handleMissing<Index + 1, Count>(handled, res, in...);
+}
+} // namespace details
+
+template <typename... UnpackTypes>
+bool readJson(const crow::Request& req, crow::Response& res, const char* key,
+ UnpackTypes&... in)
+{
+ nlohmann::json jsonRequest;
+ if (!json_util::processJsonFromRequest(res, req, jsonRequest))
+ {
+ BMCWEB_LOG_DEBUG << "Json value not readable";
+ return false;
+ }
+ if (!jsonRequest.is_object())
+ {
+ BMCWEB_LOG_DEBUG << "Json value is not an object";
+ messages::addMessageToErrorJson(res.jsonValue,
+ messages::unrecognizedRequestBody());
+ res.result(boost::beast::http::status::bad_request);
+ return false;
+ }
+
+ if (jsonRequest.empty())
+ {
+ BMCWEB_LOG_DEBUG << "Json value is empty";
+ messages::addMessageToErrorJson(res.jsonValue, messages::emptyJSON());
+ res.result(boost::beast::http::status::bad_request);
+ return false;
+ }
+
+ std::bitset<(sizeof...(in) + 1) / 2> handled(0);
+ for (const auto& item : jsonRequest.items())
+ {
+ details::readJsonValues<(sizeof...(in) + 1) / 2, 0, UnpackTypes...>(
+ item.key(), item.value(), res, handled, key, in...);
+ }
+
+ if (!handled.all())
+ {
+ details::handleMissing(handled, res, key, in...);
+
+ return false;
+ }
+ return res.result() == boost::beast::http::status::ok;
+}
+
+} // namespace json_util
} // namespace redfish
diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp
index 3d442789e6..cc375914ec 100644
--- a/redfish-core/lib/account_service.hpp
+++ b/redfish-core/lib/account_service.hpp
@@ -139,121 +139,30 @@ class AccountsCollection : public Node
{
auto asyncResp = std::make_shared<AsyncResp>(res);
- nlohmann::json patchRequest;
- if (!json_util::processJsonFromRequest(res, req, patchRequest))
+ std::string username;
+ std::string password;
+ boost::optional<std::string> roleId("User");
+ boost::optional<bool> enabled = true;
+ if (!json_util::readJson(req, res, "UserName", username, "Password",
+ password, "RoleId", roleId, "Enabled",
+ enabled))
{
return;
}
- const std::string* username = nullptr;
- const std::string* password = nullptr;
- // Default to user
- std::string privilege = "priv-user";
- // default to enabled
- bool enabled = true;
- for (const auto& item : patchRequest.items())
- {
- if (item.key() == "UserName")
- {
- username = item.value().get_ptr<const std::string*>();
- if (username == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueFormatError(item.value().dump(),
- item.key()));
- asyncResp->res.result(
- boost::beast::http::status::bad_request);
- return;
- }
- }
- else if (item.key() == "Enabled")
- {
- const bool* enabledJson = item.value().get_ptr<const bool*>();
- if (enabledJson == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueFormatError(item.value().dump(),
- item.key()));
- asyncResp->res.result(
- boost::beast::http::status::bad_request);
- return;
- }
- enabled = *enabledJson;
- }
- else if (item.key() == "Password")
- {
- password = item.value().get_ptr<const std::string*>();
- if (password == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueFormatError(item.value().dump(),
- item.key()));
- asyncResp->res.result(
- boost::beast::http::status::bad_request);
- return;
- }
- }
- else if (item.key() == "RoleId")
- {
- const std::string* roleIdJson =
- item.value().get_ptr<const std::string*>();
- if (roleIdJson == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueFormatError(item.value().dump(),
- item.key()));
- asyncResp->res.result(
- boost::beast::http::status::bad_request);
- return;
- }
- const char* priv = getRoleIdFromPrivilege(*roleIdJson);
- if (priv == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueNotInList(*roleIdJson,
- item.key()));
- asyncResp->res.result(
- boost::beast::http::status::bad_request);
- return;
- }
- privilege = priv;
- }
- else
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyNotWritable(item.key()));
- asyncResp->res.result(boost::beast::http::status::bad_request);
- return;
- }
- }
-
- if (username == nullptr)
+ const char* priv = getRoleIdFromPrivilege(*roleId);
+ if (priv == nullptr)
{
messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::createFailedMissingReqProperties("UserName"));
- asyncResp->res.result(boost::beast::http::status::bad_request);
- return;
- }
-
- if (password == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::createFailedMissingReqProperties("Password"));
- asyncResp->res.result(boost::beast::http::status::bad_request);
+ res.jsonValue,
+ messages::propertyValueNotInList(*roleId, "RoleId"));
+ res.result(boost::beast::http::status::bad_request);
return;
}
+ roleId = priv;
crow::connections::systemBus->async_method_call(
- [asyncResp, username{std::string(*username)},
- password{std::string(*password)}](
+ [asyncResp, username, password{std::move(password)}](
const boost::system::error_code ec) {
if (ec)
{
@@ -300,9 +209,9 @@ class AccountsCollection : public Node
"/redfish/v1/AccountService/Accounts/" + username);
},
"xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user",
- "xyz.openbmc_project.User.Manager", "CreateUser", *username,
+ "xyz.openbmc_project.User.Manager", "CreateUser", username,
std::array<const char*, 4>{"ipmi", "redfish", "ssh", "web"},
- privilege, enabled);
+ *roleId, *enabled);
}
static const char* getRoleIdFromPrivilege(boost::beast::string_view role)
@@ -472,15 +381,16 @@ class ManagerAccount : public Node
const std::vector<std::string>& params) override
{
auto asyncResp = std::make_shared<AsyncResp>(res);
-
if (params.size() != 1)
{
res.result(boost::beast::http::status::internal_server_error);
return;
}
- nlohmann::json patchRequest;
- if (!json_util::processJsonFromRequest(res, req, patchRequest))
+ boost::optional<std::string> password;
+ boost::optional<bool> enabled;
+ if (!json_util::readJson(req, res, "Password", password, "Enabled",
+ enabled))
{
return;
}
@@ -488,9 +398,8 @@ class ManagerAccount : public Node
// Check the user exists before updating the fields
checkDbusPathExists(
"/xyz/openbmc_project/users/" + params[0],
- [username{std::string(params[0])},
- patchRequest(std::move(patchRequest)),
- asyncResp](bool userExists) {
+ [username{std::string(params[0])}, password(std::move(password)),
+ enabled(std::move(enabled)), asyncResp](bool userExists) {
if (!userExists)
{
messages::addMessageToErrorJson(
@@ -503,78 +412,44 @@ class ManagerAccount : public Node
return;
}
- for (const auto& item : patchRequest.items())
+ if (password)
{
- if (item.key() == "Password")
+ if (!pamUpdatePassword(username, *password))
{
- const std::string* passStr =
- item.value().get_ptr<const std::string*>();
- if (passStr == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueFormatError(
- item.value().dump(), "Password"));
- return;
- }
- BMCWEB_LOG_DEBUG << "Updating user: " << username
- << " to password " << *passStr;
- if (!pamUpdatePassword(username, *passStr))
- {
- BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
- asyncResp->res.result(boost::beast::http::status::
- internal_server_error);
- return;
- }
- }
- else if (item.key() == "Enabled")
- {
- const bool* enabledBool =
- item.value().get_ptr<const bool*>();
-
- if (enabledBool == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueFormatError(
- item.value().dump(), "Enabled"));
- return;
- }
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR
- << "D-Bus responses error: " << ec;
- asyncResp->res.result(
- boost::beast::http::status::
- internal_server_error);
- return;
- }
- // TODO Consider support polling mechanism to
- // verify status of host and chassis after
- // execute the requested action.
- BMCWEB_LOG_DEBUG << "Response with no content";
- asyncResp->res.result(
- boost::beast::http::status::no_content);
- },
- "xyz.openbmc_project.User.Manager",
- "/xyz/openbmc_project/users/" + username,
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.User.Attributes"
- "UserEnabled",
- sdbusplus::message::variant<bool>{*enabledBool});
- }
- else
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyNotWritable(item.key()));
+ BMCWEB_LOG_ERROR << "pamUpdatePassword Failed";
asyncResp->res.result(
- boost::beast::http::status::bad_request);
+ boost::beast::http::status::internal_server_error);
return;
}
}
+
+ if (enabled)
+ {
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "D-Bus responses error: "
+ << ec;
+ asyncResp->res.result(
+ boost::beast::http::status::
+ internal_server_error);
+ return;
+ }
+ // TODO Consider support polling mechanism to
+ // verify status of host and chassis after
+ // execute the requested action.
+ BMCWEB_LOG_DEBUG << "Response with no content";
+ asyncResp->res.result(
+ boost::beast::http::status::no_content);
+ },
+ "xyz.openbmc_project.User.Manager",
+ "/xyz/openbmc_project/users/" + username,
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.User.Attributes"
+ "UserEnabled",
+ sdbusplus::message::variant<bool>{*enabled});
+ }
});
}
@@ -611,6 +486,6 @@ class ManagerAccount : public Node
"xyz.openbmc_project.User.Manager", userPath,
"xyz.openbmc_project.Object.Delete", "Delete");
}
-};
+}; // namespace redfish
} // namespace redfish
diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp
index 145bbb1755..4922724516 100644
--- a/redfish-core/lib/redfish_sessions.hpp
+++ b/redfish-core/lib/redfish_sessions.hpp
@@ -168,51 +168,13 @@ class SessionCollection : public Node
void doPost(crow::Response& res, const crow::Request& req,
const std::vector<std::string>& params) override
{
- nlohmann::json postRequest;
- if (!json_util::processJsonFromRequest(res, req, postRequest))
- {
- res.end();
- return;
- }
-
std::string username;
std::string password;
- for (const auto& item : postRequest.items())
+ if (!json_util::readJson(req, res, "UserName", username, "Password",
+ password))
{
- const std::string* strVal =
- item.value().get_ptr<const std::string*>();
- if (item.key() == "UserName")
- {
- if (strVal == nullptr)
- {
- res.result(boost::beast::http::status::bad_request);
- messages::addMessageToErrorJson(
- res.jsonValue, messages::propertyValueTypeError(
- item.value().dump(), item.key()));
- continue;
- }
- username = *strVal;
- }
- else if (item.key() == "Password")
- {
- if (strVal == nullptr)
- {
- res.result(boost::beast::http::status::bad_request);
- messages::addMessageToErrorJson(
- res.jsonValue, messages::propertyValueTypeError(
- item.value().dump(), item.key()));
- continue;
- }
-
- password = *strVal;
- }
- else
- {
- res.result(boost::beast::http::status::bad_request);
- messages::addMessageToErrorJson(
- res.jsonValue, messages::propertyUnknown(item.key()));
- continue;
- }
+ res.end();
+ return;
}
if (password.empty() || username.empty() ||
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 2268897320..7097cfcac6 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -15,9 +15,8 @@
*/
#pragma once
-#include "boost/container/flat_map.hpp"
-#include "node.hpp"
-
+#include <boost/container/flat_map.hpp>
+#include <node.hpp>
#include <utils/json_utils.hpp>
namespace redfish
@@ -580,121 +579,85 @@ class SystemActionsReset : public Node
void doPost(crow::Response &res, const crow::Request &req,
const std::vector<std::string> &params) override
{
- // Parse JSON request body.
- nlohmann::json post;
- if (!json_util::processJsonFromRequest(res, req, post))
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+
+ std::string resetType;
+ if (!json_util::readJson(req, res, "ResetType", resetType))
{
return;
}
- auto asyncResp = std::make_shared<AsyncResp>(res);
-
- for (const auto &item : post.items())
+ if (resetType == "ForceOff")
{
- if (item.key() == "ResetType")
- {
- const std::string *reqResetType =
- item.value().get_ptr<const std::string *>();
- if (reqResetType == nullptr)
- {
- res.result(boost::beast::http::status::bad_request);
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::actionParameterValueFormatError(
- item.value().dump(), "ResetType",
- "ComputerSystem.Reset"));
- res.end();
- return;
- }
+ // Force off acts on the chassis
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
+ return;
+ }
+ // TODO Consider support polling mechanism to verify
+ // status of host and chassis after execute the
+ // requested action.
+ BMCWEB_LOG_DEBUG << "Response with no content";
+ asyncResp->res.result(
+ boost::beast::http::status::no_content);
+ },
+ "xyz.openbmc_project.State.Chassis",
+ "/xyz/openbmc_project/state/chassis0",
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition",
+ sdbusplus::message::variant<std::string>{
+ "xyz.openbmc_project.State.Chassis.Transition.Off"});
+ return;
+ }
+ // all other actions operate on the host
+ std::string command;
+ // Execute Reset Action regarding to each reset type.
+ if (resetType == "On")
+ {
+ command = "xyz.openbmc_project.State.Host.Transition.On";
+ }
+ else if (resetType == "GracefulShutdown")
+ {
+ command = "xyz.openbmc_project.State.Host.Transition.Off";
+ }
+ else if (resetType == "GracefulRestart")
+ {
+ command = "xyz.openbmc_project.State.Host.Transition.Reboot";
+ }
+ else
+ {
+ res.result(boost::beast::http::status::bad_request);
+ messages::addMessageToErrorJson(
+ asyncResp->res.jsonValue,
+ messages::actionParameterUnknown("Reset", resetType));
+ return;
+ }
- if (*reqResetType == "ForceOff")
- {
- // Force off acts on the chassis
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "D-Bus responses error: "
- << ec;
- asyncResp->res.result(
- boost::beast::http::status::
- internal_server_error);
- return;
- }
- // TODO Consider support polling mechanism to verify
- // status of host and chassis after execute the
- // requested action.
- BMCWEB_LOG_DEBUG << "Response with no content";
- asyncResp->res.result(
- boost::beast::http::status::no_content);
- },
- "xyz.openbmc_project.State.Chassis",
- "/xyz/openbmc_project/state/chassis0",
- "org.freedesktop.DBus.Properties", "Set",
- "RequestedPowerTransition",
- "xyz.openbmc_project.State.Chassis",
- sdbusplus::message::variant<std::string>{
- "xyz.openbmc_project.State.Chassis.Transition."
- "Off"});
- return;
- }
- // all other actions operate on the host
- std::string command;
- // Execute Reset Action regarding to each reset type.
- if (*reqResetType == "On")
- {
- command = "xyz.openbmc_project.State.Host.Transition.On";
- }
- else if (*reqResetType == "GracefulShutdown")
- {
- command = "xyz.openbmc_project.State.Host.Transition.Off";
- }
- else if (*reqResetType == "GracefulRestart")
- {
- command =
- "xyz.openbmc_project.State.Host.Transition.Reboot";
- }
- else
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec) {
+ if (ec)
{
- res.result(boost::beast::http::status::bad_request);
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::actionParameterUnknown("Reset",
- *reqResetType));
- res.end();
+ BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
return;
}
-
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec;
- asyncResp->res.result(boost::beast::http::status::
- internal_server_error);
- return;
- }
- // TODO Consider support polling mechanism to verify
- // status of host and chassis after execute the
- // requested action.
- BMCWEB_LOG_DEBUG << "Response with no content";
- asyncResp->res.result(
- boost::beast::http::status::no_content);
- },
- "xyz.openbmc_project.State.Host",
- "/xyz/openbmc_project/state/host0",
- "org.freedesktop.DBus.Properties", "Set",
- "RequestedHostTransition", "xyz.openbmc_project.State.Host",
- sdbusplus::message::variant<std::string>{command});
- }
- else
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::actionParameterUnknown("ComputerSystem.Reset",
- item.key()));
- }
- }
+ // TODO Consider support polling mechanism to verify
+ // status of host and chassis after execute the
+ // requested action.
+ BMCWEB_LOG_DEBUG << "Response with no content";
+ asyncResp->res.result(boost::beast::http::status::no_content);
+ },
+ "xyz.openbmc_project.State.Host",
+ "/xyz/openbmc_project/state/host0",
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.State.Host", "RequestedHostTransition",
+ sdbusplus::message::variant<std::string>{command});
}
};
@@ -805,114 +768,91 @@ class Systems : public Node
res.result(boost::beast::http::status::internal_server_error);
return;
}
- // Parse JSON request body
- nlohmann::json patch;
- if (!json_util::processJsonFromRequest(res, req, patch))
- {
- return;
- }
const std::string &name = params[0];
res.jsonValue = Node::json;
res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
- for (const auto &item : patch.items())
+ std::string indicatorLedTemp;
+ boost::optional<std::string> indicatorLed = indicatorLedTemp;
+ if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed))
{
- if (item.key() == "IndicatorLed")
- {
- const std::string *reqLedState =
- item.value().get_ptr<const std::string *>();
- if (reqLedState == nullptr)
- {
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyValueFormatError(item.value().dump(),
- item.key()));
- return;
- }
-
- // Verify key value
- std::string dbusLedState;
- if (*reqLedState == "On")
- {
- dbusLedState =
- "xyz.openbmc_project.Led.Physical.Action.Lit";
- }
- else if (*reqLedState == "Blink")
- {
- dbusLedState =
- "xyz.openbmc_project.Led.Physical.Action.Blinking";
- }
- else if (*reqLedState == "Off")
- {
- dbusLedState =
- "xyz.openbmc_project.Led.Physical.Action.Off";
- }
- else
- {
- messages::addMessageToJsonRoot(
- res.jsonValue, messages::propertyValueNotInList(
- *reqLedState, "IndicatorLED"));
- return;
- }
-
- getHostState(asyncResp);
- getComputerSystem(asyncResp, name);
+ return;
+ }
- // Update led group
- BMCWEB_LOG_DEBUG << "Update led group.";
- crow::connections::systemBus->async_method_call(
- [asyncResp{std::move(asyncResp)}](
- const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
- asyncResp->res.result(boost::beast::http::status::
- internal_server_error);
- return;
- }
- BMCWEB_LOG_DEBUG << "Led group update done.";
- },
- "xyz.openbmc_project.LED.GroupManager",
- "/xyz/openbmc_project/led/groups/enclosure_identify",
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Led.Group", "Asserted",
- sdbusplus::message::variant<bool>(
- (dbusLedState ==
- "xyz.openbmc_project.Led.Physical.Action.Off"
- ? false
- : true)));
- // Update identify led status
- BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
- crow::connections::systemBus->async_method_call(
- [asyncResp{std::move(asyncResp)},
- reqLedState{std::move(*reqLedState)}](
- const boost::system::error_code ec) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
- asyncResp->res.result(boost::beast::http::status::
- internal_server_error);
- return;
- }
- BMCWEB_LOG_DEBUG << "Led state update done.";
- asyncResp->res.jsonValue["IndicatorLED"] =
- std::move(reqLedState);
- },
- "xyz.openbmc_project.LED.Controller.identify",
- "/xyz/openbmc_project/led/physical/identify",
- "org.freedesktop.DBus.Properties", "Set",
- "xyz.openbmc_project.Led.Physical", "State",
- sdbusplus::message::variant<std::string>(dbusLedState));
+ if (indicatorLed)
+ {
+ std::string dbusLedState;
+ if (*indicatorLed == "On")
+ {
+ dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit";
+ }
+ else if (*indicatorLed == "Blink")
+ {
+ dbusLedState =
+ "xyz.openbmc_project.Led.Physical.Action.Blinking";
+ }
+ else if (*indicatorLed == "Off")
+ {
+ dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off";
}
else
{
- messages::addMessageToErrorJson(
- asyncResp->res.jsonValue,
- messages::propertyNotWritable(item.key()));
+ messages::addMessageToJsonRoot(
+ res.jsonValue, messages::propertyValueNotInList(
+ *indicatorLed, "IndicatorLED"));
return;
}
+
+ getHostState(asyncResp);
+ getComputerSystem(asyncResp, name);
+
+ // Update led group
+ BMCWEB_LOG_DEBUG << "Update led group.";
+ crow::connections::systemBus->async_method_call(
+ [asyncResp{std::move(asyncResp)}](
+ const boost::system::error_code ec) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Led group update done.";
+ },
+ "xyz.openbmc_project.LED.GroupManager",
+ "/xyz/openbmc_project/led/groups/enclosure_identify",
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Led.Group", "Asserted",
+ sdbusplus::message::variant<bool>(
+ (dbusLedState ==
+ "xyz.openbmc_project.Led.Physical.Action.Off"
+ ? false
+ : true)));
+ // Update identify led status
+ BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection.";
+ crow::connections::systemBus->async_method_call(
+ [asyncResp{std::move(asyncResp)},
+ indicatorLed{std::move(*indicatorLed)}](
+ const boost::system::error_code ec) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error " << ec;
+ asyncResp->res.result(
+ boost::beast::http::status::internal_server_error);
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Led state update done.";
+ asyncResp->res.jsonValue["IndicatorLED"] =
+ std::move(indicatorLed);
+ },
+ "xyz.openbmc_project.LED.Controller.identify",
+ "/xyz/openbmc_project/led/physical/identify",
+ "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Led.Physical", "State",
+ sdbusplus::message::variant<std::string>(dbusLedState));
}
}
};
diff --git a/redfish-core/src/utils/json_utils.cpp b/redfish-core/src/utils/json_utils.cpp
index 868601f72d..e14131713a 100644
--- a/redfish-core/src/utils/json_utils.cpp
+++ b/redfish-core/src/utils/json_utils.cpp
@@ -15,8 +15,6 @@
*/
#include "utils/json_utils.hpp"
-#include <error_messages.hpp>
-
namespace redfish
{
@@ -521,5 +519,4 @@ bool processJsonFromRequest(crow::Response& res, const crow::Request& req,
}
} // namespace json_util
-
} // namespace redfish