xref: /openbmc/bmcweb/redfish-core/lib/message_registries.hpp (revision 276ede551ae1371b73631cbc3860c377bb26fe35)
1 /*
2 Copyright (c) 2019 Intel Corporation
3 
4 Licensed under the Apache License, Version 2.0 (the "License");
5 you may not use this file except in compliance with the License.
6 You may obtain a copy of the License at
7 
8       http://www.apache.org/licenses/LICENSE-2.0
9 
10 Unless required by applicable law or agreed to in writing, software
11 distributed under the License is distributed on an "AS IS" BASIS,
12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 See the License for the specific language governing permissions and
14 limitations under the License.
15 */
16 #pragma once
17 
18 #include "app.hpp"
19 #include "query.hpp"
20 #include "registries.hpp"
21 #include "registries_selector.hpp"
22 
23 #include <boost/url/format.hpp>
24 
25 #include <array>
26 
27 namespace redfish
28 {
29 
30 inline void handleMessageRegistryFileCollectionGet(
31     crow::App& app, const crow::Request& req,
32     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
33 {
34     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
35     {
36         return;
37     }
38     // Collections don't include the static data added by SubRoute
39     // because it has a duplicate entry for members
40 
41     asyncResp->res.jsonValue["@odata.type"] =
42         "#MessageRegistryFileCollection.MessageRegistryFileCollection";
43     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries";
44     asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection";
45     asyncResp->res.jsonValue["Description"] =
46         "Collection of MessageRegistryFiles";
47 
48     nlohmann::json& members = asyncResp->res.jsonValue["Members"];
49 
50     static constexpr const auto registryFiles = std::to_array(
51         {"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry",
52          "HeartbeatEvent"});
53 
54     for (const char* memberName : registryFiles)
55     {
56         nlohmann::json::object_t member;
57         member["@odata.id"] =
58             boost::urls::format("/redfish/v1/Registries/{}", memberName);
59         members.emplace_back(std::move(member));
60     }
61     asyncResp->res.jsonValue["Members@odata.count"] = members.size();
62 }
63 
64 inline void requestRoutesMessageRegistryFileCollection(App& app)
65 {
66     /**
67      * Functions triggers appropriate requests on DBus
68      */
69     BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
70         .privileges(redfish::privileges::getMessageRegistryFileCollection)
71         .methods(boost::beast::http::verb::get)(std::bind_front(
72             handleMessageRegistryFileCollectionGet, std::ref(app)));
73 }
74 
75 inline void handleMessageRoutesMessageRegistryFileGet(
76     crow::App& app, const crow::Request& req,
77     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
78     const std::string& registry)
79 {
80     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
81     {
82         return;
83     }
84     std::string dmtf = "DMTF ";
85     std::optional<registries::HeaderAndUrl> headerAndUrl =
86         registries::getRegistryHeaderAndUrlFromPrefix(registry);
87 
88     if (!headerAndUrl)
89     {
90         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
91                                    registry);
92         return;
93     }
94     if (registry == "OpenBMC")
95     {
96         dmtf.clear();
97     }
98     const registries::Header& header = headerAndUrl->header;
99     const char* url = headerAndUrl->url;
100 
101     asyncResp->res.jsonValue["@odata.id"] =
102         boost::urls::format("/redfish/v1/Registries/{}", registry);
103     asyncResp->res.jsonValue["@odata.type"] =
104         "#MessageRegistryFile.v1_1_0.MessageRegistryFile";
105     asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
106     asyncResp->res.jsonValue["Description"] =
107         dmtf + registry + " Message Registry File Location";
108     asyncResp->res.jsonValue["Id"] = header.registryPrefix;
109     asyncResp->res.jsonValue["Registry"] = header.id;
110     nlohmann::json::array_t languages;
111     languages.emplace_back(header.language);
112     asyncResp->res.jsonValue["Languages@odata.count"] = languages.size();
113     asyncResp->res.jsonValue["Languages"] = std::move(languages);
114     nlohmann::json::array_t locationMembers;
115     nlohmann::json::object_t location;
116     location["Language"] = header.language;
117     location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry;
118 
119     if (url != nullptr)
120     {
121         location["PublicationUri"] = url;
122     }
123     locationMembers.emplace_back(std::move(location));
124     asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size();
125     asyncResp->res.jsonValue["Location"] = std::move(locationMembers);
126 }
127 
128 inline void requestRoutesMessageRegistryFile(App& app)
129 {
130     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
131         .privileges(redfish::privileges::getMessageRegistryFile)
132         .methods(boost::beast::http::verb::get)(std::bind_front(
133             handleMessageRoutesMessageRegistryFileGet, std::ref(app)));
134 }
135 
136 inline void handleMessageRegistryGet(
137     crow::App& app, const crow::Request& req,
138     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
139     const std::string& registry, const std::string& registryMatch)
140 
141 {
142     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
143     {
144         return;
145     }
146 
147     std::optional<registries::HeaderAndUrl> headerAndUrl =
148         registries::getRegistryHeaderAndUrlFromPrefix(registry);
149     if (!headerAndUrl)
150     {
151         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
152                                    registry);
153         return;
154     }
155 
156     const registries::Header& header = headerAndUrl->header;
157     if (registry != registryMatch)
158     {
159         messages::resourceNotFound(asyncResp->res, header.type, registryMatch);
160         return;
161     }
162 
163     asyncResp->res.jsonValue["@Redfish.Copyright"] = header.copyright;
164     asyncResp->res.jsonValue["@odata.type"] = header.type;
165     asyncResp->res.jsonValue["Id"] = header.id;
166     asyncResp->res.jsonValue["Name"] = header.name;
167     asyncResp->res.jsonValue["Language"] = header.language;
168     asyncResp->res.jsonValue["Description"] = header.description;
169     asyncResp->res.jsonValue["RegistryPrefix"] = header.registryPrefix;
170     asyncResp->res.jsonValue["RegistryVersion"] = header.registryVersion;
171     asyncResp->res.jsonValue["OwningEntity"] = header.owningEntity;
172 
173     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
174 
175     // Go through the Message Registry and populate each Message
176     const std::span<const registries::MessageEntry> registryEntries =
177         registries::getRegistryFromPrefix(registry);
178 
179     for (const registries::MessageEntry& message : registryEntries)
180     {
181         nlohmann::json& obj = messageObj[message.first];
182         obj["Description"] = message.second.description;
183         obj["Message"] = message.second.message;
184         obj["Severity"] = message.second.messageSeverity;
185         obj["MessageSeverity"] = message.second.messageSeverity;
186         obj["NumberOfArgs"] = message.second.numberOfArgs;
187         obj["Resolution"] = message.second.resolution;
188         if (message.second.numberOfArgs > 0)
189         {
190             nlohmann::json& messageParamArray = obj["ParamTypes"];
191             messageParamArray = nlohmann::json::array();
192             for (const char* str : message.second.paramTypes)
193             {
194                 if (str == nullptr)
195                 {
196                     break;
197                 }
198                 messageParamArray.push_back(str);
199             }
200         }
201     }
202 }
203 
204 inline void requestRoutesMessageRegistry(App& app)
205 {
206     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
207         .privileges(redfish::privileges::getMessageRegistryFile)
208         .methods(boost::beast::http::verb::get)(
209             std::bind_front(handleMessageRegistryGet, std::ref(app)));
210 }
211 } // namespace redfish
212