xref: /openbmc/bmcweb/features/redfish/lib/message_registries.hpp (revision 4a102cd48c588d32c0a4d6610b4a9ed616f255f3)
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"
7d7857201SEd Tanous #include "async_resp.hpp"
8d7857201SEd Tanous #include "error_messages.hpp"
9d7857201SEd Tanous #include "http_request.hpp"
103ccb3adbSEd Tanous #include "query.hpp"
1170304cb5SJason M. Bills #include "registries.hpp"
12d7857201SEd Tanous #include "registries/privilege_registry.hpp"
1370304cb5SJason M. Bills 
14d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
15ef4c65b7SEd Tanous #include <boost/url/format.hpp>
16ef4c65b7SEd Tanous 
1756b81992SEd Tanous #include <format>
18d7857201SEd Tanous #include <functional>
19d7857201SEd Tanous #include <memory>
20d7857201SEd Tanous #include <optional>
21*4a102cd4SPatrick Williams #include <ranges>
22d7857201SEd Tanous #include <utility>
23613dabeaSEd Tanous 
2470304cb5SJason M. Bills namespace redfish
2570304cb5SJason M. Bills {
2670304cb5SJason M. Bills 
27dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet(
2845ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
29104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3070304cb5SJason M. Bills {
313ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3245ca1b86SEd Tanous     {
3345ca1b86SEd Tanous         return;
3445ca1b86SEd Tanous     }
357e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
367e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
3714c8aee2SEd Tanous 
381476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
391476687dSEd Tanous         "#MessageRegistryFileCollection.MessageRegistryFileCollection";
401476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries";
411476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection";
421476687dSEd Tanous     asyncResp->res.jsonValue["Description"] =
431476687dSEd Tanous         "Collection of MessageRegistryFiles";
44613dabeaSEd Tanous 
45613dabeaSEd Tanous     nlohmann::json& members = asyncResp->res.jsonValue["Members"];
46fb546105SMyung Bae 
47*4a102cd4SPatrick Williams     for (const auto& memberName : std::views::keys(registries::allRegistries()))
48613dabeaSEd Tanous     {
49613dabeaSEd Tanous         nlohmann::json::object_t member;
50bd79bce8SPatrick Williams         member["@odata.id"] =
51bd79bce8SPatrick Williams             boost::urls::format("/redfish/v1/Registries/{}", memberName);
52613dabeaSEd Tanous         members.emplace_back(std::move(member));
53613dabeaSEd Tanous     }
54fb546105SMyung Bae     asyncResp->res.jsonValue["Members@odata.count"] = members.size();
5570304cb5SJason M. Bills }
5670304cb5SJason M. Bills 
57dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app)
5870304cb5SJason M. Bills {
59dff07827SJohn Edward Broadbent     /**
60dff07827SJohn Edward Broadbent      * Functions triggers appropriate requests on DBus
61dff07827SJohn Edward Broadbent      */
62dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
63dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFileCollection)
6445ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
6545ca1b86SEd Tanous             handleMessageRegistryFileCollectionGet, std::ref(app)));
66dff07827SJohn Edward Broadbent }
67dff07827SJohn Edward Broadbent 
68dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet(
6945ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
70104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
71dff07827SJohn Edward Broadbent     const std::string& registry)
72dff07827SJohn Edward Broadbent {
733ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
7445ca1b86SEd Tanous     {
7545ca1b86SEd Tanous         return;
7645ca1b86SEd Tanous     }
77e51c710eSJames Feist     std::string dmtf = "DMTF ";
78*4a102cd4SPatrick Williams     std::optional<registries::RegistryEntryRef> registryEntry =
79*4a102cd4SPatrick Williams         registries::getRegistryFromPrefix(registry);
80e51c710eSJames Feist 
81*4a102cd4SPatrick Williams     if (!registryEntry)
82e51c710eSJames Feist     {
83d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
847e860f15SJohn Edward Broadbent                                    registry);
85e51c710eSJames Feist         return;
86e51c710eSJames Feist     }
87f7a26073SMyung Bae     if (registry == "OpenBMC")
88f7a26073SMyung Bae     {
89f7a26073SMyung Bae         dmtf.clear();
90f7a26073SMyung Bae     }
91*4a102cd4SPatrick Williams     const registries::Header& header = registryEntry->get().header;
92*4a102cd4SPatrick Williams     const char* url = registryEntry->get().url;
93e51c710eSJames Feist 
941476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
95ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/Registries/{}", registry);
961476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
971476687dSEd Tanous         "#MessageRegistryFile.v1_1_0.MessageRegistryFile";
981476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
99bd79bce8SPatrick Williams     asyncResp->res.jsonValue["Description"] =
100bd79bce8SPatrick Williams         dmtf + registry + " Message Registry File Location";
101f7a26073SMyung Bae     asyncResp->res.jsonValue["Id"] = header.registryPrefix;
10256b81992SEd Tanous     asyncResp->res.jsonValue["Registry"] =
10356b81992SEd Tanous         std::format("{}.{}.{}", header.registryPrefix, header.versionMajor,
10456b81992SEd Tanous                     header.versionMinor);
105613dabeaSEd Tanous     nlohmann::json::array_t languages;
106f7a26073SMyung Bae     languages.emplace_back(header.language);
107613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages@odata.count"] = languages.size();
108613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages"] = std::move(languages);
109613dabeaSEd Tanous     nlohmann::json::array_t locationMembers;
110613dabeaSEd Tanous     nlohmann::json::object_t location;
111f7a26073SMyung Bae     location["Language"] = header.language;
112613dabeaSEd Tanous     location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry;
113e51c710eSJames Feist 
114e51c710eSJames Feist     if (url != nullptr)
115e51c710eSJames Feist     {
116613dabeaSEd Tanous         location["PublicationUri"] = url;
117e51c710eSJames Feist     }
118613dabeaSEd Tanous     locationMembers.emplace_back(std::move(location));
119613dabeaSEd Tanous     asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size();
120613dabeaSEd Tanous     asyncResp->res.jsonValue["Location"] = std::move(locationMembers);
12170304cb5SJason M. Bills }
12270304cb5SJason M. Bills 
123dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app)
12470304cb5SJason M. Bills {
125dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
126ed398213SEd Tanous         .privileges(redfish::privileges::getMessageRegistryFile)
12745ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
12845ca1b86SEd Tanous             handleMessageRoutesMessageRegistryFileGet, std::ref(app)));
129dff07827SJohn Edward Broadbent }
130dff07827SJohn Edward Broadbent 
131dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet(
13245ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
133104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1346e8c18f0SJohn Edward Broadbent     const std::string& registry, const std::string& registryMatch)
1357e860f15SJohn Edward Broadbent 
136e51c710eSJames Feist {
1373ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
13845ca1b86SEd Tanous     {
13945ca1b86SEd Tanous         return;
14045ca1b86SEd Tanous     }
141f7a26073SMyung Bae 
142*4a102cd4SPatrick Williams     std::optional<registries::RegistryEntryRef> registryEntry =
143*4a102cd4SPatrick Williams         registries::getRegistryFromPrefix(registry);
144*4a102cd4SPatrick Williams     if (!registryEntry)
145e51c710eSJames Feist     {
146d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
1477e860f15SJohn Edward Broadbent                                    registry);
148e51c710eSJames Feist         return;
149e51c710eSJames Feist     }
150e51c710eSJames Feist 
151*4a102cd4SPatrick Williams     const registries::Header& header = registryEntry->get().header;
1526e8c18f0SJohn Edward Broadbent     if (registry != registryMatch)
153e51c710eSJames Feist     {
154f7a26073SMyung Bae         messages::resourceNotFound(asyncResp->res, header.type, registryMatch);
155e51c710eSJames Feist         return;
156e51c710eSJames Feist     }
157e51c710eSJames Feist 
158f7a26073SMyung Bae     asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright;
159f7a26073SMyung Bae     asyncResp->res.jsonValue["@odata.type"] = header.type;
16056b81992SEd Tanous     asyncResp->res.jsonValue["Id"] =
16156b81992SEd Tanous         std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor,
16256b81992SEd Tanous                     header.versionMinor, header.versionPatch);
163f7a26073SMyung Bae     asyncResp->res.jsonValue["Name"] = header.name;
164f7a26073SMyung Bae     asyncResp->res.jsonValue["Language"] = header.language;
165f7a26073SMyung Bae     asyncResp->res.jsonValue["Description"] = header.description;
166f7a26073SMyung Bae     asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix;
16756b81992SEd Tanous     asyncResp->res.jsonValue["RegistryVersion"] =
16856b81992SEd Tanous         std::format("{}.{}.{}", header.versionMajor, header.versionMinor,
16956b81992SEd Tanous                     header.versionPatch);
170f7a26073SMyung Bae     asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity;
17170304cb5SJason M. Bills 
172dff07827SJohn Edward Broadbent     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
17370304cb5SJason M. Bills 
17470304cb5SJason M. Bills     // Go through the Message Registry and populate each Message
175*4a102cd4SPatrick Williams     const registries::MessageEntries registryEntries =
176*4a102cd4SPatrick Williams         registries::getRegistryMessagesFromPrefix(registry);
177f7a26073SMyung Bae 
178f7a26073SMyung Bae     for (const registries::MessageEntry& message : registryEntries)
17970304cb5SJason M. Bills     {
180f7a26073SMyung Bae         nlohmann::json& obj = messageObj[message.first];
181f7a26073SMyung Bae         obj["Description"] = message.second.description;
182f7a26073SMyung Bae         obj["Message"] = message.second.message;
183f7a26073SMyung Bae         obj["Severity"] = message.second.messageSeverity;
184f7a26073SMyung Bae         obj["MessageSeverity"] = message.second.messageSeverity;
185f7a26073SMyung Bae         obj["NumberOfArgs"] = message.second.numberOfArgs;
186f7a26073SMyung Bae         obj["Resolution"] = message.second.resolution;
187f7a26073SMyung Bae         if (message.second.numberOfArgs > 0)
18870304cb5SJason M. Bills         {
18914c8aee2SEd Tanous             nlohmann::json& messageParamArray = obj["ParamTypes"];
190938f2568SEd Tanous             messageParamArray = nlohmann::json::array();
191f7a26073SMyung Bae             for (const char* str : message.second.paramTypes)
19270304cb5SJason M. Bills             {
19370304cb5SJason M. Bills                 if (str == nullptr)
19470304cb5SJason M. Bills                 {
19570304cb5SJason M. Bills                     break;
19670304cb5SJason M. Bills                 }
19770304cb5SJason M. Bills                 messageParamArray.push_back(str);
19870304cb5SJason M. Bills             }
19970304cb5SJason M. Bills         }
20070304cb5SJason M. Bills     }
20170304cb5SJason M. Bills }
20270304cb5SJason M. Bills 
203dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app)
204dff07827SJohn Edward Broadbent {
205dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
206dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFile)
20745ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
20845ca1b86SEd Tanous             std::bind_front(handleMessageRegistryGet, std::ref(app)));
209dff07827SJohn Edward Broadbent }
21070304cb5SJason M. Bills } // namespace redfish
211