xref: /openbmc/bmcweb/features/redfish/lib/message_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
570304cb5SJason M. Bills 
63ccb3adbSEd Tanous #include "app.hpp"
73ccb3adbSEd Tanous #include "query.hpp"
870304cb5SJason M. Bills #include "registries.hpp"
9f7a26073SMyung Bae #include "registries_selector.hpp"
1070304cb5SJason M. Bills 
11ef4c65b7SEd Tanous #include <boost/url/format.hpp>
12ef4c65b7SEd Tanous 
13613dabeaSEd Tanous #include <array>
1456b81992SEd Tanous #include <format>
15613dabeaSEd Tanous 
1670304cb5SJason M. Bills namespace redfish
1770304cb5SJason M. Bills {
1870304cb5SJason M. Bills 
19dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet(
2045ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
21104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
2270304cb5SJason M. Bills {
233ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
2445ca1b86SEd Tanous     {
2545ca1b86SEd Tanous         return;
2645ca1b86SEd Tanous     }
277e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
287e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
2914c8aee2SEd Tanous 
301476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
311476687dSEd Tanous         "#MessageRegistryFileCollection.MessageRegistryFileCollection";
321476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries";
331476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection";
341476687dSEd Tanous     asyncResp->res.jsonValue["Description"] =
351476687dSEd Tanous         "Collection of MessageRegistryFiles";
36613dabeaSEd Tanous 
37613dabeaSEd Tanous     nlohmann::json& members = asyncResp->res.jsonValue["Members"];
38fb546105SMyung Bae 
39fb546105SMyung Bae     static constexpr const auto registryFiles = std::to_array(
40fb546105SMyung Bae         {"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry",
41fb546105SMyung Bae          "HeartbeatEvent"});
42fb546105SMyung Bae 
43fb546105SMyung Bae     for (const char* memberName : registryFiles)
44613dabeaSEd Tanous     {
45613dabeaSEd Tanous         nlohmann::json::object_t member;
46bd79bce8SPatrick Williams         member["@odata.id"] =
47bd79bce8SPatrick Williams             boost::urls::format("/redfish/v1/Registries/{}", memberName);
48613dabeaSEd Tanous         members.emplace_back(std::move(member));
49613dabeaSEd Tanous     }
50fb546105SMyung Bae     asyncResp->res.jsonValue["Members@odata.count"] = members.size();
5170304cb5SJason M. Bills }
5270304cb5SJason M. Bills 
53dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app)
5470304cb5SJason M. Bills {
55dff07827SJohn Edward Broadbent     /**
56dff07827SJohn Edward Broadbent      * Functions triggers appropriate requests on DBus
57dff07827SJohn Edward Broadbent      */
58dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
59dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFileCollection)
6045ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
6145ca1b86SEd Tanous             handleMessageRegistryFileCollectionGet, std::ref(app)));
62dff07827SJohn Edward Broadbent }
63dff07827SJohn Edward Broadbent 
64dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet(
6545ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
66104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
67dff07827SJohn Edward Broadbent     const std::string& registry)
68dff07827SJohn Edward Broadbent {
693ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
7045ca1b86SEd Tanous     {
7145ca1b86SEd Tanous         return;
7245ca1b86SEd Tanous     }
73e51c710eSJames Feist     std::string dmtf = "DMTF ";
74f7a26073SMyung Bae     std::optional<registries::HeaderAndUrl> headerAndUrl =
75f7a26073SMyung Bae         registries::getRegistryHeaderAndUrlFromPrefix(registry);
76e51c710eSJames Feist 
77f7a26073SMyung Bae     if (!headerAndUrl)
78e51c710eSJames Feist     {
79d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
807e860f15SJohn Edward Broadbent                                    registry);
81e51c710eSJames Feist         return;
82e51c710eSJames Feist     }
83f7a26073SMyung Bae     if (registry == "OpenBMC")
84f7a26073SMyung Bae     {
85f7a26073SMyung Bae         dmtf.clear();
86f7a26073SMyung Bae     }
87f7a26073SMyung Bae     const registries::Header& header = headerAndUrl->header;
88f7a26073SMyung Bae     const char* url = headerAndUrl->url;
89e51c710eSJames Feist 
901476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
91ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/Registries/{}", registry);
921476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
931476687dSEd Tanous         "#MessageRegistryFile.v1_1_0.MessageRegistryFile";
941476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
95bd79bce8SPatrick Williams     asyncResp->res.jsonValue["Description"] =
96bd79bce8SPatrick Williams         dmtf + registry + " Message Registry File Location";
97f7a26073SMyung Bae     asyncResp->res.jsonValue["Id"] = header.registryPrefix;
9856b81992SEd Tanous     asyncResp->res.jsonValue["Registry"] =
9956b81992SEd Tanous         std::format("{}.{}.{}", header.registryPrefix, header.versionMajor,
10056b81992SEd Tanous                     header.versionMinor);
101613dabeaSEd Tanous     nlohmann::json::array_t languages;
102f7a26073SMyung Bae     languages.emplace_back(header.language);
103613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages@odata.count"] = languages.size();
104613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages"] = std::move(languages);
105613dabeaSEd Tanous     nlohmann::json::array_t locationMembers;
106613dabeaSEd Tanous     nlohmann::json::object_t location;
107f7a26073SMyung Bae     location["Language"] = header.language;
108613dabeaSEd Tanous     location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry;
109e51c710eSJames Feist 
110e51c710eSJames Feist     if (url != nullptr)
111e51c710eSJames Feist     {
112613dabeaSEd Tanous         location["PublicationUri"] = url;
113e51c710eSJames Feist     }
114613dabeaSEd Tanous     locationMembers.emplace_back(std::move(location));
115613dabeaSEd Tanous     asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size();
116613dabeaSEd Tanous     asyncResp->res.jsonValue["Location"] = std::move(locationMembers);
11770304cb5SJason M. Bills }
11870304cb5SJason M. Bills 
119dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app)
12070304cb5SJason M. Bills {
121dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
122ed398213SEd Tanous         .privileges(redfish::privileges::getMessageRegistryFile)
12345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
12445ca1b86SEd Tanous             handleMessageRoutesMessageRegistryFileGet, std::ref(app)));
125dff07827SJohn Edward Broadbent }
126dff07827SJohn Edward Broadbent 
127dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet(
12845ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
129104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1306e8c18f0SJohn Edward Broadbent     const std::string& registry, const std::string& registryMatch)
1317e860f15SJohn Edward Broadbent 
132e51c710eSJames Feist {
1333ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
13445ca1b86SEd Tanous     {
13545ca1b86SEd Tanous         return;
13645ca1b86SEd Tanous     }
137f7a26073SMyung Bae 
138f7a26073SMyung Bae     std::optional<registries::HeaderAndUrl> headerAndUrl =
139f7a26073SMyung Bae         registries::getRegistryHeaderAndUrlFromPrefix(registry);
140f7a26073SMyung Bae     if (!headerAndUrl)
141e51c710eSJames Feist     {
142d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
1437e860f15SJohn Edward Broadbent                                    registry);
144e51c710eSJames Feist         return;
145e51c710eSJames Feist     }
146e51c710eSJames Feist 
147f7a26073SMyung Bae     const registries::Header& header = headerAndUrl->header;
1486e8c18f0SJohn Edward Broadbent     if (registry != registryMatch)
149e51c710eSJames Feist     {
150f7a26073SMyung Bae         messages::resourceNotFound(asyncResp->res, header.type, registryMatch);
151e51c710eSJames Feist         return;
152e51c710eSJames Feist     }
153e51c710eSJames Feist 
154f7a26073SMyung Bae     asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright;
155f7a26073SMyung Bae     asyncResp->res.jsonValue["@odata.type"] = header.type;
15656b81992SEd Tanous     asyncResp->res.jsonValue["Id"] =
15756b81992SEd Tanous         std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor,
15856b81992SEd Tanous                     header.versionMinor, header.versionPatch);
159f7a26073SMyung Bae     asyncResp->res.jsonValue["Name"] = header.name;
160f7a26073SMyung Bae     asyncResp->res.jsonValue["Language"] = header.language;
161f7a26073SMyung Bae     asyncResp->res.jsonValue["Description"] = header.description;
162f7a26073SMyung Bae     asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix;
16356b81992SEd Tanous     asyncResp->res.jsonValue["RegistryVersion"] =
16456b81992SEd Tanous         std::format("{}.{}.{}", header.versionMajor, header.versionMinor,
16556b81992SEd Tanous                     header.versionPatch);
166f7a26073SMyung Bae     asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity;
16770304cb5SJason M. Bills 
168dff07827SJohn Edward Broadbent     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
16970304cb5SJason M. Bills 
17070304cb5SJason M. Bills     // Go through the Message Registry and populate each Message
171f7a26073SMyung Bae     const std::span<const registries::MessageEntry> registryEntries =
172f7a26073SMyung Bae         registries::getRegistryFromPrefix(registry);
173f7a26073SMyung Bae 
174f7a26073SMyung Bae     for (const registries::MessageEntry& message : registryEntries)
17570304cb5SJason M. Bills     {
176f7a26073SMyung Bae         nlohmann::json& obj = messageObj[message.first];
177f7a26073SMyung Bae         obj["Description"] = message.second.description;
178f7a26073SMyung Bae         obj["Message"] = message.second.message;
179f7a26073SMyung Bae         obj["Severity"] = message.second.messageSeverity;
180f7a26073SMyung Bae         obj["MessageSeverity"] = message.second.messageSeverity;
181f7a26073SMyung Bae         obj["NumberOfArgs"] = message.second.numberOfArgs;
182f7a26073SMyung Bae         obj["Resolution"] = message.second.resolution;
183f7a26073SMyung Bae         if (message.second.numberOfArgs > 0)
18470304cb5SJason M. Bills         {
18514c8aee2SEd Tanous             nlohmann::json& messageParamArray = obj["ParamTypes"];
186938f2568SEd Tanous             messageParamArray = nlohmann::json::array();
187f7a26073SMyung Bae             for (const char* str : message.second.paramTypes)
18870304cb5SJason M. Bills             {
18970304cb5SJason M. Bills                 if (str == nullptr)
19070304cb5SJason M. Bills                 {
19170304cb5SJason M. Bills                     break;
19270304cb5SJason M. Bills                 }
19370304cb5SJason M. Bills                 messageParamArray.push_back(str);
19470304cb5SJason M. Bills             }
19570304cb5SJason M. Bills         }
19670304cb5SJason M. Bills     }
19770304cb5SJason M. Bills }
19870304cb5SJason M. Bills 
199dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app)
200dff07827SJohn Edward Broadbent {
201dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
202dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFile)
20345ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
20445ca1b86SEd Tanous             std::bind_front(handleMessageRegistryGet, std::ref(app)));
205dff07827SJohn Edward Broadbent }
20670304cb5SJason M. Bills } // namespace redfish
207