blob: 22d594eb14c455100ed02348d5d7e4820387acf5 [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2019 Intel Corporation
Jason M. Bills70304cb2019-03-27 12:03:59 -07004#pragma once
Ed Tanousc5ba4c22022-02-07 09:59:55 -08005
Ed Tanous56b81992024-12-02 10:36:37 -08006#include "bmcweb_config.h"
7
Ed Tanous65e4f1f2022-02-08 00:23:54 -08008#include <nlohmann/json.hpp>
9
Nan Zhoud5c80ad2022-07-11 01:16:31 +000010#include <array>
Ed Tanous80f595e2022-02-14 09:32:05 -080011#include <charconv>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000012#include <cstddef>
Ed Tanous56b81992024-12-02 10:36:37 -080013#include <format>
Patrick Williams4a102cd2025-02-27 14:52:54 -050014#include <functional>
15#include <map>
16#include <optional>
Ed Tanousc5ba4c22022-02-07 09:59:55 -080017#include <span>
18#include <string>
19#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080020#include <system_error>
Nan Zhoud5c80ad2022-07-11 01:16:31 +000021#include <utility>
22
Ed Tanousfffb8c12022-02-07 23:53:03 -080023namespace redfish::registries
Jason M. Bills70304cb2019-03-27 12:03:59 -070024{
Jason M. Bills351d3062019-03-27 12:58:21 -070025struct Header
26{
27 const char* copyright;
28 const char* type;
Ed Tanous56b81992024-12-02 10:36:37 -080029 unsigned int versionMajor;
30 unsigned int versionMinor;
31 unsigned int versionPatch;
Jason M. Bills351d3062019-03-27 12:58:21 -070032 const char* name;
33 const char* language;
34 const char* description;
35 const char* registryPrefix;
Jason M. Bills351d3062019-03-27 12:58:21 -070036 const char* owningEntity;
37};
Jason M. Bills70304cb2019-03-27 12:03:59 -070038
39struct Message
40{
41 const char* description;
42 const char* message;
Gunnar Millse7808c92020-07-08 21:17:44 -050043 const char* messageSeverity;
Ed Tanous271584a2019-07-09 16:24:22 -070044 const size_t numberOfArgs;
Jason M. Bills70304cb2019-03-27 12:03:59 -070045 std::array<const char*, 5> paramTypes;
46 const char* resolution;
47};
Thang Trand9495962025-10-16 07:07:30 +000048
49struct MessageId
50{
51 std::string registryName;
52 std::string majorVersion;
53 std::string minorVersion;
54 std::string messageKey;
55};
56
Jason M. Bills70304cb2019-03-27 12:03:59 -070057using MessageEntry = std::pair<const char*, const Message>;
Patrick Williams4a102cd2025-02-27 14:52:54 -050058using MessageEntries = std::span<const MessageEntry>;
59
60struct RegistryEntry
61{
62 const Header& header;
63 const char* url;
64 MessageEntries entries;
65};
66using RegistryEntryRef = std::reference_wrapper<RegistryEntry>;
67
68auto allRegistries() -> std::map<std::string, RegistryEntry>&;
69
70auto getRegistryFromPrefix(const std::string& registryName)
71 -> std::optional<RegistryEntryRef>;
72
73auto getRegistryMessagesFromPrefix(const std::string& registryName)
74 -> MessageEntries;
75
76template <typename T>
77void registerRegistry()
78{
79 allRegistries().emplace(T::header.registryPrefix,
80 RegistryEntry{T::header, T::url, T::registry});
81}
Ed Tanousc5ba4c22022-02-07 09:59:55 -080082
Patrick Williamsbd79bce2024-08-16 15:22:20 -040083inline std::string fillMessageArgs(
84 const std::span<const std::string_view> messageArgs, std::string_view msg)
Ed Tanousc5ba4c22022-02-07 09:59:55 -080085{
Ed Tanous80f595e2022-02-14 09:32:05 -080086 std::string ret;
87 size_t reserve = msg.size();
Ed Tanous26ccae32023-02-16 10:28:44 -080088 for (std::string_view arg : messageArgs)
Ed Tanousc5ba4c22022-02-07 09:59:55 -080089 {
Ed Tanous80f595e2022-02-14 09:32:05 -080090 reserve += arg.size();
Ed Tanousc5ba4c22022-02-07 09:59:55 -080091 }
Ed Tanous80f595e2022-02-14 09:32:05 -080092 ret.reserve(reserve);
93
94 for (size_t stringIndex = msg.find('%'); stringIndex != std::string::npos;
95 stringIndex = msg.find('%'))
96 {
97 ret += msg.substr(0, stringIndex);
98 msg.remove_prefix(stringIndex + 1);
99 size_t number = 0;
Ed Tanous7da633f2024-12-02 08:25:38 -0800100 auto it = std::from_chars(&*msg.begin(), &*msg.end(), number);
Ed Tanous80f595e2022-02-14 09:32:05 -0800101 if (it.ec != std::errc())
102 {
103 return "";
104 }
105 msg.remove_prefix(1);
106 // Redfish message args are 1 indexed.
107 number--;
108 if (number >= messageArgs.size())
109 {
110 return "";
111 }
112 ret += messageArgs[number];
113 }
114 ret += msg;
115 return ret;
Ed Tanousc5ba4c22022-02-07 09:59:55 -0800116}
117
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400118inline nlohmann::json::object_t getLogFromRegistry(
119 const Header& header, std::span<const MessageEntry> registry, size_t index,
120 std::span<const std::string_view> args)
Ed Tanous65e4f1f2022-02-08 00:23:54 -0800121{
122 const redfish::registries::MessageEntry& entry = registry[index];
123 // Intentionally make a copy of the string, so we can append in the
124 // parameters.
Krzysztof Grobelny2e30bc22022-09-09 10:13:41 +0200125 std::string msg =
126 redfish::registries::fillMessageArgs(args, entry.second.message);
Ed Tanous65e4f1f2022-02-08 00:23:54 -0800127 nlohmann::json jArgs = nlohmann::json::array();
Ed Tanous26ccae32023-02-16 10:28:44 -0800128 for (std::string_view arg : args)
Ed Tanous65e4f1f2022-02-08 00:23:54 -0800129 {
130 jArgs.push_back(arg);
131 }
Gunnar Mills019caea2025-11-07 13:33:05 -0600132 std::string msgId =
133 std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor,
134 header.versionMinor, entry.first);
Ed Tanous65e4f1f2022-02-08 00:23:54 -0800135 nlohmann::json::object_t response;
136 response["@odata.type"] = "#Message.v1_1_1.Message";
137 response["MessageId"] = std::move(msgId);
138 response["Message"] = std::move(msg);
139 response["MessageArgs"] = std::move(jArgs);
140 response["MessageSeverity"] = entry.second.messageSeverity;
141 response["Resolution"] = entry.second.resolution;
142 return response;
143}
144
Sui Chend1d411f2022-04-10 23:09:36 -0700145const Message* getMessage(std::string_view messageID);
146
147const Message* getMessageFromRegistry(const std::string& messageKey,
148 std::span<const MessageEntry> registry);
149
Thang Trand9495962025-10-16 07:07:30 +0000150std::optional<MessageId> getMessageComponents(std::string_view message);
151
Ed Tanousfffb8c12022-02-07 23:53:03 -0800152} // namespace redfish::registries