xref: /openbmc/bmcweb/features/redfish/include/registries.hpp (revision 7da633f00b5d1499e53f43a5f0c7ea106f4dd5ee)
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 
1856b81992SEd Tanous #include "bmcweb_config.h"
1956b81992SEd Tanous 
2065e4f1f7SEd Tanous #include <nlohmann/json.hpp>
2165e4f1f7SEd Tanous 
22d5c80ad9SNan Zhou #include <array>
2380f595e7SEd Tanous #include <charconv>
24d5c80ad9SNan Zhou #include <cstddef>
2556b81992SEd 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;
3856b81992SEd Tanous     unsigned int versionMajor;
3956b81992SEd Tanous     unsigned int versionMinor;
4056b81992SEd 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 
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;
76*7da633f0SEd Tanous         auto it = std::from_chars(&*msg.begin(), &*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 
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     }
10856b81992SEd Tanous     std::string msgId;
10956b81992SEd Tanous     if (BMCWEB_REDFISH_USE_3_DIGIT_MESSAGEID)
11056b81992SEd Tanous     {
11156b81992SEd Tanous         msgId = std::format("{}.{}.{}.{}.{}", header.registryPrefix,
11256b81992SEd Tanous                             header.versionMajor, header.versionMinor,
11356b81992SEd Tanous                             header.versionPatch, entry.first);
11456b81992SEd Tanous     }
11556b81992SEd Tanous     else
11656b81992SEd Tanous     {
11756b81992SEd Tanous         msgId =
11856b81992SEd Tanous             std::format("{}.{}.{}.{}", header.registryPrefix,
11956b81992SEd Tanous                         header.versionMajor, header.versionMinor, entry.first);
12056b81992SEd 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