xref: /openbmc/bmcweb/redfish-core/include/registries.hpp (revision 56b81992ba8a8e644f2e75251a94df4f4d0d0880)
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