xref: /openbmc/bmcweb/features/redfish/lib/metric_report.hpp (revision 45ca1b868e47978a4d2e8ebb680cb384e804c97e)
1081ebf06SWludzik, Jozef #pragma once
2081ebf06SWludzik, Jozef 
34028ff77SEd Tanous #include "utils/collection.hpp"
4081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp"
5081ebf06SWludzik, Jozef 
67e860f15SJohn Edward Broadbent #include <app.hpp>
7168e20c1SEd Tanous #include <dbus_utility.hpp>
8*45ca1b86SEd Tanous #include <query.hpp>
9ed398213SEd Tanous #include <registries/privilege_registry.hpp>
101e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
117e860f15SJohn Edward Broadbent 
12081ebf06SWludzik, Jozef namespace redfish
13081ebf06SWludzik, Jozef {
14081ebf06SWludzik, Jozef 
15081ebf06SWludzik, Jozef namespace telemetry
16081ebf06SWludzik, Jozef {
17081ebf06SWludzik, Jozef 
18456cd875SSzymon Dompke constexpr const char* metricReportUri =
19456cd875SSzymon Dompke     "/redfish/v1/TelemetryService/MetricReports";
20456cd875SSzymon Dompke 
21081ebf06SWludzik, Jozef using Readings =
22081ebf06SWludzik, Jozef     std::vector<std::tuple<std::string, std::string, double, uint64_t>>;
23081ebf06SWludzik, Jozef using TimestampReadings = std::tuple<uint64_t, Readings>;
24081ebf06SWludzik, Jozef 
25081ebf06SWludzik, Jozef inline nlohmann::json toMetricValues(const Readings& readings)
26081ebf06SWludzik, Jozef {
27081ebf06SWludzik, Jozef     nlohmann::json metricValues = nlohmann::json::array_t();
28081ebf06SWludzik, Jozef 
299eb808c1SEd Tanous     for (const auto& [id, metadata, sensorValue, timestamp] : readings)
30081ebf06SWludzik, Jozef     {
31081ebf06SWludzik, Jozef         metricValues.push_back({
32081ebf06SWludzik, Jozef             {"MetricId", id},
33081ebf06SWludzik, Jozef             {"MetricProperty", metadata},
34081ebf06SWludzik, Jozef             {"MetricValue", std::to_string(sensorValue)},
3545c367e0SKrzysztof Grobelny             {"Timestamp", crow::utility::getDateTimeUintMs(timestamp)},
36081ebf06SWludzik, Jozef         });
37081ebf06SWludzik, Jozef     }
38081ebf06SWludzik, Jozef 
39081ebf06SWludzik, Jozef     return metricValues;
40081ebf06SWludzik, Jozef }
41081ebf06SWludzik, Jozef 
42c0353249SWludzik, Jozef inline bool fillReport(nlohmann::json& json, const std::string& id,
431e1e598dSJonathan Doman                        const TimestampReadings& timestampReadings)
44081ebf06SWludzik, Jozef {
45c0353249SWludzik, Jozef     json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport";
46456cd875SSzymon Dompke     json["@odata.id"] =
47456cd875SSzymon Dompke         crow::utility::urlFromPieces("redfish", "v1", "TelemetryService",
48456cd875SSzymon Dompke                                      "MetricReports", id)
49456cd875SSzymon Dompke             .string();
50c0353249SWludzik, Jozef     json["Id"] = id;
51c0353249SWludzik, Jozef     json["Name"] = id;
52c0353249SWludzik, Jozef     json["MetricReportDefinition"]["@odata.id"] =
53456cd875SSzymon Dompke         crow::utility::urlFromPieces("redfish", "v1", "TelemetryService",
54456cd875SSzymon Dompke                                      "MetricReportDefinitions", id)
55456cd875SSzymon Dompke             .string();
56081ebf06SWludzik, Jozef 
571e1e598dSJonathan Doman     const auto& [timestamp, readings] = timestampReadings;
5845c367e0SKrzysztof Grobelny     json["Timestamp"] = crow::utility::getDateTimeUintMs(timestamp);
59c0353249SWludzik, Jozef     json["MetricValues"] = toMetricValues(readings);
60c0353249SWludzik, Jozef     return true;
61081ebf06SWludzik, Jozef }
62081ebf06SWludzik, Jozef } // namespace telemetry
63081ebf06SWludzik, Jozef 
647e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportCollection(App& app)
65081ebf06SWludzik, Jozef {
667e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/")
67ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReportCollection)
687e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
69*45ca1b86SEd Tanous             [&app](const crow::Request& req,
707e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
71*45ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
72*45ca1b86SEd Tanous                 {
73*45ca1b86SEd Tanous                     return;
74*45ca1b86SEd Tanous                 }
75*45ca1b86SEd Tanous 
768d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
77081ebf06SWludzik, Jozef                     "#MetricReportCollection.MetricReportCollection";
788d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] =
79456cd875SSzymon Dompke                     telemetry::metricReportUri;
808d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
814028ff77SEd Tanous                 const std::vector<const char*> interfaces{
824028ff77SEd Tanous                     telemetry::reportInterface};
834028ff77SEd Tanous                 collection_util::getCollectionMembers(
844028ff77SEd Tanous                     asyncResp, telemetry::metricReportUri, interfaces,
854028ff77SEd Tanous                     "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
867e860f15SJohn Edward Broadbent             });
87081ebf06SWludzik, Jozef }
88081ebf06SWludzik, Jozef 
897e860f15SJohn Edward Broadbent inline void requestRoutesMetricReport(App& app)
90081ebf06SWludzik, Jozef {
917e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/")
92ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReport)
937e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
94*45ca1b86SEd Tanous             [&app](const crow::Request& req,
957e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
967e860f15SJohn Edward Broadbent                    const std::string& id) {
97*45ca1b86SEd Tanous                 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
98*45ca1b86SEd Tanous                 {
99*45ca1b86SEd Tanous                     return;
100*45ca1b86SEd Tanous                 }
101081ebf06SWludzik, Jozef                 const std::string reportPath = telemetry::getDbusReportPath(id);
102081ebf06SWludzik, Jozef                 crow::connections::systemBus->async_method_call(
1037e860f15SJohn Edward Broadbent                     [asyncResp, id,
1047e860f15SJohn Edward Broadbent                      reportPath](const boost::system::error_code& ec) {
105081ebf06SWludzik, Jozef                         if (ec.value() == EBADR ||
106081ebf06SWludzik, Jozef                             ec == boost::system::errc::host_unreachable)
107081ebf06SWludzik, Jozef                         {
1087e860f15SJohn Edward Broadbent                             messages::resourceNotFound(asyncResp->res,
1097e860f15SJohn Edward Broadbent                                                        "MetricReport", id);
110081ebf06SWludzik, Jozef                             return;
111081ebf06SWludzik, Jozef                         }
112081ebf06SWludzik, Jozef                         if (ec)
113081ebf06SWludzik, Jozef                         {
114081ebf06SWludzik, Jozef                             BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
115081ebf06SWludzik, Jozef                             messages::internalError(asyncResp->res);
116081ebf06SWludzik, Jozef                             return;
117081ebf06SWludzik, Jozef                         }
118081ebf06SWludzik, Jozef 
1191e1e598dSJonathan Doman                         sdbusplus::asio::getProperty<
1201e1e598dSJonathan Doman                             telemetry::TimestampReadings>(
1211e1e598dSJonathan Doman                             *crow::connections::systemBus, telemetry::service,
1221e1e598dSJonathan Doman                             reportPath, telemetry::reportInterface, "Readings",
1237e860f15SJohn Edward Broadbent                             [asyncResp,
1247e860f15SJohn Edward Broadbent                              id](const boost::system::error_code ec,
1251e1e598dSJonathan Doman                                  const telemetry::TimestampReadings& ret) {
126081ebf06SWludzik, Jozef                                 if (ec)
127081ebf06SWludzik, Jozef                                 {
1287e860f15SJohn Edward Broadbent                                     BMCWEB_LOG_ERROR
1297e860f15SJohn Edward Broadbent                                         << "respHandler DBus error " << ec;
130081ebf06SWludzik, Jozef                                     messages::internalError(asyncResp->res);
131081ebf06SWludzik, Jozef                                     return;
132081ebf06SWludzik, Jozef                                 }
133081ebf06SWludzik, Jozef 
1341e1e598dSJonathan Doman                                 telemetry::fillReport(asyncResp->res.jsonValue,
1351e1e598dSJonathan Doman                                                       id, ret);
1361e1e598dSJonathan Doman                             });
137081ebf06SWludzik, Jozef                     },
138081ebf06SWludzik, Jozef                     telemetry::service, reportPath, telemetry::reportInterface,
139081ebf06SWludzik, Jozef                     "Update");
1407e860f15SJohn Edward Broadbent             });
141081ebf06SWludzik, Jozef }
142081ebf06SWludzik, Jozef } // namespace redfish
143