xref: /openbmc/bmcweb/features/redfish/lib/message_registries.hpp (revision d8a5d5d8e07f6dec97ed0cbc84052656165f6172)
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 "registries.hpp"
19 #include "registries/base_message_registry.hpp"
20 #include "registries/openbmc_message_registry.hpp"
21 #include "registries/resource_event_message_registry.hpp"
22 #include "registries/task_event_message_registry.hpp"
23 
24 #include <app.hpp>
25 #include <query.hpp>
26 #include <registries/privilege_registry.hpp>
27 
28 namespace redfish
29 {
30 
31 inline void handleMessageRegistryFileCollectionGet(
32     crow::App& app, const crow::Request& req,
33     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
34 {
35     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
36     {
37         return;
38     }
39     // Collections don't include the static data added by SubRoute
40     // because it has a duplicate entry for members
41 
42     asyncResp->res.jsonValue["@odata.type"] =
43         "#MessageRegistryFileCollection.MessageRegistryFileCollection";
44     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries";
45     asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection";
46     asyncResp->res.jsonValue["Description"] =
47         "Collection of MessageRegistryFiles";
48     asyncResp->res.jsonValue["Members@odata.count"] = 4;
49     asyncResp->res.jsonValue["Members"] = {
50         {{"@odata.id", "/redfish/v1/Registries/Base"}},
51         {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}},
52         {{"@odata.id", "/redfish/v1/Registries/ResourceEvent"}},
53         {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}};
54 }
55 
56 inline void requestRoutesMessageRegistryFileCollection(App& app)
57 {
58     /**
59      * Functions triggers appropriate requests on DBus
60      */
61     BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
62         .privileges(redfish::privileges::getMessageRegistryFileCollection)
63         .methods(boost::beast::http::verb::get)(std::bind_front(
64             handleMessageRegistryFileCollectionGet, std::ref(app)));
65 }
66 
67 inline void handleMessageRoutesMessageRegistryFileGet(
68     crow::App& app, const crow::Request& req,
69     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
70     const std::string& registry)
71 {
72     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
73     {
74         return;
75     }
76     const registries::Header* header = nullptr;
77     std::string dmtf = "DMTF ";
78     const char* url = nullptr;
79 
80     if (registry == "Base")
81     {
82         header = &registries::base::header;
83         url = registries::base::url;
84     }
85     else if (registry == "TaskEvent")
86     {
87         header = &registries::task_event::header;
88         url = registries::task_event::url;
89     }
90     else if (registry == "OpenBMC")
91     {
92         header = &registries::openbmc::header;
93         dmtf.clear();
94     }
95     else if (registry == "ResourceEvent")
96     {
97         header = &registries::resource_event::header;
98         url = registries::resource_event::url;
99     }
100     else
101     {
102         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
103                                    registry);
104         return;
105     }
106 
107     asyncResp->res.jsonValue["@odata.id"] =
108         "/redfish/v1/Registries/" + registry;
109     asyncResp->res.jsonValue["@odata.type"] =
110         "#MessageRegistryFile.v1_1_0.MessageRegistryFile";
111     asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
112     asyncResp->res.jsonValue["Description"] =
113         dmtf + registry + " Message Registry File Location";
114     asyncResp->res.jsonValue["Id"] = header->registryPrefix;
115     asyncResp->res.jsonValue["Registry"] = header->id;
116     asyncResp->res.jsonValue["Languages"] = {"en"};
117     asyncResp->res.jsonValue["Languages@odata.count"] = 1;
118     asyncResp->res.jsonValue["Location"] = {
119         {{"Language", "en"},
120          {"Uri", "/redfish/v1/Registries/" + registry + "/" + registry}}};
121 
122     asyncResp->res.jsonValue["Location@odata.count"] = 1;
123 
124     if (url != nullptr)
125     {
126         asyncResp->res.jsonValue["Location"][0]["PublicationUri"] = url;
127     }
128 }
129 
130 inline void requestRoutesMessageRegistryFile(App& app)
131 {
132     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
133         .privileges(redfish::privileges::getMessageRegistryFile)
134         .methods(boost::beast::http::verb::get)(std::bind_front(
135             handleMessageRoutesMessageRegistryFileGet, std::ref(app)));
136 }
137 
138 inline void handleMessageRegistryGet(
139     crow::App& app, const crow::Request& req,
140     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
141     const std::string& registry, const std::string& registryMatch)
142 
143 {
144     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
145     {
146         return;
147     }
148     const registries::Header* header = nullptr;
149     std::vector<const registries::MessageEntry*> registryEntries;
150     if (registry == "Base")
151     {
152         header = &registries::base::header;
153         for (const registries::MessageEntry& entry : registries::base::registry)
154         {
155             registryEntries.emplace_back(&entry);
156         }
157     }
158     else if (registry == "TaskEvent")
159     {
160         header = &registries::task_event::header;
161         for (const registries::MessageEntry& entry :
162              registries::task_event::registry)
163         {
164             registryEntries.emplace_back(&entry);
165         }
166     }
167     else if (registry == "OpenBMC")
168     {
169         header = &registries::openbmc::header;
170         for (const registries::MessageEntry& entry :
171              registries::openbmc::registry)
172         {
173             registryEntries.emplace_back(&entry);
174         }
175     }
176     else if (registry == "ResourceEvent")
177     {
178         header = &registries::resource_event::header;
179         for (const registries::MessageEntry& entry :
180              registries::resource_event::registry)
181         {
182             registryEntries.emplace_back(&entry);
183         }
184     }
185     else
186     {
187         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
188                                    registry);
189         return;
190     }
191 
192     if (registry != registryMatch)
193     {
194         messages::resourceNotFound(asyncResp->res, header->type, registryMatch);
195         return;
196     }
197 
198     asyncResp->res.jsonValue["@Redfish.Copyright"] = header->copyright;
199     asyncResp->res.jsonValue["@odata.type"] = header->type;
200     asyncResp->res.jsonValue["Id"] = header->id;
201     asyncResp->res.jsonValue["Name"] = header->name;
202     asyncResp->res.jsonValue["Language"] = header->language;
203     asyncResp->res.jsonValue["Description"] = header->description;
204     asyncResp->res.jsonValue["RegistryPrefix"] = header->registryPrefix;
205     asyncResp->res.jsonValue["RegistryVersion"] = header->registryVersion;
206     asyncResp->res.jsonValue["OwningEntity"] = header->owningEntity;
207 
208     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
209 
210     // Go through the Message Registry and populate each Message
211     for (const registries::MessageEntry* message : registryEntries)
212     {
213         nlohmann::json& obj = messageObj[message->first];
214         obj["Description"] = message->second.description;
215         obj["Message"] = message->second.message;
216         obj["Severity"] = message->second.messageSeverity;
217         obj["MessageSeverity"] = message->second.messageSeverity;
218         obj["NumberOfArgs"] = message->second.numberOfArgs;
219         obj["Resolution"] = message->second.resolution;
220         if (message->second.numberOfArgs > 0)
221         {
222             nlohmann::json& messageParamArray = obj["ParamTypes"];
223             messageParamArray = nlohmann::json::array();
224             for (const char* str : message->second.paramTypes)
225             {
226                 if (str == nullptr)
227                 {
228                     break;
229                 }
230                 messageParamArray.push_back(str);
231             }
232         }
233     }
234 }
235 
236 inline void requestRoutesMessageRegistry(App& app)
237 {
238     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
239         .privileges(redfish::privileges::getMessageRegistryFile)
240         .methods(boost::beast::http::verb::get)(
241             std::bind_front(handleMessageRegistryGet, std::ref(app)));
242 }
243 } // namespace redfish
244