xref: /openbmc/bmcweb/features/redfish/lib/metric_report.hpp (revision 7e860f1550c8686eec42f7a75bc5f2ef51e756ad)
1081ebf06SWludzik, Jozef #pragma once
2081ebf06SWludzik, Jozef 
3081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp"
4081ebf06SWludzik, Jozef 
5*7e860f15SJohn Edward Broadbent #include <app.hpp>
6*7e860f15SJohn Edward Broadbent 
7081ebf06SWludzik, Jozef namespace redfish
8081ebf06SWludzik, Jozef {
9081ebf06SWludzik, Jozef 
10081ebf06SWludzik, Jozef namespace telemetry
11081ebf06SWludzik, Jozef {
12081ebf06SWludzik, Jozef 
13081ebf06SWludzik, Jozef using Readings =
14081ebf06SWludzik, Jozef     std::vector<std::tuple<std::string, std::string, double, uint64_t>>;
15081ebf06SWludzik, Jozef using TimestampReadings = std::tuple<uint64_t, Readings>;
16081ebf06SWludzik, Jozef 
17081ebf06SWludzik, Jozef inline nlohmann::json toMetricValues(const Readings& readings)
18081ebf06SWludzik, Jozef {
19081ebf06SWludzik, Jozef     nlohmann::json metricValues = nlohmann::json::array_t();
20081ebf06SWludzik, Jozef 
21081ebf06SWludzik, Jozef     for (auto& [id, metadata, sensorValue, timestamp] : readings)
22081ebf06SWludzik, Jozef     {
23081ebf06SWludzik, Jozef         metricValues.push_back({
24081ebf06SWludzik, Jozef             {"MetricId", id},
25081ebf06SWludzik, Jozef             {"MetricProperty", metadata},
26081ebf06SWludzik, Jozef             {"MetricValue", std::to_string(sensorValue)},
27081ebf06SWludzik, Jozef             {"Timestamp",
28081ebf06SWludzik, Jozef              crow::utility::getDateTime(static_cast<time_t>(timestamp))},
29081ebf06SWludzik, Jozef         });
30081ebf06SWludzik, Jozef     }
31081ebf06SWludzik, Jozef 
32081ebf06SWludzik, Jozef     return metricValues;
33081ebf06SWludzik, Jozef }
34081ebf06SWludzik, Jozef 
358d1b46d7Szhanghch05 inline void fillReport(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
36081ebf06SWludzik, Jozef                        const std::string& id,
37081ebf06SWludzik, Jozef                        const std::variant<TimestampReadings>& var)
38081ebf06SWludzik, Jozef {
39081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["@odata.type"] =
40081ebf06SWludzik, Jozef         "#MetricReport.v1_3_0.MetricReport";
41081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["@odata.id"] = telemetry::metricReportUri + id;
42081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["Id"] = id;
43081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["Name"] = id;
44081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["MetricReportDefinition"]["@odata.id"] =
45081ebf06SWludzik, Jozef         telemetry::metricReportDefinitionUri + id;
46081ebf06SWludzik, Jozef 
47081ebf06SWludzik, Jozef     const TimestampReadings* timestampReadings =
48081ebf06SWludzik, Jozef         std::get_if<TimestampReadings>(&var);
49081ebf06SWludzik, Jozef     if (!timestampReadings)
50081ebf06SWludzik, Jozef     {
51081ebf06SWludzik, Jozef         BMCWEB_LOG_ERROR << "Property type mismatch or property is missing";
52081ebf06SWludzik, Jozef         messages::internalError(asyncResp->res);
53081ebf06SWludzik, Jozef         return;
54081ebf06SWludzik, Jozef     }
55081ebf06SWludzik, Jozef 
56081ebf06SWludzik, Jozef     const auto& [timestamp, readings] = *timestampReadings;
57081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["Timestamp"] =
58081ebf06SWludzik, Jozef         crow::utility::getDateTime(static_cast<time_t>(timestamp));
59081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["MetricValues"] = toMetricValues(readings);
60081ebf06SWludzik, Jozef }
61081ebf06SWludzik, Jozef } // namespace telemetry
62081ebf06SWludzik, Jozef 
63*7e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportCollection(App& app)
64081ebf06SWludzik, Jozef {
65*7e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/")
66*7e860f15SJohn Edward Broadbent         .privileges({"Login"})
67*7e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
68*7e860f15SJohn Edward Broadbent             [](const crow::Request&,
69*7e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
708d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
71081ebf06SWludzik, Jozef                     "#MetricReportCollection.MetricReportCollection";
728d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.id"] =
73081ebf06SWludzik, Jozef                     "/redfish/v1/TelemetryService/MetricReports";
748d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
75081ebf06SWludzik, Jozef 
76*7e860f15SJohn Edward Broadbent                 telemetry::getReportCollection(asyncResp,
77*7e860f15SJohn Edward Broadbent                                                telemetry::metricReportUri);
78*7e860f15SJohn Edward Broadbent             });
79081ebf06SWludzik, Jozef }
80081ebf06SWludzik, Jozef 
81*7e860f15SJohn Edward Broadbent inline void requestRoutesMetricReport(App& app)
82081ebf06SWludzik, Jozef {
83*7e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/")
84*7e860f15SJohn Edward Broadbent         .privileges({"Login"})
85*7e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
86*7e860f15SJohn Edward Broadbent             [](const crow::Request&,
87*7e860f15SJohn Edward Broadbent                const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
88*7e860f15SJohn Edward Broadbent                const std::string& id) {
89081ebf06SWludzik, Jozef                 const std::string reportPath = telemetry::getDbusReportPath(id);
90081ebf06SWludzik, Jozef                 crow::connections::systemBus->async_method_call(
91*7e860f15SJohn Edward Broadbent                     [asyncResp, id,
92*7e860f15SJohn Edward Broadbent                      reportPath](const boost::system::error_code& ec) {
93081ebf06SWludzik, Jozef                         if (ec.value() == EBADR ||
94081ebf06SWludzik, Jozef                             ec == boost::system::errc::host_unreachable)
95081ebf06SWludzik, Jozef                         {
96*7e860f15SJohn Edward Broadbent                             messages::resourceNotFound(asyncResp->res,
97*7e860f15SJohn Edward Broadbent                                                        "MetricReport", id);
98081ebf06SWludzik, Jozef                             return;
99081ebf06SWludzik, Jozef                         }
100081ebf06SWludzik, Jozef                         if (ec)
101081ebf06SWludzik, Jozef                         {
102081ebf06SWludzik, Jozef                             BMCWEB_LOG_ERROR << "respHandler DBus error " << ec;
103081ebf06SWludzik, Jozef                             messages::internalError(asyncResp->res);
104081ebf06SWludzik, Jozef                             return;
105081ebf06SWludzik, Jozef                         }
106081ebf06SWludzik, Jozef 
107081ebf06SWludzik, Jozef                         crow::connections::systemBus->async_method_call(
108*7e860f15SJohn Edward Broadbent                             [asyncResp,
109*7e860f15SJohn Edward Broadbent                              id](const boost::system::error_code ec,
110*7e860f15SJohn Edward Broadbent                                  const std::variant<
111*7e860f15SJohn Edward Broadbent                                      telemetry::TimestampReadings>& ret) {
112081ebf06SWludzik, Jozef                                 if (ec)
113081ebf06SWludzik, Jozef                                 {
114*7e860f15SJohn Edward Broadbent                                     BMCWEB_LOG_ERROR
115*7e860f15SJohn Edward Broadbent                                         << "respHandler DBus error " << ec;
116081ebf06SWludzik, Jozef                                     messages::internalError(asyncResp->res);
117081ebf06SWludzik, Jozef                                     return;
118081ebf06SWludzik, Jozef                                 }
119081ebf06SWludzik, Jozef 
120081ebf06SWludzik, Jozef                                 telemetry::fillReport(asyncResp, id, ret);
121081ebf06SWludzik, Jozef                             },
122081ebf06SWludzik, Jozef                             telemetry::service, reportPath,
123081ebf06SWludzik, Jozef                             "org.freedesktop.DBus.Properties", "Get",
124081ebf06SWludzik, Jozef                             telemetry::reportInterface, "Readings");
125081ebf06SWludzik, Jozef                     },
126081ebf06SWludzik, Jozef                     telemetry::service, reportPath, telemetry::reportInterface,
127081ebf06SWludzik, Jozef                     "Update");
128*7e860f15SJohn Edward Broadbent             });
129081ebf06SWludzik, Jozef }
130081ebf06SWludzik, Jozef } // namespace redfish
131