xref: /openbmc/bmcweb/features/redfish/lib/metric_report.hpp (revision 40e9b92ec19acffb46f83a6e55b18974da5d708e)
1*40e9b92eSEd Tanous // SPDX-License-Identifier: Apache-2.0
2*40e9b92eSEd Tanous // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3081ebf06SWludzik, Jozef #pragma once
4081ebf06SWludzik, Jozef 
53ccb3adbSEd Tanous #include "app.hpp"
63ccb3adbSEd Tanous #include "dbus_utility.hpp"
73ccb3adbSEd Tanous #include "query.hpp"
83ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
94028ff77SEd Tanous #include "utils/collection.hpp"
10081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp"
112b82937eSEd Tanous #include "utils/time_utils.hpp"
12081ebf06SWludzik, Jozef 
13ef4c65b7SEd Tanous #include <boost/url/format.hpp>
141e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp>
157e860f15SJohn Edward Broadbent 
167a1dbc48SGeorge Liu #include <array>
177a1dbc48SGeorge Liu #include <string_view>
187a1dbc48SGeorge Liu 
19081ebf06SWludzik, Jozef namespace redfish
20081ebf06SWludzik, Jozef {
21081ebf06SWludzik, Jozef 
22081ebf06SWludzik, Jozef namespace telemetry
23081ebf06SWludzik, Jozef {
24081ebf06SWludzik, Jozef 
25479e899dSKrzysztof Grobelny using Readings = std::vector<std::tuple<std::string, double, uint64_t>>;
26081ebf06SWludzik, Jozef using TimestampReadings = std::tuple<uint64_t, Readings>;
27081ebf06SWludzik, Jozef 
28081ebf06SWludzik, Jozef inline nlohmann::json toMetricValues(const Readings& readings)
29081ebf06SWludzik, Jozef {
30081ebf06SWludzik, Jozef     nlohmann::json metricValues = nlohmann::json::array_t();
31081ebf06SWludzik, Jozef 
32479e899dSKrzysztof Grobelny     for (const auto& [metadata, sensorValue, timestamp] : readings)
33081ebf06SWludzik, Jozef     {
34613dabeaSEd Tanous         nlohmann::json::object_t metricReport;
35613dabeaSEd Tanous         metricReport["MetricProperty"] = metadata;
36613dabeaSEd Tanous         metricReport["MetricValue"] = std::to_string(sensorValue);
37613dabeaSEd Tanous         metricReport["Timestamp"] =
38613dabeaSEd Tanous             redfish::time_utils::getDateTimeUintMs(timestamp);
39b2ba3072SPatrick Williams         metricValues.emplace_back(std::move(metricReport));
40081ebf06SWludzik, Jozef     }
41081ebf06SWludzik, Jozef 
42081ebf06SWludzik, Jozef     return metricValues;
43081ebf06SWludzik, Jozef }
44081ebf06SWludzik, Jozef 
45c0353249SWludzik, Jozef inline bool fillReport(nlohmann::json& json, const std::string& id,
461e1e598dSJonathan Doman                        const TimestampReadings& timestampReadings)
47081ebf06SWludzik, Jozef {
48c0353249SWludzik, Jozef     json["@odata.type"] = "#MetricReport.v1_3_0.MetricReport";
49ef4c65b7SEd Tanous     json["@odata.id"] = boost::urls::format(
50ef4c65b7SEd Tanous         "/redfish/v1/TelemetryService/MetricReports/{}", id);
51c0353249SWludzik, Jozef     json["Id"] = id;
52c0353249SWludzik, Jozef     json["Name"] = id;
53ef4c65b7SEd Tanous     json["MetricReportDefinition"]["@odata.id"] = boost::urls::format(
54ef4c65b7SEd Tanous         "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", id);
55081ebf06SWludzik, Jozef 
561e1e598dSJonathan Doman     const auto& [timestamp, readings] = timestampReadings;
572b82937eSEd Tanous     json["Timestamp"] = redfish::time_utils::getDateTimeUintMs(timestamp);
58c0353249SWludzik, Jozef     json["MetricValues"] = toMetricValues(readings);
59c0353249SWludzik, Jozef     return true;
60081ebf06SWludzik, Jozef }
61081ebf06SWludzik, Jozef } // namespace telemetry
62081ebf06SWludzik, Jozef 
637e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportCollection(App& app)
64081ebf06SWludzik, Jozef {
657e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/")
66ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReportCollection)
677e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
6845ca1b86SEd Tanous             [&app](const crow::Request& req,
697e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
703ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
7145ca1b86SEd Tanous                 {
7245ca1b86SEd Tanous                     return;
7345ca1b86SEd Tanous                 }
7445ca1b86SEd Tanous 
758d1b46d7Szhanghch05                 asyncResp->res.jsonValue["@odata.type"] =
76081ebf06SWludzik, Jozef                     "#MetricReportCollection.MetricReportCollection";
77ae9031f0SWilly Tu                 asyncResp->res.jsonValue["@odata.id"] =
78ae9031f0SWilly Tu                     "/redfish/v1/TelemetryService/MetricReports";
798d1b46d7Szhanghch05                 asyncResp->res.jsonValue["Name"] = "Metric Report Collection";
807a1dbc48SGeorge Liu                 constexpr std::array<std::string_view, 1> interfaces{
817a1dbc48SGeorge Liu                     telemetry::reportInterface};
824028ff77SEd Tanous                 collection_util::getCollectionMembers(
83ae9031f0SWilly Tu                     asyncResp,
84bd79bce8SPatrick Williams                     boost::urls::url(
85bd79bce8SPatrick Williams                         "/redfish/v1/TelemetryService/MetricReports"),
86ae9031f0SWilly Tu                     interfaces,
874028ff77SEd Tanous                     "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
887e860f15SJohn Edward Broadbent             });
89081ebf06SWludzik, Jozef }
90081ebf06SWludzik, Jozef 
917e860f15SJohn Edward Broadbent inline void requestRoutesMetricReport(App& app)
92081ebf06SWludzik, Jozef {
937e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReports/<str>/")
94ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReport)
957e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
9645ca1b86SEd Tanous             [&app](const crow::Request& req,
977e860f15SJohn Edward Broadbent                    const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
987e860f15SJohn Edward Broadbent                    const std::string& id) {
993ba00073SCarson Labrado                 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
10045ca1b86SEd Tanous                 {
10145ca1b86SEd Tanous                     return;
10245ca1b86SEd Tanous                 }
103081ebf06SWludzik, Jozef                 const std::string reportPath = telemetry::getDbusReportPath(id);
104081ebf06SWludzik, Jozef                 crow::connections::systemBus->async_method_call(
105bd79bce8SPatrick Williams                     [asyncResp, id,
106bd79bce8SPatrick Williams                      reportPath](const boost::system::error_code& ec) {
107081ebf06SWludzik, Jozef                         if (ec.value() == EBADR ||
108081ebf06SWludzik, Jozef                             ec == boost::system::errc::host_unreachable)
109081ebf06SWludzik, Jozef                         {
110bd79bce8SPatrick Williams                             messages::resourceNotFound(asyncResp->res,
111bd79bce8SPatrick Williams                                                        "MetricReport", id);
112081ebf06SWludzik, Jozef                             return;
113081ebf06SWludzik, Jozef                         }
114081ebf06SWludzik, Jozef                         if (ec)
115081ebf06SWludzik, Jozef                         {
11662598e31SEd Tanous                             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
117081ebf06SWludzik, Jozef                             messages::internalError(asyncResp->res);
118081ebf06SWludzik, Jozef                             return;
119081ebf06SWludzik, Jozef                         }
120081ebf06SWludzik, Jozef 
121bd79bce8SPatrick Williams                         sdbusplus::asio::getProperty<
122bd79bce8SPatrick Williams                             telemetry::TimestampReadings>(
123bd79bce8SPatrick Williams                             *crow::connections::systemBus, telemetry::service,
124bd79bce8SPatrick Williams                             reportPath, telemetry::reportInterface, "Readings",
125bd79bce8SPatrick Williams                             [asyncResp,
126bd79bce8SPatrick Williams                              id](const boost::system::error_code& ec2,
1271e1e598dSJonathan Doman                                  const telemetry::TimestampReadings& ret) {
1288a592810SEd Tanous                                 if (ec2)
129081ebf06SWludzik, Jozef                                 {
130bd79bce8SPatrick Williams                                     BMCWEB_LOG_ERROR(
131bd79bce8SPatrick Williams                                         "respHandler DBus error {}", ec2);
132081ebf06SWludzik, Jozef                                     messages::internalError(asyncResp->res);
133081ebf06SWludzik, Jozef                                     return;
134081ebf06SWludzik, Jozef                                 }
135081ebf06SWludzik, Jozef 
136bd79bce8SPatrick Williams                                 telemetry::fillReport(asyncResp->res.jsonValue,
137bd79bce8SPatrick Williams                                                       id, ret);
1381e1e598dSJonathan Doman                             });
139081ebf06SWludzik, Jozef                     },
140081ebf06SWludzik, Jozef                     telemetry::service, reportPath, telemetry::reportInterface,
141081ebf06SWludzik, Jozef                     "Update");
1427e860f15SJohn Edward Broadbent             });
143081ebf06SWludzik, Jozef }
144081ebf06SWludzik, Jozef } // namespace redfish
145