170304cb5SJason M. Bills /*
26be832e2SEd Tanous Copyright (c) 2019 Intel Corporation
36be832e2SEd Tanous
46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License");
56be832e2SEd Tanous you may not use this file except in compliance with the License.
66be832e2SEd Tanous You may obtain a copy of the License at
76be832e2SEd Tanous
86be832e2SEd Tanous http://www.apache.org/licenses/LICENSE-2.0
96be832e2SEd Tanous
106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software
116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS,
126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136be832e2SEd Tanous See the License for the specific language governing permissions and
146be832e2SEd Tanous limitations under the License.
1570304cb5SJason M. Bills */
1670304cb5SJason M. Bills #pragma once
17c5ba4c27SEd Tanous
18*56b81992SEd Tanous #include "bmcweb_config.h"
19*56b81992SEd Tanous
2065e4f1f7SEd Tanous #include <nlohmann/json.hpp>
2165e4f1f7SEd Tanous
22d5c80ad9SNan Zhou #include <array>
2380f595e7SEd Tanous #include <charconv>
24d5c80ad9SNan Zhou #include <cstddef>
25*56b81992SEd Tanous #include <format>
2680f595e7SEd Tanous #include <numeric>
27c5ba4c27SEd Tanous #include <span>
28c5ba4c27SEd Tanous #include <string>
29c5ba4c27SEd Tanous #include <string_view>
30d5c80ad9SNan Zhou #include <utility>
31d5c80ad9SNan Zhou
32fffb8c1fSEd Tanous namespace redfish::registries
3370304cb5SJason M. Bills {
34351d3063SJason M. Bills struct Header
35351d3063SJason M. Bills {
36351d3063SJason M. Bills const char* copyright;
37351d3063SJason M. Bills const char* type;
38*56b81992SEd Tanous unsigned int versionMajor;
39*56b81992SEd Tanous unsigned int versionMinor;
40*56b81992SEd Tanous unsigned int versionPatch;
41351d3063SJason M. Bills const char* name;
42351d3063SJason M. Bills const char* language;
43351d3063SJason M. Bills const char* description;
44351d3063SJason M. Bills const char* registryPrefix;
45351d3063SJason M. Bills const char* owningEntity;
46351d3063SJason M. Bills };
4770304cb5SJason M. Bills
4870304cb5SJason M. Bills struct Message
4970304cb5SJason M. Bills {
5070304cb5SJason M. Bills const char* description;
5170304cb5SJason M. Bills const char* message;
52e7808c93SGunnar Mills const char* messageSeverity;
53271584abSEd Tanous const size_t numberOfArgs;
5470304cb5SJason M. Bills std::array<const char*, 5> paramTypes;
5570304cb5SJason M. Bills const char* resolution;
5670304cb5SJason M. Bills };
5770304cb5SJason M. Bills using MessageEntry = std::pair<const char*, const Message>;
58c5ba4c27SEd Tanous
fillMessageArgs(const std::span<const std::string_view> messageArgs,std::string_view msg)59bd79bce8SPatrick Williams inline std::string fillMessageArgs(
60bd79bce8SPatrick Williams const std::span<const std::string_view> messageArgs, std::string_view msg)
61c5ba4c27SEd Tanous {
6280f595e7SEd Tanous std::string ret;
6380f595e7SEd Tanous size_t reserve = msg.size();
6426ccae32SEd Tanous for (std::string_view arg : messageArgs)
65c5ba4c27SEd Tanous {
6680f595e7SEd Tanous reserve += arg.size();
67c5ba4c27SEd Tanous }
6880f595e7SEd Tanous ret.reserve(reserve);
6980f595e7SEd Tanous
7080f595e7SEd Tanous for (size_t stringIndex = msg.find('%'); stringIndex != std::string::npos;
7180f595e7SEd Tanous stringIndex = msg.find('%'))
7280f595e7SEd Tanous {
7380f595e7SEd Tanous ret += msg.substr(0, stringIndex);
7480f595e7SEd Tanous msg.remove_prefix(stringIndex + 1);
7580f595e7SEd Tanous size_t number = 0;
7680f595e7SEd Tanous auto it = std::from_chars(msg.data(), &*msg.end(), number);
7780f595e7SEd Tanous if (it.ec != std::errc())
7880f595e7SEd Tanous {
7980f595e7SEd Tanous return "";
80c5ba4c27SEd Tanous }
8180f595e7SEd Tanous msg.remove_prefix(1);
8280f595e7SEd Tanous // Redfish message args are 1 indexed.
8380f595e7SEd Tanous number--;
8480f595e7SEd Tanous if (number >= messageArgs.size())
8580f595e7SEd Tanous {
8680f595e7SEd Tanous return "";
8780f595e7SEd Tanous }
8880f595e7SEd Tanous ret += messageArgs[number];
8980f595e7SEd Tanous }
9080f595e7SEd Tanous ret += msg;
9180f595e7SEd Tanous return ret;
92c5ba4c27SEd Tanous }
93c5ba4c27SEd Tanous
getLogFromRegistry(const Header & header,std::span<const MessageEntry> registry,size_t index,std::span<const std::string_view> args)94bd79bce8SPatrick Williams inline nlohmann::json::object_t getLogFromRegistry(
95bd79bce8SPatrick Williams const Header& header, std::span<const MessageEntry> registry, size_t index,
9665e4f1f7SEd Tanous std::span<const std::string_view> args)
9765e4f1f7SEd Tanous {
9865e4f1f7SEd Tanous const redfish::registries::MessageEntry& entry = registry[index];
9965e4f1f7SEd Tanous // Intentionally make a copy of the string, so we can append in the
10065e4f1f7SEd Tanous // parameters.
1012e30bc2dSKrzysztof Grobelny std::string msg =
1022e30bc2dSKrzysztof Grobelny redfish::registries::fillMessageArgs(args, entry.second.message);
10365e4f1f7SEd Tanous nlohmann::json jArgs = nlohmann::json::array();
10426ccae32SEd Tanous for (std::string_view arg : args)
10565e4f1f7SEd Tanous {
10665e4f1f7SEd Tanous jArgs.push_back(arg);
10765e4f1f7SEd Tanous }
108*56b81992SEd Tanous std::string msgId;
109*56b81992SEd Tanous if (BMCWEB_REDFISH_USE_3_DIGIT_MESSAGEID)
110*56b81992SEd Tanous {
111*56b81992SEd Tanous msgId = std::format("{}.{}.{}.{}.{}", header.registryPrefix,
112*56b81992SEd Tanous header.versionMajor, header.versionMinor,
113*56b81992SEd Tanous header.versionPatch, entry.first);
114*56b81992SEd Tanous }
115*56b81992SEd Tanous else
116*56b81992SEd Tanous {
117*56b81992SEd Tanous msgId =
118*56b81992SEd Tanous std::format("{}.{}.{}.{}", header.registryPrefix,
119*56b81992SEd Tanous header.versionMajor, header.versionMinor, entry.first);
120*56b81992SEd Tanous }
12165e4f1f7SEd Tanous nlohmann::json::object_t response;
12265e4f1f7SEd Tanous response["@odata.type"] = "#Message.v1_1_1.Message";
12365e4f1f7SEd Tanous response["MessageId"] = std::move(msgId);
12465e4f1f7SEd Tanous response["Message"] = std::move(msg);
12565e4f1f7SEd Tanous response["MessageArgs"] = std::move(jArgs);
12665e4f1f7SEd Tanous response["MessageSeverity"] = entry.second.messageSeverity;
12765e4f1f7SEd Tanous response["Resolution"] = entry.second.resolution;
12865e4f1f7SEd Tanous return response;
12965e4f1f7SEd Tanous }
13065e4f1f7SEd Tanous
131d1d411f9SSui Chen const Message* getMessage(std::string_view messageID);
132d1d411f9SSui Chen
133d1d411f9SSui Chen const Message* getMessageFromRegistry(const std::string& messageKey,
134d1d411f9SSui Chen std::span<const MessageEntry> registry);
135d1d411f9SSui Chen
136fffb8c1fSEd Tanous } // namespace redfish::registries
137