Roll out error message utils
This code should really be in a cpp/hpp file, not in a generated python
script. The python script housed this temporarily to allow us to
generate the registries. It's time to roll it out.
Tested: Message registries generate successfully on GET. Redfish
service validator passes.
Change-Id: I7aca2d0a7fac6d530511421b667ff732617df61e
Signed-off-by: Ed Tanous <etanous@nvidia.com>
diff --git a/meson.build b/meson.build
index ffc0c14..9c16bde 100644
--- a/meson.build
+++ b/meson.build
@@ -358,6 +358,7 @@
'http/mutual_tls.cpp',
'redfish-core/src/dbus_log_watcher.cpp',
'redfish-core/src/error_messages.cpp',
+ 'redfish-core/src/error_message_utils.cpp',
'redfish-core/src/event_log.cpp',
'redfish-core/src/filesystem_log_watcher.cpp',
'redfish-core/src/filter_expr_executor.cpp',
diff --git a/redfish-core/include/error_message_utils.hpp b/redfish-core/include/error_message_utils.hpp
new file mode 100644
index 0000000..75015bc
--- /dev/null
+++ b/redfish-core/include/error_message_utils.hpp
@@ -0,0 +1,24 @@
+#include <nlohmann/json.hpp>
+
+#include <string_view>
+
+namespace redfish
+{
+
+namespace messages
+{
+
+constexpr const char* messageVersionPrefix = "Base.1.19.0.";
+constexpr const char* messageAnnotation = "@Message.ExtendedInfo";
+
+void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source);
+void addMessageToJsonRoot(nlohmann::json& target,
+ const nlohmann::json& message);
+
+void addMessageToJson(nlohmann::json& target, const nlohmann::json& message,
+ std::string_view fieldPath);
+
+void addMessageToErrorJson(nlohmann::json& target,
+ const nlohmann::json& message);
+} // namespace messages
+} // namespace redfish
diff --git a/redfish-core/include/error_messages.hpp b/redfish-core/include/error_messages.hpp
index d9a3bb3..3b700ae 100644
--- a/redfish-core/include/error_messages.hpp
+++ b/redfish-core/include/error_messages.hpp
@@ -25,14 +25,6 @@
namespace messages
{
-constexpr const char* messageVersionPrefix = "Base.1.19.0.";
-constexpr const char* messageAnnotation = "@Message.ExtendedInfo";
-
-/**
- * @brief Moves all error messages from the |source| JSON to |target|
- */
-void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source);
-
/**
* @brief Formats Success message into JSON
* Message body: "The request completed successfully."
diff --git a/redfish-core/include/utils/query_param.hpp b/redfish-core/include/utils/query_param.hpp
index a867338..b579190 100644
--- a/redfish-core/include/utils/query_param.hpp
+++ b/redfish-core/include/utils/query_param.hpp
@@ -5,6 +5,7 @@
#include "app.hpp"
#include "async_resp.hpp"
+#include "error_message_utils.hpp"
#include "error_messages.hpp"
#include "filter_expr_executor.hpp"
#include "filter_expr_printer.hpp"
diff --git a/redfish-core/src/error_message_utils.cpp b/redfish-core/src/error_message_utils.cpp
new file mode 100644
index 0000000..ae7829a
--- /dev/null
+++ b/redfish-core/src/error_message_utils.cpp
@@ -0,0 +1,124 @@
+#include "error_message_utils.hpp"
+
+#include "logging.hpp"
+
+#include <nlohmann/json.hpp>
+
+#include <string>
+#include <string_view>
+
+namespace redfish
+{
+
+namespace messages
+{
+
+void addMessageToErrorJson(nlohmann::json& target,
+ const nlohmann::json& message)
+{
+ auto& error = target["error"];
+
+ // If this is the first error message, fill in the information from the
+ // first error message to the top level struct
+ if (!error.is_object())
+ {
+ auto messageIdIterator = message.find("MessageId");
+ if (messageIdIterator == message.end())
+ {
+ BMCWEB_LOG_CRITICAL(
+ "Attempt to add error message without MessageId");
+ return;
+ }
+
+ auto messageFieldIterator = message.find("Message");
+ if (messageFieldIterator == message.end())
+ {
+ BMCWEB_LOG_CRITICAL("Attempt to add error message without Message");
+ return;
+ }
+ error["code"] = *messageIdIterator;
+ error["message"] = *messageFieldIterator;
+ }
+ else
+ {
+ // More than 1 error occurred, so the message has to be generic
+ error["code"] = std::string(messageVersionPrefix) + "GeneralError";
+ error["message"] = "A general error has occurred. See Resolution for "
+ "information on how to resolve the error.";
+ }
+
+ // This check could technically be done in the default construction
+ // branch above, but because we need the pointer to the extended info field
+ // anyway, it's more efficient to do it here.
+ auto& extendedInfo = error[messages::messageAnnotation];
+ if (!extendedInfo.is_array())
+ {
+ extendedInfo = nlohmann::json::array();
+ }
+
+ extendedInfo.push_back(message);
+}
+
+void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source)
+{
+ if (!source.is_object())
+ {
+ return;
+ }
+ auto errorIt = source.find("error");
+ if (errorIt == source.end())
+ {
+ // caller puts error message in root
+ messages::addMessageToErrorJson(target, source);
+ source.clear();
+ return;
+ }
+ auto extendedInfoIt = errorIt->find(messages::messageAnnotation);
+ if (extendedInfoIt == errorIt->end())
+ {
+ return;
+ }
+ const nlohmann::json::array_t* extendedInfo =
+ (*extendedInfoIt).get_ptr<const nlohmann::json::array_t*>();
+ if (extendedInfo == nullptr)
+ {
+ source.erase(errorIt);
+ return;
+ }
+ for (const nlohmann::json& message : *extendedInfo)
+ {
+ addMessageToErrorJson(target, message);
+ }
+ source.erase(errorIt);
+}
+
+void addMessageToJsonRoot(nlohmann::json& target, const nlohmann::json& message)
+{
+ if (!target[messages::messageAnnotation].is_array())
+ {
+ // Force object to be an array
+ target[messages::messageAnnotation] = nlohmann::json::array();
+ }
+
+ target[messages::messageAnnotation].push_back(message);
+}
+
+void addMessageToJson(nlohmann::json& target, const nlohmann::json& message,
+ std::string_view fieldPath)
+{
+ std::string extendedInfo(fieldPath);
+ extendedInfo += messages::messageAnnotation;
+
+ nlohmann::json& field = target[extendedInfo];
+ if (!field.is_array())
+ {
+ // Force object to be an array
+ field = nlohmann::json::array();
+ }
+
+ // Object exists and it is an array so we can just push in the message
+ field.push_back(message);
+}
+
+} // namespace messages
+} // namespace redfish
diff --git a/redfish-core/src/error_messages.cpp b/redfish-core/src/error_messages.cpp
index 4e2ede8..5325849 100644
--- a/redfish-core/src/error_messages.cpp
+++ b/redfish-core/src/error_messages.cpp
@@ -10,6 +10,7 @@
***************************************************************/
#include "error_messages.hpp"
+#include "error_message_utils.hpp"
#include "http_response.hpp"
#include "logging.hpp"
#include "registries.hpp"
@@ -39,115 +40,6 @@
namespace messages
{
-static void addMessageToErrorJson(nlohmann::json& target,
- const nlohmann::json& message)
-{
- auto& error = target["error"];
-
- // If this is the first error message, fill in the information from the
- // first error message to the top level struct
- if (!error.is_object())
- {
- auto messageIdIterator = message.find("MessageId");
- if (messageIdIterator == message.end())
- {
- BMCWEB_LOG_CRITICAL(
- "Attempt to add error message without MessageId");
- return;
- }
-
- auto messageFieldIterator = message.find("Message");
- if (messageFieldIterator == message.end())
- {
- BMCWEB_LOG_CRITICAL("Attempt to add error message without Message");
- return;
- }
- error["code"] = *messageIdIterator;
- error["message"] = *messageFieldIterator;
- }
- else
- {
- // More than 1 error occurred, so the message has to be generic
- error["code"] = std::string(messageVersionPrefix) + "GeneralError";
- error["message"] = "A general error has occurred. See Resolution for "
- "information on how to resolve the error.";
- }
-
- // This check could technically be done in the default construction
- // branch above, but because we need the pointer to the extended info field
- // anyway, it's more efficient to do it here.
- auto& extendedInfo = error[messages::messageAnnotation];
- if (!extendedInfo.is_array())
- {
- extendedInfo = nlohmann::json::array();
- }
-
- extendedInfo.push_back(message);
-}
-
-void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source)
-{
- if (!source.is_object())
- {
- return;
- }
- auto errorIt = source.find("error");
- if (errorIt == source.end())
- {
- // caller puts error message in root
- messages::addMessageToErrorJson(target, source);
- source.clear();
- return;
- }
- auto extendedInfoIt = errorIt->find(messages::messageAnnotation);
- if (extendedInfoIt == errorIt->end())
- {
- return;
- }
- const nlohmann::json::array_t* extendedInfo =
- (*extendedInfoIt).get_ptr<const nlohmann::json::array_t*>();
- if (extendedInfo == nullptr)
- {
- source.erase(errorIt);
- return;
- }
- for (const nlohmann::json& message : *extendedInfo)
- {
- addMessageToErrorJson(target, message);
- }
- source.erase(errorIt);
-}
-
-static void addMessageToJsonRoot(nlohmann::json& target,
- const nlohmann::json& message)
-{
- if (!target[messages::messageAnnotation].is_array())
- {
- // Force object to be an array
- target[messages::messageAnnotation] = nlohmann::json::array();
- }
-
- target[messages::messageAnnotation].push_back(message);
-}
-
-static void addMessageToJson(nlohmann::json& target,
- const nlohmann::json& message,
- std::string_view fieldPath)
-{
- std::string extendedInfo(fieldPath);
- extendedInfo += messages::messageAnnotation;
-
- nlohmann::json& field = target[extendedInfo];
- if (!field.is_array())
- {
- // Force object to be an array
- field = nlohmann::json::array();
- }
-
- // Object exists and it is an array so we can just push in the message
- field.push_back(message);
-}
-
static nlohmann::json getLog(redfish::registries::base::Index name,
std::span<const std::string_view> args)
{
diff --git a/scripts/parse_registries.py b/scripts/parse_registries.py
index e172923..0e566aa 100755
--- a/scripts/parse_registries.py
+++ b/scripts/parse_registries.py
@@ -434,21 +434,6 @@
{
"""
)
- if registry_name == "Base":
- out.write(
- f'constexpr const char* messageVersionPrefix = "{registry_name}.{registry_version}.";'
- )
- out.write(
- """
- constexpr const char* messageAnnotation = "@Message.ExtendedInfo";
-
- /**
- * @brief Moves all error messages from the |source| JSON to |target|
- */
- void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source);
-
- """
- )
for entry_id, entry in messages.items():
message = entry["Message"]
for index in range(1, 10):
@@ -494,6 +479,7 @@
headers.append('"registries.hpp"')
if registry_name == "Base":
reg_name_lower = "base"
+ headers.append('"error_message_utils.hpp"')
headers.append('"http_response.hpp"')
headers.append('"logging.hpp"')
headers.append("<boost/beast/http/field.hpp>")
@@ -531,120 +517,6 @@
{
"""
)
-
- if registry_name == "Base":
- out.write(
- """
-static void addMessageToErrorJson(nlohmann::json& target,
- const nlohmann::json& message)
-{
- auto& error = target["error"];
-
- // If this is the first error message, fill in the information from the
- // first error message to the top level struct
- if (!error.is_object())
- {
- auto messageIdIterator = message.find("MessageId");
- if (messageIdIterator == message.end())
- {
- BMCWEB_LOG_CRITICAL(
- "Attempt to add error message without MessageId");
- return;
- }
-
- auto messageFieldIterator = message.find("Message");
- if (messageFieldIterator == message.end())
- {
- BMCWEB_LOG_CRITICAL("Attempt to add error message without Message");
- return;
- }
- error["code"] = *messageIdIterator;
- error["message"] = *messageFieldIterator;
- }
- else
- {
- // More than 1 error occurred, so the message has to be generic
- error["code"] = std::string(messageVersionPrefix) + "GeneralError";
- error["message"] = "A general error has occurred. See Resolution for "
- "information on how to resolve the error.";
- }
-
- // This check could technically be done in the default construction
- // branch above, but because we need the pointer to the extended info field
- // anyway, it's more efficient to do it here.
- auto& extendedInfo = error[messages::messageAnnotation];
- if (!extendedInfo.is_array())
- {
- extendedInfo = nlohmann::json::array();
- }
-
- extendedInfo.push_back(message);
-}
-
-void moveErrorsToErrorJson(nlohmann::json& target, nlohmann::json& source)
-{
- if (!source.is_object())
- {
- return;
- }
- auto errorIt = source.find("error");
- if (errorIt == source.end())
- {
- // caller puts error message in root
- messages::addMessageToErrorJson(target, source);
- source.clear();
- return;
- }
- auto extendedInfoIt = errorIt->find(messages::messageAnnotation);
- if (extendedInfoIt == errorIt->end())
- {
- return;
- }
- const nlohmann::json::array_t* extendedInfo =
- (*extendedInfoIt).get_ptr<const nlohmann::json::array_t*>();
- if (extendedInfo == nullptr)
- {
- source.erase(errorIt);
- return;
- }
- for (const nlohmann::json& message : *extendedInfo)
- {
- addMessageToErrorJson(target, message);
- }
- source.erase(errorIt);
-}
-
-static void addMessageToJsonRoot(nlohmann::json& target,
- const nlohmann::json& message)
-{
- if (!target[messages::messageAnnotation].is_array())
- {
- // Force object to be an array
- target[messages::messageAnnotation] = nlohmann::json::array();
- }
-
- target[messages::messageAnnotation].push_back(message);
-}
-
-static void addMessageToJson(nlohmann::json& target,
- const nlohmann::json& message,
- std::string_view fieldPath)
-{
- std::string extendedInfo(fieldPath);
- extendedInfo += messages::messageAnnotation;
-
- nlohmann::json& field = target[extendedInfo];
- if (!field.is_array())
- {
- // Force object to be an array
- field = nlohmann::json::array();
- }
-
- // Object exists and it is an array so we can just push in the message
- field.push_back(message);
-}
-"""
- )
out.write(
"""
static nlohmann::json getLog(redfish::registries::{namespace_name}::Index name,
diff --git a/test/redfish-core/include/utils/query_param_test.cpp b/test/redfish-core/include/utils/query_param_test.cpp
index d037bd8..d9025c0 100644
--- a/test/redfish-core/include/utils/query_param_test.cpp
+++ b/test/redfish-core/include/utils/query_param_test.cpp
@@ -2,7 +2,6 @@
// SPDX-FileCopyrightText: Copyright OpenBMC Authors
#include "bmcweb_config.h"
-#include "error_messages.hpp"
#include "http_response.hpp"
#include "utils/query_param.hpp"