xref: /openbmc/bmcweb/features/redfish/lib/message_registries.hpp (revision 45ca1b868e47978a4d2e8ebb680cb384e804c97e)
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->res))
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 = {
43         {"@odata.type",
44          "#MessageRegistryFileCollection.MessageRegistryFileCollection"},
45         {"@odata.id", "/redfish/v1/Registries"},
46         {"Name", "MessageRegistryFile Collection"},
47         {"Description", "Collection of MessageRegistryFiles"},
48         {"Members@odata.count", 4},
49         {"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->res))
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(
103             asyncResp->res, "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
104             registry);
105         return;
106     }
107 
108     asyncResp->res.jsonValue = {
109         {"@odata.id", "/redfish/v1/Registries/" + registry},
110         {"@odata.type", "#MessageRegistryFile.v1_1_0.MessageRegistryFile"},
111         {"Name", registry + " Message Registry File"},
112         {"Description", dmtf + registry + " Message Registry File Location"},
113         {"Id", header->registryPrefix},
114         {"Registry", header->id},
115         {"Languages", {"en"}},
116         {"Languages@odata.count", 1},
117         {"Location",
118          {{{"Language", "en"},
119            {"Uri", "/redfish/v1/Registries/" + registry + "/" + registry}}}},
120         {"Location@odata.count", 1}};
121 
122     if (url != nullptr)
123     {
124         asyncResp->res.jsonValue["Location"][0]["PublicationUri"] = url;
125     }
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->res))
143     {
144         return;
145     }
146     const registries::Header* header = nullptr;
147     std::vector<const registries::MessageEntry*> registryEntries;
148     if (registry == "Base")
149     {
150         header = &registries::base::header;
151         for (const registries::MessageEntry& entry : registries::base::registry)
152         {
153             registryEntries.emplace_back(&entry);
154         }
155     }
156     else if (registry == "TaskEvent")
157     {
158         header = &registries::task_event::header;
159         for (const registries::MessageEntry& entry :
160              registries::task_event::registry)
161         {
162             registryEntries.emplace_back(&entry);
163         }
164     }
165     else if (registry == "OpenBMC")
166     {
167         header = &registries::openbmc::header;
168         for (const registries::MessageEntry& entry :
169              registries::openbmc::registry)
170         {
171             registryEntries.emplace_back(&entry);
172         }
173     }
174     else if (registry == "ResourceEvent")
175     {
176         header = &registries::resource_event::header;
177         for (const registries::MessageEntry& entry :
178              registries::resource_event::registry)
179         {
180             registryEntries.emplace_back(&entry);
181         }
182     }
183     else
184     {
185         messages::resourceNotFound(
186             asyncResp->res, "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
187             registry);
188         return;
189     }
190 
191     if (registry != registryMatch)
192     {
193         messages::resourceNotFound(asyncResp->res, header->type, registryMatch);
194         return;
195     }
196 
197     asyncResp->res.jsonValue = {{"@Redfish.Copyright", header->copyright},
198                                 {"@odata.type", header->type},
199                                 {"Id", header->id},
200                                 {"Name", header->name},
201                                 {"Language", header->language},
202                                 {"Description", header->description},
203                                 {"RegistryPrefix", header->registryPrefix},
204                                 {"RegistryVersion", header->registryVersion},
205                                 {"OwningEntity", header->owningEntity}};
206 
207     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
208 
209     // Go through the Message Registry and populate each Message
210     for (const registries::MessageEntry* message : registryEntries)
211     {
212         nlohmann::json& obj = messageObj[message->first];
213         obj = {{"Description", message->second.description},
214                {"Message", message->second.message},
215                {"Severity", message->second.messageSeverity},
216                {"MessageSeverity", message->second.messageSeverity},
217                {"NumberOfArgs", message->second.numberOfArgs},
218                {"Resolution", message->second.resolution}};
219         if (message->second.numberOfArgs > 0)
220         {
221             nlohmann::json& messageParamArray = obj["ParamTypes"];
222             messageParamArray = nlohmann::json::array();
223             for (const char* str : message->second.paramTypes)
224             {
225                 if (str == nullptr)
226                 {
227                     break;
228                 }
229                 messageParamArray.push_back(str);
230             }
231         }
232     }
233 }
234 
235 inline void requestRoutesMessageRegistry(App& app)
236 {
237     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
238         .privileges(redfish::privileges::getMessageRegistryFile)
239         .methods(boost::beast::http::verb::get)(
240             std::bind_front(handleMessageRegistryGet, std::ref(app)));
241 }
242 } // namespace redfish
243