170304cb5SJason M. Bills /*
2*6be832e2SEd Tanous Copyright (c) 2019 Intel Corporation
3*6be832e2SEd Tanous 
4*6be832e2SEd Tanous Licensed under the Apache License, Version 2.0 (the "License");
5*6be832e2SEd Tanous you may not use this file except in compliance with the License.
6*6be832e2SEd Tanous You may obtain a copy of the License at
7*6be832e2SEd Tanous 
8*6be832e2SEd Tanous       http://www.apache.org/licenses/LICENSE-2.0
9*6be832e2SEd Tanous 
10*6be832e2SEd Tanous Unless required by applicable law or agreed to in writing, software
11*6be832e2SEd Tanous distributed under the License is distributed on an "AS IS" BASIS,
12*6be832e2SEd Tanous WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*6be832e2SEd Tanous See the License for the specific language governing permissions and
14*6be832e2SEd Tanous limitations under the License.
1570304cb5SJason M. Bills */
1670304cb5SJason M. Bills #pragma once
1770304cb5SJason M. Bills 
183ccb3adbSEd Tanous #include "app.hpp"
193ccb3adbSEd Tanous #include "query.hpp"
2070304cb5SJason M. Bills #include "registries.hpp"
2170304cb5SJason M. Bills #include "registries/base_message_registry.hpp"
22fbe8378fSJason M. Bills #include "registries/openbmc_message_registry.hpp"
233ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
2474eec26bSSunitha Harish #include "registries/resource_event_message_registry.hpp"
25e51c710eSJames Feist #include "registries/task_event_message_registry.hpp"
2686987606SMichal Orzel #include "registries/telemetry_message_registry.hpp"
2770304cb5SJason M. Bills 
28ef4c65b7SEd Tanous #include <boost/url/format.hpp>
29ef4c65b7SEd Tanous 
30613dabeaSEd Tanous #include <array>
31613dabeaSEd Tanous 
3270304cb5SJason M. Bills namespace redfish
3370304cb5SJason M. Bills {
3470304cb5SJason M. Bills 
handleMessageRegistryFileCollectionGet(crow::App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)35dff07827SJohn Edward Broadbent inline void handleMessageRegistryFileCollectionGet(
3645ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
37104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
3870304cb5SJason M. Bills {
393ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
4045ca1b86SEd Tanous     {
4145ca1b86SEd Tanous         return;
4245ca1b86SEd Tanous     }
437e860f15SJohn Edward Broadbent     // Collections don't include the static data added by SubRoute
447e860f15SJohn Edward Broadbent     // because it has a duplicate entry for members
4514c8aee2SEd Tanous 
461476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
471476687dSEd Tanous         "#MessageRegistryFileCollection.MessageRegistryFileCollection";
481476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Registries";
491476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = "MessageRegistryFile Collection";
501476687dSEd Tanous     asyncResp->res.jsonValue["Description"] =
511476687dSEd Tanous         "Collection of MessageRegistryFiles";
5286987606SMichal Orzel     asyncResp->res.jsonValue["Members@odata.count"] = 5;
53613dabeaSEd Tanous 
54613dabeaSEd Tanous     nlohmann::json& members = asyncResp->res.jsonValue["Members"];
5586987606SMichal Orzel     for (const char* memberName : std::to_array(
5686987606SMichal Orzel              {"Base", "TaskEvent", "ResourceEvent", "OpenBMC", "Telemetry"}))
57613dabeaSEd Tanous     {
58613dabeaSEd Tanous         nlohmann::json::object_t member;
59bd79bce8SPatrick Williams         member["@odata.id"] =
60bd79bce8SPatrick Williams             boost::urls::format("/redfish/v1/Registries/{}", memberName);
61613dabeaSEd Tanous         members.emplace_back(std::move(member));
62613dabeaSEd Tanous     }
6370304cb5SJason M. Bills }
6470304cb5SJason M. Bills 
requestRoutesMessageRegistryFileCollection(App & app)65dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFileCollection(App& app)
6670304cb5SJason M. Bills {
67dff07827SJohn Edward Broadbent     /**
68dff07827SJohn Edward Broadbent      * Functions triggers appropriate requests on DBus
69dff07827SJohn Edward Broadbent      */
70dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/")
71dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFileCollection)
7245ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
7345ca1b86SEd Tanous             handleMessageRegistryFileCollectionGet, std::ref(app)));
74dff07827SJohn Edward Broadbent }
75dff07827SJohn Edward Broadbent 
handleMessageRoutesMessageRegistryFileGet(crow::App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & registry)76dff07827SJohn Edward Broadbent inline void handleMessageRoutesMessageRegistryFileGet(
7745ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
78104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
79dff07827SJohn Edward Broadbent     const std::string& registry)
80dff07827SJohn Edward Broadbent {
813ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
8245ca1b86SEd Tanous     {
8345ca1b86SEd Tanous         return;
8445ca1b86SEd Tanous     }
85fffb8c1fSEd Tanous     const registries::Header* header = nullptr;
86e51c710eSJames Feist     std::string dmtf = "DMTF ";
87e51c710eSJames Feist     const char* url = nullptr;
88e51c710eSJames Feist 
89e51c710eSJames Feist     if (registry == "Base")
90e51c710eSJames Feist     {
91fffb8c1fSEd Tanous         header = &registries::base::header;
92fffb8c1fSEd Tanous         url = registries::base::url;
93e51c710eSJames Feist     }
94e51c710eSJames Feist     else if (registry == "TaskEvent")
95e51c710eSJames Feist     {
96fffb8c1fSEd Tanous         header = &registries::task_event::header;
97fffb8c1fSEd Tanous         url = registries::task_event::url;
98e51c710eSJames Feist     }
99e51c710eSJames Feist     else if (registry == "OpenBMC")
100e51c710eSJames Feist     {
101fffb8c1fSEd Tanous         header = &registries::openbmc::header;
102e51c710eSJames Feist         dmtf.clear();
103e51c710eSJames Feist     }
10474eec26bSSunitha Harish     else if (registry == "ResourceEvent")
10574eec26bSSunitha Harish     {
106fffb8c1fSEd Tanous         header = &registries::resource_event::header;
107fffb8c1fSEd Tanous         url = registries::resource_event::url;
10874eec26bSSunitha Harish     }
10986987606SMichal Orzel     else if (registry == "Telemetry")
11086987606SMichal Orzel     {
11186987606SMichal Orzel         header = &registries::telemetry::header;
11286987606SMichal Orzel         url = registries::telemetry::url;
11386987606SMichal Orzel     }
114e51c710eSJames Feist     else
115e51c710eSJames Feist     {
116d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
1177e860f15SJohn Edward Broadbent                                    registry);
118e51c710eSJames Feist         return;
119e51c710eSJames Feist     }
120e51c710eSJames Feist 
1211476687dSEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
122ef4c65b7SEd Tanous         boost::urls::format("/redfish/v1/Registries/{}", registry);
1231476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
1241476687dSEd Tanous         "#MessageRegistryFile.v1_1_0.MessageRegistryFile";
1251476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = registry + " Message Registry File";
126bd79bce8SPatrick Williams     asyncResp->res.jsonValue["Description"] =
127bd79bce8SPatrick Williams         dmtf + registry + " Message Registry File Location";
1281476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = header->registryPrefix;
1291476687dSEd Tanous     asyncResp->res.jsonValue["Registry"] = header->id;
130613dabeaSEd Tanous     nlohmann::json::array_t languages;
1313ad903a7SAlexander Paramonov     languages.emplace_back(header->language);
132613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages@odata.count"] = languages.size();
133613dabeaSEd Tanous     asyncResp->res.jsonValue["Languages"] = std::move(languages);
134613dabeaSEd Tanous     nlohmann::json::array_t locationMembers;
135613dabeaSEd Tanous     nlohmann::json::object_t location;
1363ad903a7SAlexander Paramonov     location["Language"] = header->language;
137613dabeaSEd Tanous     location["Uri"] = "/redfish/v1/Registries/" + registry + "/" + registry;
138e51c710eSJames Feist 
139e51c710eSJames Feist     if (url != nullptr)
140e51c710eSJames Feist     {
141613dabeaSEd Tanous         location["PublicationUri"] = url;
142e51c710eSJames Feist     }
143613dabeaSEd Tanous     locationMembers.emplace_back(std::move(location));
144613dabeaSEd Tanous     asyncResp->res.jsonValue["Location@odata.count"] = locationMembers.size();
145613dabeaSEd Tanous     asyncResp->res.jsonValue["Location"] = std::move(locationMembers);
14670304cb5SJason M. Bills }
14770304cb5SJason M. Bills 
requestRoutesMessageRegistryFile(App & app)148dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistryFile(App& app)
14970304cb5SJason M. Bills {
150dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/")
151ed398213SEd Tanous         .privileges(redfish::privileges::getMessageRegistryFile)
15245ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
15345ca1b86SEd Tanous             handleMessageRoutesMessageRegistryFileGet, std::ref(app)));
154dff07827SJohn Edward Broadbent }
155dff07827SJohn Edward Broadbent 
handleMessageRegistryGet(crow::App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp,const std::string & registry,const std::string & registryMatch)156dff07827SJohn Edward Broadbent inline void handleMessageRegistryGet(
15745ca1b86SEd Tanous     crow::App& app, const crow::Request& req,
158104f09c9SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1596e8c18f0SJohn Edward Broadbent     const std::string& registry, const std::string& registryMatch)
1607e860f15SJohn Edward Broadbent 
161e51c710eSJames Feist {
1623ba00073SCarson Labrado     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
16345ca1b86SEd Tanous     {
16445ca1b86SEd Tanous         return;
16545ca1b86SEd Tanous     }
166fffb8c1fSEd Tanous     const registries::Header* header = nullptr;
167fffb8c1fSEd Tanous     std::vector<const registries::MessageEntry*> registryEntries;
168e51c710eSJames Feist     if (registry == "Base")
169e51c710eSJames Feist     {
170fffb8c1fSEd Tanous         header = &registries::base::header;
171fffb8c1fSEd Tanous         for (const registries::MessageEntry& entry : registries::base::registry)
172e51c710eSJames Feist         {
173e51c710eSJames Feist             registryEntries.emplace_back(&entry);
174e51c710eSJames Feist         }
175e51c710eSJames Feist     }
176e51c710eSJames Feist     else if (registry == "TaskEvent")
177e51c710eSJames Feist     {
178fffb8c1fSEd Tanous         header = &registries::task_event::header;
179fffb8c1fSEd Tanous         for (const registries::MessageEntry& entry :
180fffb8c1fSEd Tanous              registries::task_event::registry)
181e51c710eSJames Feist         {
182e51c710eSJames Feist             registryEntries.emplace_back(&entry);
183e51c710eSJames Feist         }
184e51c710eSJames Feist     }
185e51c710eSJames Feist     else if (registry == "OpenBMC")
186e51c710eSJames Feist     {
187fffb8c1fSEd Tanous         header = &registries::openbmc::header;
188fffb8c1fSEd Tanous         for (const registries::MessageEntry& entry :
189fffb8c1fSEd Tanous              registries::openbmc::registry)
190e51c710eSJames Feist         {
191e51c710eSJames Feist             registryEntries.emplace_back(&entry);
192e51c710eSJames Feist         }
193e51c710eSJames Feist     }
19474eec26bSSunitha Harish     else if (registry == "ResourceEvent")
19574eec26bSSunitha Harish     {
196fffb8c1fSEd Tanous         header = &registries::resource_event::header;
197fffb8c1fSEd Tanous         for (const registries::MessageEntry& entry :
198fffb8c1fSEd Tanous              registries::resource_event::registry)
19974eec26bSSunitha Harish         {
20074eec26bSSunitha Harish             registryEntries.emplace_back(&entry);
20174eec26bSSunitha Harish         }
20274eec26bSSunitha Harish     }
20386987606SMichal Orzel     else if (registry == "Telemetry")
20486987606SMichal Orzel     {
20586987606SMichal Orzel         header = &registries::telemetry::header;
20686987606SMichal Orzel         for (const registries::MessageEntry& entry :
20786987606SMichal Orzel              registries::telemetry::registry)
20886987606SMichal Orzel         {
20986987606SMichal Orzel             registryEntries.emplace_back(&entry);
21086987606SMichal Orzel         }
21186987606SMichal Orzel     }
212e51c710eSJames Feist     else
213e51c710eSJames Feist     {
214d8a5d5d8SJiaqing Zhao         messages::resourceNotFound(asyncResp->res, "MessageRegistryFile",
2157e860f15SJohn Edward Broadbent                                    registry);
216e51c710eSJames Feist         return;
217e51c710eSJames Feist     }
218e51c710eSJames Feist 
2196e8c18f0SJohn Edward Broadbent     if (registry != registryMatch)
220e51c710eSJames Feist     {
2216e8c18f0SJohn Edward Broadbent         messages::resourceNotFound(asyncResp->res, header->type, registryMatch);
222e51c710eSJames Feist         return;
223e51c710eSJames Feist     }
224e51c710eSJames Feist 
2251476687dSEd Tanous     asyncResp->res.jsonValue["@Redfish.Copyright"] = header->copyright;
2261476687dSEd Tanous     asyncResp->res.jsonValue["@odata.type"] = header->type;
2271476687dSEd Tanous     asyncResp->res.jsonValue["Id"] = header->id;
2281476687dSEd Tanous     asyncResp->res.jsonValue["Name"] = header->name;
2291476687dSEd Tanous     asyncResp->res.jsonValue["Language"] = header->language;
2301476687dSEd Tanous     asyncResp->res.jsonValue["Description"] = header->description;
2311476687dSEd Tanous     asyncResp->res.jsonValue["RegistryPrefix"] = header->registryPrefix;
2321476687dSEd Tanous     asyncResp->res.jsonValue["RegistryVersion"] = header->registryVersion;
2331476687dSEd Tanous     asyncResp->res.jsonValue["OwningEntity"] = header->owningEntity;
23470304cb5SJason M. Bills 
235dff07827SJohn Edward Broadbent     nlohmann::json& messageObj = asyncResp->res.jsonValue["Messages"];
23670304cb5SJason M. Bills 
23770304cb5SJason M. Bills     // Go through the Message Registry and populate each Message
238fffb8c1fSEd Tanous     for (const registries::MessageEntry* message : registryEntries)
23970304cb5SJason M. Bills     {
240e51c710eSJames Feist         nlohmann::json& obj = messageObj[message->first];
2411476687dSEd Tanous         obj["Description"] = message->second.description;
2421476687dSEd Tanous         obj["Message"] = message->second.message;
2431476687dSEd Tanous         obj["Severity"] = message->second.messageSeverity;
2441476687dSEd Tanous         obj["MessageSeverity"] = message->second.messageSeverity;
2451476687dSEd Tanous         obj["NumberOfArgs"] = message->second.numberOfArgs;
2461476687dSEd Tanous         obj["Resolution"] = message->second.resolution;
247e51c710eSJames Feist         if (message->second.numberOfArgs > 0)
24870304cb5SJason M. Bills         {
24914c8aee2SEd Tanous             nlohmann::json& messageParamArray = obj["ParamTypes"];
250938f2568SEd Tanous             messageParamArray = nlohmann::json::array();
251e51c710eSJames Feist             for (const char* str : message->second.paramTypes)
25270304cb5SJason M. Bills             {
25370304cb5SJason M. Bills                 if (str == nullptr)
25470304cb5SJason M. Bills                 {
25570304cb5SJason M. Bills                     break;
25670304cb5SJason M. Bills                 }
25770304cb5SJason M. Bills                 messageParamArray.push_back(str);
25870304cb5SJason M. Bills             }
25970304cb5SJason M. Bills         }
26070304cb5SJason M. Bills     }
26170304cb5SJason M. Bills }
26270304cb5SJason M. Bills 
requestRoutesMessageRegistry(App & app)263dff07827SJohn Edward Broadbent inline void requestRoutesMessageRegistry(App& app)
264dff07827SJohn Edward Broadbent {
265dff07827SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/Registries/<str>/<str>/")
266dff07827SJohn Edward Broadbent         .privileges(redfish::privileges::getMessageRegistryFile)
26745ca1b86SEd Tanous         .methods(boost::beast::http::verb::get)(
26845ca1b86SEd Tanous             std::bind_front(handleMessageRegistryGet, std::ref(app)));
269dff07827SJohn Edward Broadbent }
27070304cb5SJason M. Bills } // namespace redfish
271