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