xref: /openbmc/bmcweb/features/redfish/lib/message_registries.hpp (revision 56b81992ba8a8e644f2e75251a94df4f4d0d0880)
170304cb5SJason M. Bills /*
26be832e2SEd Tanous Copyright (c) 2019 Intel Corporation
36be832e2SEd Tanous 
46be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License");
56be832e2SEd Tanous you may not use this file except in compliance with the License.
66be832e2SEd Tanous You may obtain a copy of the License at
76be832e2SEd Tanous 
86be832e2SEd Tanous       http://www.apache.org/licenses/LICENSE-2.0
96be832e2SEd Tanous 
106be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software
116be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS,
126be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136be832e2SEd Tanous See the License for the specific language governing permissions and
146be832e2SEd Tanous limitations under the License.
1570304cb5SJason M. Bills */
1670304cb5SJason M. Bills #pragma once
1770304cb5SJason M. Bills 
183ccb3adbSEd Tanous #include "app.hpp"
193ccb3adbSEd Tanous #include "query.hpp"
2070304cb5SJason M. Bills #include "registries.hpp"
21f7a26073SMyung Bae #include "registries_selector.hpp"
2270304cb5SJason M. Bills 
23ef4c65b7SEd Tanous #include <boost/url/format.hpp>
24ef4c65b7SEd Tanous 
25613dabeaSEd Tanous #include <array>
26*56b81992SEd Tanous #include <format>
27613dabeaSEd Tanous 
2870304cb5SJason M. Bills namespace redfish
2970304cb5SJason M. Bills {
3070304cb5SJason M. Bills 
31dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet(
3245ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
33104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3470304cb5SJason M. Bills {
353ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
3645ca1b86SEd Tanous     {
3745ca1b86SEd Tanous         return;
3845ca1b86SEd Tanous     }
397e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
407e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
4114c8aee2SEd Tanous 
421476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
431476687dSEd Tanous         "#MessageRegistryFileCollection.MessageRegistryFileCollection";
441476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries";
451476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection";
461476687dSEd Tanous     asyncResp->res.jsonValue["Description"] =
471476687dSEd Tanous         "Collection of MessageRegistryFiles";
48613dabeaSEd Tanous 
49613dabeaSEd Tanous     nlohmann::json& members = asyncResp->res.jsonValue["Members"];
50fb546105SMyung Bae 
51fb546105SMyung Bae     static constexpr const auto registryFiles = std::to_array(
52fb546105SMyung Bae         {"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry",
53fb546105SMyung Bae          "HeartbeatEvent"});
54fb546105SMyung Bae 
55fb546105SMyung Bae     for (const char* memberName : registryFiles)
56613dabeaSEd Tanous     {
57613dabeaSEd Tanous         nlohmann::json::object_t member;
58bd79bce8SPatrick Williams         member["@odata.id"] =
59bd79bce8SPatrick Williams             boost::urls::format("/redfish/v1/Registries/{}", memberName);
60613dabeaSEd Tanous         members.emplace_back(std::move(member));
61613dabeaSEd Tanous     }
62fb546105SMyung Bae     asyncResp->res.jsonValue["Members@odata.count"] = members.size();
6370304cb5SJason M. Bills }
6470304cb5SJason M. Bills 
65dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app)
6670304cb5SJason M. Bills {
67dff07827SJohn Edward Broadbent     /**
68dff07827SJohn Edward Broadbent      * Functions triggers appropriate requests on DBus
69dff07827SJohn Edward Broadbent      */
70dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
71dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFileCollection)
7245ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
7345ca1b86SEd Tanous             handleMessageRegistryFileCollectionGet, std::ref(app)));
74dff07827SJohn Edward Broadbent }
75dff07827SJohn Edward Broadbent 
76dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet(
7745ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
78104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
79dff07827SJohn Edward Broadbent     const std::string& registry)
80dff07827SJohn Edward Broadbent {
813ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
8245ca1b86SEd Tanous     {
8345ca1b86SEd Tanous         return;
8445ca1b86SEd Tanous     }
85e51c710eSJames Feist     std::string dmtf = "DMTF ";
86f7a26073SMyung Bae     std::optional<registries::HeaderAndUrl> headerAndUrl =
87f7a26073SMyung Bae         registries::getRegistryHeaderAndUrlFromPrefix(registry);
88e51c710eSJames Feist 
89f7a26073SMyung Bae     if (!headerAndUrl)
90e51c710eSJames Feist     {
91d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
927e860f15SJohn Edward Broadbent                                    registry);
93e51c710eSJames Feist         return;
94e51c710eSJames Feist     }
95f7a26073SMyung Bae     if (registry == "OpenBMC")
96f7a26073SMyung Bae     {
97f7a26073SMyung Bae         dmtf.clear();
98f7a26073SMyung Bae     }
99f7a26073SMyung Bae     const registries::Header& header = headerAndUrl->header;
100f7a26073SMyung Bae     const char* url = headerAndUrl->url;
101e51c710eSJames Feist 
1021476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
103ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/Registries/{}", registry);
1041476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
1051476687dSEd Tanous         "#MessageRegistryFile.v1_1_0.MessageRegistryFile";
1061476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
107bd79bce8SPatrick Williams     asyncResp->res.jsonValue["Description"] =
108bd79bce8SPatrick Williams         dmtf + registry + " Message Registry File Location";
109f7a26073SMyung Bae     asyncResp->res.jsonValue["Id"] = header.registryPrefix;
110*56b81992SEd Tanous     asyncResp->res.jsonValue["Registry"] =
111*56b81992SEd Tanous         std::format("{}.{}.{}", header.registryPrefix, header.versionMajor,
112*56b81992SEd Tanous                     header.versionMinor);
113613dabeaSEd Tanous     nlohmann::json::array_t languages;
114f7a26073SMyung Bae     languages.emplace_back(header.language);
115613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages@odata.count"] = languages.size();
116613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages"] = std::move(languages);
117613dabeaSEd Tanous     nlohmann::json::array_t locationMembers;
118613dabeaSEd Tanous     nlohmann::json::object_t location;
119f7a26073SMyung Bae     location["Language"] = header.language;
120613dabeaSEd Tanous     location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry;
121e51c710eSJames Feist 
122e51c710eSJames Feist     if (url != nullptr)
123e51c710eSJames Feist     {
124613dabeaSEd Tanous         location["PublicationUri"] = url;
125e51c710eSJames Feist     }
126613dabeaSEd Tanous     locationMembers.emplace_back(std::move(location));
127613dabeaSEd Tanous     asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size();
128613dabeaSEd Tanous     asyncResp->res.jsonValue["Location"] = std::move(locationMembers);
12970304cb5SJason M. Bills }
13070304cb5SJason M. Bills 
131dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app)
13270304cb5SJason M. Bills {
133dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
134ed398213SEd Tanous         .privileges(redfish::privileges::getMessageRegistryFile)
13545ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
13645ca1b86SEd Tanous             handleMessageRoutesMessageRegistryFileGet, std::ref(app)));
137dff07827SJohn Edward Broadbent }
138dff07827SJohn Edward Broadbent 
139dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet(
14045ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
141104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1426e8c18f0SJohn Edward Broadbent     const std::string& registry, const std::string& registryMatch)
1437e860f15SJohn Edward Broadbent 
144e51c710eSJames Feist {
1453ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
14645ca1b86SEd Tanous     {
14745ca1b86SEd Tanous         return;
14845ca1b86SEd Tanous     }
149f7a26073SMyung Bae 
150f7a26073SMyung Bae     std::optional<registries::HeaderAndUrl> headerAndUrl =
151f7a26073SMyung Bae         registries::getRegistryHeaderAndUrlFromPrefix(registry);
152f7a26073SMyung Bae     if (!headerAndUrl)
153e51c710eSJames Feist     {
154d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
1557e860f15SJohn Edward Broadbent                                    registry);
156e51c710eSJames Feist         return;
157e51c710eSJames Feist     }
158e51c710eSJames Feist 
159f7a26073SMyung Bae     const registries::Header& header = headerAndUrl->header;
1606e8c18f0SJohn Edward Broadbent     if (registry != registryMatch)
161e51c710eSJames Feist     {
162f7a26073SMyung Bae         messages::resourceNotFound(asyncResp->res, header.type, registryMatch);
163e51c710eSJames Feist         return;
164e51c710eSJames Feist     }
165e51c710eSJames Feist 
166f7a26073SMyung Bae     asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright;
167f7a26073SMyung Bae     asyncResp->res.jsonValue["@odata.type"] = header.type;
168*56b81992SEd Tanous     asyncResp->res.jsonValue["Id"] =
169*56b81992SEd Tanous         std::format("{}.{}.{}.{}", header.registryPrefix, header.versionMajor,
170*56b81992SEd Tanous                     header.versionMinor, header.versionPatch);
171f7a26073SMyung Bae     asyncResp->res.jsonValue["Name"] = header.name;
172f7a26073SMyung Bae     asyncResp->res.jsonValue["Language"] = header.language;
173f7a26073SMyung Bae     asyncResp->res.jsonValue["Description"] = header.description;
174f7a26073SMyung Bae     asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix;
175*56b81992SEd Tanous     asyncResp->res.jsonValue["RegistryVersion"] =
176*56b81992SEd Tanous         std::format("{}.{}.{}", header.versionMajor, header.versionMinor,
177*56b81992SEd Tanous                     header.versionPatch);
178f7a26073SMyung Bae     asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity;
17970304cb5SJason M. Bills 
180dff07827SJohn Edward Broadbent     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
18170304cb5SJason M. Bills 
18270304cb5SJason M. Bills     // Go through the Message Registry and populate each Message
183f7a26073SMyung Bae     const std::span<const registries::MessageEntry> registryEntries =
184f7a26073SMyung Bae         registries::getRegistryFromPrefix(registry);
185f7a26073SMyung Bae 
186f7a26073SMyung Bae     for (const registries::MessageEntry& message : registryEntries)
18770304cb5SJason M. Bills     {
188f7a26073SMyung Bae         nlohmann::json& obj = messageObj[message.first];
189f7a26073SMyung Bae         obj["Description"] = message.second.description;
190f7a26073SMyung Bae         obj["Message"] = message.second.message;
191f7a26073SMyung Bae         obj["Severity"] = message.second.messageSeverity;
192f7a26073SMyung Bae         obj["MessageSeverity"] = message.second.messageSeverity;
193f7a26073SMyung Bae         obj["NumberOfArgs"] = message.second.numberOfArgs;
194f7a26073SMyung Bae         obj["Resolution"] = message.second.resolution;
195f7a26073SMyung Bae         if (message.second.numberOfArgs > 0)
19670304cb5SJason M. Bills         {
19714c8aee2SEd Tanous             nlohmann::json& messageParamArray = obj["ParamTypes"];
198938f2568SEd Tanous             messageParamArray = nlohmann::json::array();
199f7a26073SMyung Bae             for (const char* str : message.second.paramTypes)
20070304cb5SJason M. Bills             {
20170304cb5SJason M. Bills                 if (str == nullptr)
20270304cb5SJason M. Bills                 {
20370304cb5SJason M. Bills                     break;
20470304cb5SJason M. Bills                 }
20570304cb5SJason M. Bills                 messageParamArray.push_back(str);
20670304cb5SJason M. Bills             }
20770304cb5SJason M. Bills         }
20870304cb5SJason M. Bills     }
20970304cb5SJason M. Bills }
21070304cb5SJason M. Bills 
211dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app)
212dff07827SJohn Edward Broadbent {
213dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
214dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFile)
21545ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
21645ca1b86SEd Tanous             std::bind_front(handleMessageRegistryGet, std::ref(app)));
217dff07827SJohn Edward Broadbent }
21870304cb5SJason M. Bills } // namespace redfish
219