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/task_event_message_registry.hpp"
23 
24 namespace redfish
25 {
26 
27 class MessageRegistryFileCollection : public Node
28 {
29   public:
30     template <typename CrowApp>
31     MessageRegistryFileCollection(CrowApp& 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& req,
48                const std::vector<std::string>& params) 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", 3},
60             {"Members",
61              {{{"@odata.id", "/redfish/v1/Registries/Base"}},
62               {{"@odata.id", "/redfish/v1/Registries/TaskEvent"}},
63               {{"@odata.id", "/redfish/v1/Registries/OpenBMC"}}}}};
64 
65         res.end();
66     }
67 };
68 
69 class MessageRegistryFile : public Node
70 {
71   public:
72     template <typename CrowApp>
73     MessageRegistryFile(CrowApp& 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& req,
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
117         {
118             messages::resourceNotFound(
119                 res, "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
120                 registry);
121             res.end();
122             return;
123         }
124 
125         res.jsonValue = {
126             {"@odata.id", "/redfish/v1/Registries/" + registry},
127             {"@odata.type", "#MessageRegistryFile.v1_1_0.MessageRegistryFile"},
128             {"Name", registry + " Message Registry File"},
129             {"Description",
130              dmtf + registry + " Message Registry File Location"},
131             {"Id", header->registryPrefix},
132             {"Registry", header->id},
133             {"Languages", {"en"}},
134             {"Languages@odata.count", 1},
135             {"Location",
136              {{{"Language", "en"},
137                {"Uri",
138                 "/redfish/v1/Registries/" + registry + "/" + registry}}}},
139             {"Location@odata.count", 1}};
140 
141         if (url != nullptr)
142         {
143             res.jsonValue["Location"][0]["PublicationUri"] = url;
144         }
145 
146         res.end();
147     }
148 };
149 
150 class MessageRegistry : public Node
151 {
152   public:
153     template <typename CrowApp>
154     MessageRegistry(CrowApp& app) :
155         Node(app, "/redfish/v1/Registries/<str>/<str>/", std::string(),
156              std::string())
157     {
158         entityPrivileges = {
159             {boost::beast::http::verb::get, {{"Login"}}},
160             {boost::beast::http::verb::head, {{"Login"}}},
161             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
162             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
163             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
164             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
165     }
166 
167   private:
168     void doGet(crow::Response& res, const crow::Request& req,
169                const std::vector<std::string>& params) override
170     {
171         if (params.size() != 2)
172         {
173             messages::internalError(res);
174             res.end();
175             return;
176         }
177 
178         const std::string& registry = params[0];
179         const std::string& registry1 = params[1];
180 
181         const message_registries::Header* header;
182         std::vector<const message_registries::MessageEntry*> registryEntries;
183         if (registry == "Base")
184         {
185             header = &message_registries::base::header;
186             for (const message_registries::MessageEntry& entry :
187                  message_registries::base::registry)
188             {
189                 registryEntries.emplace_back(&entry);
190             }
191         }
192         else if (registry == "TaskEvent")
193         {
194             header = &message_registries::task_event::header;
195             for (const message_registries::MessageEntry& entry :
196                  message_registries::task_event::registry)
197             {
198                 registryEntries.emplace_back(&entry);
199             }
200         }
201         else if (registry == "OpenBMC")
202         {
203             header = &message_registries::openbmc::header;
204             for (const message_registries::MessageEntry& entry :
205                  message_registries::openbmc::registry)
206             {
207                 registryEntries.emplace_back(&entry);
208             }
209         }
210         else
211         {
212             messages::resourceNotFound(
213                 res, "#MessageRegistryFile.v1_1_0.MessageRegistryFile",
214                 registry);
215             res.end();
216             return;
217         }
218 
219         if (registry != registry1)
220         {
221             messages::resourceNotFound(res, header->type, registry1);
222             res.end();
223             return;
224         }
225 
226         res.jsonValue = {{"@Redfish.Copyright", header->copyright},
227                          {"@odata.type", header->type},
228                          {"Id", header->id},
229                          {"Name", header->name},
230                          {"Language", header->language},
231                          {"Description", header->description},
232                          {"RegistryPrefix", header->registryPrefix},
233                          {"RegistryVersion", header->registryVersion},
234                          {"OwningEntity", header->owningEntity}};
235 
236         nlohmann::json& messageObj = res.jsonValue["Messages"];
237 
238         // Go through the Message Registry and populate each Message
239         for (const message_registries::MessageEntry* message : registryEntries)
240         {
241             nlohmann::json& obj = messageObj[message->first];
242             obj = {{"Description", message->second.description},
243                    {"Message", message->second.message},
244                    {"Severity", message->second.severity},
245                    {"NumberOfArgs", message->second.numberOfArgs},
246                    {"Resolution", message->second.resolution}};
247             if (message->second.numberOfArgs > 0)
248             {
249                 nlohmann::json& messageParamArray = obj["ParamTypes"];
250                 for (const char* str : message->second.paramTypes)
251                 {
252                     if (str == nullptr)
253                     {
254                         break;
255                     }
256                     messageParamArray.push_back(str);
257                 }
258             }
259         }
260         res.end();
261     }
262 };
263 
264 } // namespace redfish
265