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