xref: /openbmc/bmcweb/features/redfish/lib/message_registries.hpp (revision d78572018fc2022091ff8b8eb5a7fef2172ba3d6)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
340e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright 2019 Intel Corporation
470304cb5SJason M. Bills #pragma once
570304cb5SJason M. Bills 
63ccb3adbSEd Tanous #include "app.hpp"
7*d7857201SEd Tanous #include "async_resp.hpp"
8*d7857201SEd Tanous #include "error_messages.hpp"
9*d7857201SEd Tanous #include "http_request.hpp"
103ccb3adbSEd Tanous #include "query.hpp"
1170304cb5SJason M. Bills #include "registries.hpp"
12*d7857201SEd Tanous #include "registries/privilege_registry.hpp"
13f7a26073SMyung Bae #include "registries_selector.hpp"
1470304cb5SJason M. Bills 
15*d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
16ef4c65b7SEd Tanous #include <boost/url/format.hpp>
17ef4c65b7SEd Tanous 
18613dabeaSEd Tanous #include <array>
1956b81992SEd Tanous #include <format>
20*d7857201SEd Tanous #include <functional>
21*d7857201SEd Tanous #include <memory>
22*d7857201SEd Tanous #include <optional>
23*d7857201SEd Tanous #include <span>
24*d7857201SEd Tanous #include <utility>
25613dabeaSEd Tanous 
2670304cb5SJason M. Bills namespace redfish
2770304cb5SJason M. Bills {
2870304cb5SJason M. Bills 
29dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet(
3045ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
31104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3270304cb5SJason M. Bills {
333ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3445ca1b86SEd Tanous     {
3545ca1b86SEd Tanous         return;
3645ca1b86SEd Tanous     }
377e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
387e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
3914c8aee2SEd Tanous 
401476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
411476687dSEd Tanous         "#MessageRegistryFileCollection.MessageRegistryFileCollection";
421476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries";
431476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection";
441476687dSEd Tanous     asyncResp->res.jsonValue["Description"] =
451476687dSEd Tanous         "Collection of MessageRegistryFiles";
46613dabeaSEd Tanous 
47613dabeaSEd Tanous     nlohmann::json& members = asyncResp->res.jsonValue["Members"];
48fb546105SMyung Bae 
49fb546105SMyung Bae     static constexpr const auto registryFiles = std::to_array(
50fb546105SMyung Bae         {"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry",
51fb546105SMyung Bae          "HeartbeatEvent"});
52fb546105SMyung Bae 
53fb546105SMyung Bae     for (const char* memberName : registryFiles)
54613dabeaSEd Tanous     {
55613dabeaSEd Tanous         nlohmann::json::object_t member;
56bd79bce8SPatrick Williams         member["@odata.id"] =
57bd79bce8SPatrick Williams             boost::urls::format("/redfish/v1/Registries/{}", memberName);
58613dabeaSEd Tanous         members.emplace_back(std::move(member));
59613dabeaSEd Tanous     }
60fb546105SMyung Bae     asyncResp->res.jsonValue["Members@odata.count"] = members.size();
6170304cb5SJason M. Bills }
6270304cb5SJason M. Bills 
63dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app)
6470304cb5SJason M. Bills {
65dff07827SJohn Edward Broadbent     /**
66dff07827SJohn Edward Broadbent      * Functions triggers appropriate requests on DBus
67dff07827SJohn Edward Broadbent      */
68dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
69dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFileCollection)
7045ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
7145ca1b86SEd Tanous             handleMessageRegistryFileCollectionGet, std::ref(app)));
72dff07827SJohn Edward Broadbent }
73dff07827SJohn Edward Broadbent 
74dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet(
7545ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
76104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
77dff07827SJohn Edward Broadbent     const std::string& registry)
78dff07827SJohn Edward Broadbent {
793ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
8045ca1b86SEd Tanous     {
8145ca1b86SEd Tanous         return;
8245ca1b86SEd Tanous     }
83e51c710eSJames Feist     std::string dmtf = "DMTF ";
84f7a26073SMyung Bae     std::optional<registries::HeaderAndUrl> headerAndUrl =
85f7a26073SMyung Bae         registries::getRegistryHeaderAndUrlFromPrefix(registry);
86e51c710eSJames Feist 
87f7a26073SMyung Bae     if (!headerAndUrl)
88e51c710eSJames Feist     {
89d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
907e860f15SJohn Edward Broadbent                                    registry);
91e51c710eSJames Feist         return;
92e51c710eSJames Feist     }
93f7a26073SMyung Bae     if (registry == "OpenBMC")
94f7a26073SMyung Bae     {
95f7a26073SMyung Bae         dmtf.clear();
96f7a26073SMyung Bae     }
97f7a26073SMyung Bae     const registries::Header& header = headerAndUrl->header;
98f7a26073SMyung Bae     const char* url = headerAndUrl->url;
99e51c710eSJames Feist 
1001476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
101ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/Registries/{}", registry);
1021476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
1031476687dSEd Tanous         "#MessageRegistryFile.v1_1_0.MessageRegistryFile";
1041476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
105bd79bce8SPatrick Williams     asyncResp->res.jsonValue["Description"] =
106bd79bce8SPatrick Williams         dmtf + registry + " Message Registry File Location";
107f7a26073SMyung Bae     asyncResp->res.jsonValue["Id"] = header.registryPrefix;
10856b81992SEd Tanous     asyncResp->res.jsonValue["Registry"] =
10956b81992SEd Tanous         std::format("{}.{}.{}", header.registryPrefix, header.versionMajor,
11056b81992SEd Tanous                     header.versionMinor);
111613dabeaSEd Tanous     nlohmann::json::array_t languages;
112f7a26073SMyung Bae     languages.emplace_back(header.language);
113613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages@odata.count"] = languages.size();
114613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages"] = std::move(languages);
115613dabeaSEd Tanous     nlohmann::json::array_t locationMembers;
116613dabeaSEd Tanous     nlohmann::json::object_t location;
117f7a26073SMyung Bae     location["Language"] = header.language;
118613dabeaSEd Tanous     location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry;
119e51c710eSJames Feist 
120e51c710eSJames Feist     if (url != nullptr)
121e51c710eSJames Feist     {
122613dabeaSEd Tanous         location["PublicationUri"] = url;
123e51c710eSJames Feist     }
124613dabeaSEd Tanous     locationMembers.emplace_back(std::move(location));
125613dabeaSEd Tanous     asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size();
126613dabeaSEd Tanous     asyncResp->res.jsonValue["Location"] = std::move(locationMembers);
12770304cb5SJason M. Bills }
12870304cb5SJason M. Bills 
129dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app)
13070304cb5SJason M. Bills {
131dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
132ed398213SEd Tanous         .privileges(redfish::privileges::getMessageRegistryFile)
13345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
13445ca1b86SEd Tanous             handleMessageRoutesMessageRegistryFileGet, std::ref(app)));
135dff07827SJohn Edward Broadbent }
136dff07827SJohn Edward Broadbent 
137dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet(
13845ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
139104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1406e8c18f0SJohn Edward Broadbent     const std::string& registry, const std::string& registryMatch)
1417e860f15SJohn Edward Broadbent 
142e51c710eSJames Feist {
1433ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
14445ca1b86SEd Tanous     {
14545ca1b86SEd Tanous         return;
14645ca1b86SEd Tanous     }
147f7a26073SMyung Bae 
148f7a26073SMyung Bae     std::optional<registries::HeaderAndUrl> headerAndUrl =
149f7a26073SMyung Bae         registries::getRegistryHeaderAndUrlFromPrefix(registry);
150f7a26073SMyung Bae     if (!headerAndUrl)
151e51c710eSJames Feist     {
152d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
1537e860f15SJohn Edward Broadbent                                    registry);
154e51c710eSJames Feist         return;
155e51c710eSJames Feist     }
156e51c710eSJames Feist 
157f7a26073SMyung Bae     const registries::Header& header = headerAndUrl->header;
1586e8c18f0SJohn Edward Broadbent     if (registry != registryMatch)
159e51c710eSJames Feist     {
160f7a26073SMyung Bae         messages::resourceNotFound(asyncResp->res, header.type, registryMatch);
161e51c710eSJames Feist         return;
162e51c710eSJames Feist     }
163e51c710eSJames Feist 
164f7a26073SMyung Bae     asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright;
165f7a26073SMyung Bae     asyncResp->res.jsonValue["@odata.type"] = header.type;
16656b81992SEd Tanous     asyncResp->res.jsonValue["Id"] =
16756b81992SEd Tanous         std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor,
16856b81992SEd Tanous                     header.versionMinor, header.versionPatch);
169f7a26073SMyung Bae     asyncResp->res.jsonValue["Name"] = header.name;
170f7a26073SMyung Bae     asyncResp->res.jsonValue["Language"] = header.language;
171f7a26073SMyung Bae     asyncResp->res.jsonValue["Description"] = header.description;
172f7a26073SMyung Bae     asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix;
17356b81992SEd Tanous     asyncResp->res.jsonValue["RegistryVersion"] =
17456b81992SEd Tanous         std::format("{}.{}.{}", header.versionMajor, header.versionMinor,
17556b81992SEd Tanous                     header.versionPatch);
176f7a26073SMyung Bae     asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity;
17770304cb5SJason M. Bills 
178dff07827SJohn Edward Broadbent     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
17970304cb5SJason M. Bills 
18070304cb5SJason M. Bills     // Go through the Message Registry and populate each Message
181f7a26073SMyung Bae     const std::span<const registries::MessageEntry> registryEntries =
182f7a26073SMyung Bae         registries::getRegistryFromPrefix(registry);
183f7a26073SMyung Bae 
184f7a26073SMyung Bae     for (const registries::MessageEntry& message : registryEntries)
18570304cb5SJason M. Bills     {
186f7a26073SMyung Bae         nlohmann::json& obj = messageObj[message.first];
187f7a26073SMyung Bae         obj["Description"] = message.second.description;
188f7a26073SMyung Bae         obj["Message"] = message.second.message;
189f7a26073SMyung Bae         obj["Severity"] = message.second.messageSeverity;
190f7a26073SMyung Bae         obj["MessageSeverity"] = message.second.messageSeverity;
191f7a26073SMyung Bae         obj["NumberOfArgs"] = message.second.numberOfArgs;
192f7a26073SMyung Bae         obj["Resolution"] = message.second.resolution;
193f7a26073SMyung Bae         if (message.second.numberOfArgs > 0)
19470304cb5SJason M. Bills         {
19514c8aee2SEd Tanous             nlohmann::json& messageParamArray = obj["ParamTypes"];
196938f2568SEd Tanous             messageParamArray = nlohmann::json::array();
197f7a26073SMyung Bae             for (const char* str : message.second.paramTypes)
19870304cb5SJason M. Bills             {
19970304cb5SJason M. Bills                 if (str == nullptr)
20070304cb5SJason M. Bills                 {
20170304cb5SJason M. Bills                     break;
20270304cb5SJason M. Bills                 }
20370304cb5SJason M. Bills                 messageParamArray.push_back(str);
20470304cb5SJason M. Bills             }
20570304cb5SJason M. Bills         }
20670304cb5SJason M. Bills     }
20770304cb5SJason M. Bills }
20870304cb5SJason M. Bills 
209dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app)
210dff07827SJohn Edward Broadbent {
211dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
212dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFile)
21345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
21445ca1b86SEd Tanous             std::bind_front(handleMessageRegistryGet, std::ref(app)));
215dff07827SJohn Edward Broadbent }
21670304cb5SJason M. Bills } // namespace redfish
217