xref: /openbmc/bmcweb/features/redfish/include/registries.hpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2019 Intel Corporation
470304cb5SJason M. Bills #pragma once
5c5ba4c27SEd Tanous 
656b81992SEd Tanous #include "bmcweb_config.h"
756b81992SEd Tanous 
865e4f1f7SEd Tanous #include <nlohmann/json.hpp>
965e4f1f7SEd Tanous 
10d5c80ad9SNan Zhou #include <array>
1180f595e7SEd Tanous #include <charconv>
12d5c80ad9SNan Zhou #include <cstddef>
1356b81992SEd Tanous #include <format>
1480f595e7SEd Tanous #include <numeric>
15c5ba4c27SEd Tanous #include <span>
16c5ba4c27SEd Tanous #include <string>
17c5ba4c27SEd Tanous #include <string_view>
18d5c80ad9SNan Zhou #include <utility>
19d5c80ad9SNan Zhou 
20fffb8c1fSEd Tanous namespace redfish::registries
2170304cb5SJason M. Bills {
22351d3063SJason M. Bills struct Header
23351d3063SJason M. Bills {
24351d3063SJason M. Bills     const char* copyright;
25351d3063SJason M. Bills     const char* type;
2656b81992SEd Tanous     unsigned int versionMajor;
2756b81992SEd Tanous     unsigned int versionMinor;
2856b81992SEd Tanous     unsigned int versionPatch;
29351d3063SJason M. Bills     const char* name;
30351d3063SJason M. Bills     const char* language;
31351d3063SJason M. Bills     const char* description;
32351d3063SJason M. Bills     const char* registryPrefix;
33351d3063SJason M. Bills     const char* owningEntity;
34351d3063SJason M. Bills };
3570304cb5SJason M. Bills 
3670304cb5SJason M. Bills struct Message
3770304cb5SJason M. Bills {
3870304cb5SJason M. Bills     const char* description;
3970304cb5SJason M. Bills     const char* message;
40e7808c93SGunnar Mills     const char* messageSeverity;
41271584abSEd Tanous     const size_t numberOfArgs;
4270304cb5SJason M. Bills     std::array<const char*, 5> paramTypes;
4370304cb5SJason M. Bills     const char* resolution;
4470304cb5SJason M. Bills };
4570304cb5SJason M. Bills using MessageEntry = std::pair<const char*, const Message>;
46c5ba4c27SEd Tanous 
47bd79bce8SPatrick Williams inline std::string fillMessageArgs(
48bd79bce8SPatrick Williams     const std::span<const std::string_view> messageArgs, std::string_view msg)
49c5ba4c27SEd Tanous {
5080f595e7SEd Tanous     std::string ret;
5180f595e7SEd Tanous     size_t reserve = msg.size();
5226ccae32SEd Tanous     for (std::string_view arg : messageArgs)
53c5ba4c27SEd Tanous     {
5480f595e7SEd Tanous         reserve += arg.size();
55c5ba4c27SEd Tanous     }
5680f595e7SEd Tanous     ret.reserve(reserve);
5780f595e7SEd Tanous 
5880f595e7SEd Tanous     for (size_t stringIndex = msg.find('%'); stringIndex != std::string::npos;
5980f595e7SEd Tanous          stringIndex = msg.find('%'))
6080f595e7SEd Tanous     {
6180f595e7SEd Tanous         ret += msg.substr(0, stringIndex);
6280f595e7SEd Tanous         msg.remove_prefix(stringIndex + 1);
6380f595e7SEd Tanous         size_t number = 0;
647da633f0SEd Tanous         auto it = std::from_chars(&*msg.begin(), &*msg.end(), number);
6580f595e7SEd Tanous         if (it.ec != std::errc())
6680f595e7SEd Tanous         {
6780f595e7SEd Tanous             return "";
68c5ba4c27SEd Tanous         }
6980f595e7SEd Tanous         msg.remove_prefix(1);
7080f595e7SEd Tanous         // Redfish message args are 1 indexed.
7180f595e7SEd Tanous         number--;
7280f595e7SEd Tanous         if (number >= messageArgs.size())
7380f595e7SEd Tanous         {
7480f595e7SEd Tanous             return "";
7580f595e7SEd Tanous         }
7680f595e7SEd Tanous         ret += messageArgs[number];
7780f595e7SEd Tanous     }
7880f595e7SEd Tanous     ret += msg;
7980f595e7SEd Tanous     return ret;
80c5ba4c27SEd Tanous }
81c5ba4c27SEd Tanous 
82bd79bce8SPatrick Williams inline nlohmann::json::object_t getLogFromRegistry(
83bd79bce8SPatrick Williams     const Header& header, std::span<const MessageEntry> registry, size_t index,
8465e4f1f7SEd Tanous     std::span<const std::string_view> args)
8565e4f1f7SEd Tanous {
8665e4f1f7SEd Tanous     const redfish::registries::MessageEntry& entry = registry[index];
8765e4f1f7SEd Tanous     // Intentionally make a copy of the string, so we can append in the
8865e4f1f7SEd Tanous     // parameters.
892e30bc2dSKrzysztof Grobelny     std::string msg =
902e30bc2dSKrzysztof Grobelny         redfish::registries::fillMessageArgs(args, entry.second.message);
9165e4f1f7SEd Tanous     nlohmann::json jArgs = nlohmann::json::array();
9226ccae32SEd Tanous     for (std::string_view arg : args)
9365e4f1f7SEd Tanous     {
9465e4f1f7SEd Tanous         jArgs.push_back(arg);
9565e4f1f7SEd Tanous     }
9656b81992SEd Tanous     std::string msgId;
9756b81992SEd Tanous     if (BMCWEB_REDFISH_USE_3_DIGIT_MESSAGEID)
9856b81992SEd Tanous     {
9956b81992SEd Tanous         msgId = std::format("{}.{}.{}.{}.{}", header.registryPrefix,
10056b81992SEd Tanous                             header.versionMajor, header.versionMinor,
10156b81992SEd Tanous                             header.versionPatch, entry.first);
10256b81992SEd Tanous     }
10356b81992SEd Tanous     else
10456b81992SEd Tanous     {
10556b81992SEd Tanous         msgId =
10656b81992SEd Tanous             std::format("{}.{}.{}.{}", header.registryPrefix,
10756b81992SEd Tanous                         header.versionMajor, header.versionMinor, entry.first);
10856b81992SEd Tanous     }
10965e4f1f7SEd Tanous     nlohmann::json::object_t response;
11065e4f1f7SEd Tanous     response["@odata.type"] = "#Message.v1_1_1.Message";
11165e4f1f7SEd Tanous     response["MessageId"] = std::move(msgId);
11265e4f1f7SEd Tanous     response["Message"] = std::move(msg);
11365e4f1f7SEd Tanous     response["MessageArgs"] = std::move(jArgs);
11465e4f1f7SEd Tanous     response["MessageSeverity"] = entry.second.messageSeverity;
11565e4f1f7SEd Tanous     response["Resolution"] = entry.second.resolution;
11665e4f1f7SEd Tanous     return response;
11765e4f1f7SEd Tanous }
11865e4f1f7SEd Tanous 
119d1d411f9SSui Chen const Message* getMessage(std::string_view messageID);
120d1d411f9SSui Chen 
121d1d411f9SSui Chen const Message* getMessageFromRegistry(const std::string& messageKey,
122d1d411f9SSui Chen                                       std::span<const MessageEntry> registry);
123d1d411f9SSui Chen 
124fffb8c1fSEd Tanous } // namespace redfish::registries
125