xref: /openbmc/bmcweb/features/redfish/lib/metric_report.hpp (revision 177612aaa0633cf9d5aef0b763a43135cf552d9b)
140e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
240e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3081ebf06SWludzik, Jozef #pragma once
4081ebf06SWludzik, Jozef 
53ccb3adbSEd Tanous #include "app.hpp"
6d7857201SEd Tanous #include "async_resp.hpp"
7d7857201SEd Tanous #include "dbus_singleton.hpp"
8*177612aaSEd Tanous #include "dbus_utility.hpp"
9d7857201SEd Tanous #include "error_messages.hpp"
10d7857201SEd Tanous #include "http_request.hpp"
11d7857201SEd Tanous #include "logging.hpp"
123ccb3adbSEd Tanous #include "query.hpp"
133ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
144028ff77SEd Tanous #include "utils/collection.hpp"
15081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp"
162b82937eSEd Tanous #include "utils/time_utils.hpp"
17081ebf06SWludzik, Jozef 
18d7857201SEd Tanous #include <asm-generic/errno.h>
19d7857201SEd Tanous 
20d7857201SEd Tanous #include <boost/beast/http/verb.hpp>
21ef4c65b7SEd Tanous #include <boost/url/format.hpp>
22d7857201SEd Tanous #include <boost/url/url.hpp>
23d7857201SEd Tanous #include <nlohmann/json.hpp>
241e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
257e860f15SJohn Edward Broadbent 
267a1dbc48SGeorge Liu #include <array>
27d7857201SEd Tanous #include <cstdint>
28d7857201SEd Tanous #include <memory>
29d7857201SEd Tanous #include <string>
307a1dbc48SGeorge Liu #include <string_view>
31d7857201SEd Tanous #include <tuple>
32d7857201SEd Tanous #include <utility>
33d7857201SEd Tanous #include <vector>
347a1dbc48SGeorge Liu 
35081ebf06SWludzik, Jozef namespace redfish
36081ebf06SWludzik, Jozef {
37081ebf06SWludzik, Jozef 
38081ebf06SWludzik, Jozef namespace telemetry
39081ebf06SWludzik, Jozef {
40081ebf06SWludzik, Jozef 
41479e899dSKrzysztof Grobelny using Readings = std::vector<std::tuple<std::string, double, uint64_t>>;
42081ebf06SWludzik, Jozef using TimestampReadings = std::tuple<uint64_t, Readings>;
43081ebf06SWludzik, Jozef 
44081ebf06SWludzik, Jozef inline nlohmann::json toMetricValues(const Readings& readings)
45081ebf06SWludzik, Jozef {
46081ebf06SWludzik, Jozef     nlohmann::json metricValues = nlohmann::json::array_t();
47081ebf06SWludzik, Jozef 
48479e899dSKrzysztof Grobelny     for (const auto& [metadata, sensorValue, timestamp] : readings)
49081ebf06SWludzik, Jozef     {
50613dabeaSEd Tanous         nlohmann::json::object_t metricReport;
51613dabeaSEd Tanous         metricReport["MetricProperty"] = metadata;
52613dabeaSEd Tanous         metricReport["MetricValue"] = std::to_string(sensorValue);
53613dabeaSEd Tanous         metricReport["Timestamp"] =
54613dabeaSEd Tanous             redfish::time_utils::getDateTimeUintMs(timestamp);
55b2ba3072SPatrick Williams         metricValues.emplace_back(std::move(metricReport));
56081ebf06SWludzik, Jozef     }
57081ebf06SWludzik, Jozef 
58081ebf06SWludzik, Jozef     return metricValues;
59081ebf06SWludzik, Jozef }
60081ebf06SWludzik, Jozef 
61c0353249SWludzik, Jozef inline bool fillReport(nlohmann::json& json, const std::string& id,
621e1e598dSJonathan Doman                        const TimestampReadings& timestampReadings)
63081ebf06SWludzik, Jozef {
64c0353249SWludzik, Jozef     json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport";
65ef4c65b7SEd Tanous     json["@odata.id"] = boost::urls::format(
66ef4c65b7SEd Tanous         "/redfish/v1/TelemetryService/MetricReports/{}", id);
67c0353249SWludzik, Jozef     json["Id"] = id;
68c0353249SWludzik, Jozef     json["Name"] = id;
69ef4c65b7SEd Tanous     json["MetricReportDefinition"]["@odata.id"] = boost::urls::format(
70ef4c65b7SEd Tanous         "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", id);
71081ebf06SWludzik, Jozef 
721e1e598dSJonathan Doman     const auto& [timestamp, readings] = timestampReadings;
732b82937eSEd Tanous     json["Timestamp"] = redfish::time_utils::getDateTimeUintMs(timestamp);
74c0353249SWludzik, Jozef     json["MetricValues"] = toMetricValues(readings);
75c0353249SWludzik, Jozef     return true;
76081ebf06SWludzik, Jozef }
77081ebf06SWludzik, Jozef } // namespace telemetry
78081ebf06SWludzik, Jozef 
797e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportCollection(App& app)
80081ebf06SWludzik, Jozef {
817e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/")
82ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReportCollection)
837e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
8445ca1b86SEd Tanous             [&app](const crow::Request& req,
857e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
863ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
8745ca1b86SEd Tanous                 {
8845ca1b86SEd Tanous                     return;
8945ca1b86SEd Tanous                 }
9045ca1b86SEd Tanous 
918d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
92081ebf06SWludzik, Jozef                     "#MetricReportCollection.MetricReportCollection";
93ae9031f0SWilly Tu                 asyncResp->res.jsonValue["@odata.id"] =
94ae9031f0SWilly Tu                     "/redfish/v1/TelemetryService/MetricReports";
958d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
967a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
977a1dbc48SGeorge Liu                     telemetry::reportInterface};
984028ff77SEd Tanous                 collection_util::getCollectionMembers(
99ae9031f0SWilly Tu                     asyncResp,
100bd79bce8SPatrick Williams                     boost::urls::url(
101bd79bce8SPatrick Williams                         "/redfish/v1/TelemetryService/MetricReports"),
102ae9031f0SWilly Tu                     interfaces,
1034028ff77SEd Tanous                     "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
1047e860f15SJohn Edward Broadbent             });
105081ebf06SWludzik, Jozef }
106081ebf06SWludzik, Jozef 
1077e860f15SJohn Edward Broadbent inline void requestRoutesMetricReport(App& app)
108081ebf06SWludzik, Jozef {
1097e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/")
110ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReport)
1117e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
11245ca1b86SEd Tanous             [&app](const crow::Request& req,
1137e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
1147e860f15SJohn Edward Broadbent                    const std::string& id) {
1153ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
11645ca1b86SEd Tanous                 {
11745ca1b86SEd Tanous                     return;
11845ca1b86SEd Tanous                 }
119081ebf06SWludzik, Jozef                 const std::string reportPath = telemetry::getDbusReportPath(id);
120*177612aaSEd Tanous                 dbus::utility::async_method_call(
121*177612aaSEd Tanous                     asyncResp,
122bd79bce8SPatrick Williams                     [asyncResp, id,
123bd79bce8SPatrick Williams                      reportPath](const boost::system::error_code& ec) {
124081ebf06SWludzik, Jozef                         if (ec.value() == EBADR ||
125081ebf06SWludzik, Jozef                             ec == boost::system::errc::host_unreachable)
126081ebf06SWludzik, Jozef                         {
127bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
128bd79bce8SPatrick Williams                                                        "MetricReport", id);
129081ebf06SWludzik, Jozef                             return;
130081ebf06SWludzik, Jozef                         }
131081ebf06SWludzik, Jozef                         if (ec)
132081ebf06SWludzik, Jozef                         {
13362598e31SEd Tanous                             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
134081ebf06SWludzik, Jozef                             messages::internalError(asyncResp->res);
135081ebf06SWludzik, Jozef                             return;
136081ebf06SWludzik, Jozef                         }
137081ebf06SWludzik, Jozef 
138bd79bce8SPatrick Williams                         sdbusplus::asio::getProperty<
139bd79bce8SPatrick Williams                             telemetry::TimestampReadings>(
140bd79bce8SPatrick Williams                             *crow::connections::systemBus, telemetry::service,
141bd79bce8SPatrick Williams                             reportPath, telemetry::reportInterface, "Readings",
142bd79bce8SPatrick Williams                             [asyncResp,
143bd79bce8SPatrick Williams                              id](const boost::system::error_code& ec2,
1441e1e598dSJonathan Doman                                  const telemetry::TimestampReadings& ret) {
1458a592810SEd Tanous                                 if (ec2)
146081ebf06SWludzik, Jozef                                 {
147bd79bce8SPatrick Williams                                     BMCWEB_LOG_ERROR(
148bd79bce8SPatrick Williams                                         "respHandler DBus error {}", ec2);
149081ebf06SWludzik, Jozef                                     messages::internalError(asyncResp->res);
150081ebf06SWludzik, Jozef                                     return;
151081ebf06SWludzik, Jozef                                 }
152081ebf06SWludzik, Jozef 
153bd79bce8SPatrick Williams                                 telemetry::fillReport(asyncResp->res.jsonValue,
154bd79bce8SPatrick Williams                                                       id, ret);
1551e1e598dSJonathan Doman                             });
156081ebf06SWludzik, Jozef                     },
157081ebf06SWludzik, Jozef                     telemetry::service, reportPath, telemetry::reportInterface,
158081ebf06SWludzik, Jozef                     "Update");
1597e860f15SJohn Edward Broadbent             });
160081ebf06SWludzik, Jozef }
161081ebf06SWludzik, Jozef } // namespace redfish
162