xref: /openbmc/bmcweb/redfish-core/include/registries.hpp (revision 478b7adffab38c98d880ad2c39c8dc421433bd92)
1 /*
2 // Copyright (c) 2019 Intel Corporation
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 */
16 #pragma once
17 
18 #include <nlohmann/json.hpp>
19 
20 #include <array>
21 #include <charconv>
22 #include <cstddef>
23 #include <numeric>
24 #include <span>
25 #include <string>
26 #include <string_view>
27 #include <utility>
28 
29 namespace redfish::registries
30 {
31 struct Header
32 {
33     const char* copyright;
34     const char* type;
35     const char* id;
36     const char* name;
37     const char* language;
38     const char* description;
39     const char* registryPrefix;
40     const char* registryVersion;
41     const char* owningEntity;
42 };
43 
44 struct Message
45 {
46     const char* description;
47     const char* message;
48     const char* messageSeverity;
49     const size_t numberOfArgs;
50     std::array<const char*, 5> paramTypes;
51     const char* resolution;
52 };
53 using MessageEntry = std::pair<const char*, const Message>;
54 
55 inline std::string fillMessageArgs(
56     const std::span<const std::string_view> messageArgs, std::string_view msg)
57 {
58     std::string ret;
59     size_t reserve = msg.size();
60     for (std::string_view arg : messageArgs)
61     {
62         reserve += arg.size();
63     }
64     ret.reserve(reserve);
65 
66     for (size_t stringIndex = msg.find('%'); stringIndex != std::string::npos;
67          stringIndex = msg.find('%'))
68     {
69         ret += msg.substr(0, stringIndex);
70         msg.remove_prefix(stringIndex + 1);
71         size_t number = 0;
72         auto it = std::from_chars(msg.data(), &*msg.end(), number);
73         if (it.ec != std::errc())
74         {
75             return "";
76         }
77         msg.remove_prefix(1);
78         // Redfish message args are 1 indexed.
79         number--;
80         if (number >= messageArgs.size())
81         {
82             return "";
83         }
84         ret += messageArgs[number];
85     }
86     ret += msg;
87     return ret;
88 }
89 
90 inline nlohmann::json::object_t getLogFromRegistry(
91     const Header& header, std::span<const MessageEntry> registry, size_t index,
92     std::span<const std::string_view> args)
93 {
94     const redfish::registries::MessageEntry& entry = registry[index];
95     // Intentionally make a copy of the string, so we can append in the
96     // parameters.
97     std::string msg =
98         redfish::registries::fillMessageArgs(args, entry.second.message);
99     nlohmann::json jArgs = nlohmann::json::array();
100     for (std::string_view arg : args)
101     {
102         jArgs.push_back(arg);
103     }
104     std::string msgId = header.id;
105     msgId += ".";
106     msgId += entry.first;
107 
108     nlohmann::json::object_t response;
109     response["@odata.type"] = "#Message.v1_1_1.Message";
110     response["MessageId"] = std::move(msgId);
111     response["Message"] = std::move(msg);
112     response["MessageArgs"] = std::move(jArgs);
113     response["MessageSeverity"] = entry.second.messageSeverity;
114     response["Resolution"] = entry.second.resolution;
115     return response;
116 }
117 
118 const Message* getMessage(std::string_view messageID);
119 
120 const Message* getMessageFromRegistry(const std::string& messageKey,
121                                       std::span<const MessageEntry> registry);
122 
123 } // namespace redfish::registries
124