170304cb5SJason M. Bills /* 270304cb5SJason M. Bills // Copyright (c) 2019 Intel Corporation 370304cb5SJason M. Bills // 470304cb5SJason M. Bills // Licensed under the Apache License, Version 2.0 (the "License"); 570304cb5SJason M. Bills // you may not use this file except in compliance with the License. 670304cb5SJason M. Bills // You may obtain a copy of the License at 770304cb5SJason M. Bills // 870304cb5SJason M. Bills // http://www.apache.org/licenses/LICENSE-2.0 970304cb5SJason M. Bills // 1070304cb5SJason M. Bills // Unless required by applicable law or agreed to in writing, software 1170304cb5SJason M. Bills // distributed under the License is distributed on an "AS IS" BASIS, 1270304cb5SJason M. Bills // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370304cb5SJason M. Bills // See the License for the specific language governing permissions and 1470304cb5SJason M. Bills // limitations under the License. 1570304cb5SJason M. Bills */ 1670304cb5SJason M. Bills #pragma once 17c5ba4c27SEd Tanous 1865e4f1f7SEd Tanous #include <nlohmann/json.hpp> 1965e4f1f7SEd Tanous 20d5c80ad9SNan Zhou #include <array> 2180f595e7SEd Tanous #include <charconv> 22d5c80ad9SNan Zhou #include <cstddef> 2380f595e7SEd Tanous #include <iostream> 2480f595e7SEd Tanous #include <numeric> 25c5ba4c27SEd Tanous #include <span> 26c5ba4c27SEd Tanous #include <string> 27c5ba4c27SEd Tanous #include <string_view> 28d5c80ad9SNan Zhou #include <utility> 29d5c80ad9SNan Zhou 30d5c80ad9SNan Zhou // IWYU pragma: no_include <stddef.h> 31c5ba4c27SEd Tanous 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; 38351d3063SJason M. Bills const char* id; 39351d3063SJason M. Bills const char* name; 40351d3063SJason M. Bills const char* language; 41351d3063SJason M. Bills const char* description; 42351d3063SJason M. Bills const char* registryPrefix; 43351d3063SJason M. Bills const char* registryVersion; 44351d3063SJason M. Bills const char* owningEntity; 45351d3063SJason M. Bills }; 4670304cb5SJason M. Bills 4770304cb5SJason M. Bills struct Message 4870304cb5SJason M. Bills { 4970304cb5SJason M. Bills const char* description; 5070304cb5SJason M. Bills const char* message; 51e7808c93SGunnar Mills const char* messageSeverity; 52271584abSEd Tanous const size_t numberOfArgs; 5370304cb5SJason M. Bills std::array<const char*, 5> paramTypes; 5470304cb5SJason M. Bills const char* resolution; 5570304cb5SJason M. Bills }; 5670304cb5SJason M. Bills using MessageEntry = std::pair<const char*, const Message>; 57c5ba4c27SEd Tanous 5880f595e7SEd Tanous inline std::string 5980f595e7SEd Tanous fillMessageArgs(const std::span<const std::string_view> messageArgs, 6080f595e7SEd Tanous std::string_view msg) 61c5ba4c27SEd Tanous { 6280f595e7SEd Tanous std::string ret; 6380f595e7SEd Tanous size_t reserve = msg.size(); 6480f595e7SEd Tanous for (const 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 9465e4f1f7SEd Tanous inline nlohmann::json::object_t 9565e4f1f7SEd Tanous getLogFromRegistry(const Header& header, 9665e4f1f7SEd Tanous std::span<const MessageEntry> registry, size_t index, 9765e4f1f7SEd Tanous std::span<const std::string_view> args) 9865e4f1f7SEd Tanous { 9965e4f1f7SEd Tanous const redfish::registries::MessageEntry& entry = registry[index]; 10065e4f1f7SEd Tanous // Intentionally make a copy of the string, so we can append in the 10165e4f1f7SEd Tanous // parameters. 102*2e30bc2dSKrzysztof Grobelny std::string msg = 103*2e30bc2dSKrzysztof Grobelny redfish::registries::fillMessageArgs(args, entry.second.message); 10465e4f1f7SEd Tanous nlohmann::json jArgs = nlohmann::json::array(); 10565e4f1f7SEd Tanous for (const std::string_view arg : args) 10665e4f1f7SEd Tanous { 10765e4f1f7SEd Tanous jArgs.push_back(arg); 10865e4f1f7SEd Tanous } 10965e4f1f7SEd Tanous std::string msgId = header.id; 11065e4f1f7SEd Tanous msgId += "."; 11165e4f1f7SEd Tanous msgId += entry.first; 11265e4f1f7SEd Tanous 11365e4f1f7SEd Tanous nlohmann::json::object_t response; 11465e4f1f7SEd Tanous response["@odata.type"] = "#Message.v1_1_1.Message"; 11565e4f1f7SEd Tanous response["MessageId"] = std::move(msgId); 11665e4f1f7SEd Tanous response["Message"] = std::move(msg); 11765e4f1f7SEd Tanous response["MessageArgs"] = std::move(jArgs); 11865e4f1f7SEd Tanous response["MessageSeverity"] = entry.second.messageSeverity; 11965e4f1f7SEd Tanous response["Resolution"] = entry.second.resolution; 12065e4f1f7SEd Tanous return response; 12165e4f1f7SEd Tanous } 12265e4f1f7SEd Tanous 123fffb8c1fSEd Tanous } // namespace redfish::registries 124