xref: /openbmc/bmcweb/features/redfish/lib/metric_report_definition.hpp (revision 95bdb5f061023498a4390f17d436517d4be32b29)
1081ebf06SWludzik, Jozef #pragma once
2081ebf06SWludzik, Jozef 
33ccb3adbSEd Tanous #include "app.hpp"
43ccb3adbSEd Tanous #include "dbus_utility.hpp"
5479e899dSKrzysztof Grobelny #include "generated/enums/metric_report_definition.hpp"
63ccb3adbSEd Tanous #include "query.hpp"
73ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
84dbb8aeaSWludzik, Jozef #include "sensors.hpp"
93ccb3adbSEd Tanous #include "utils/collection.hpp"
103ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
11081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp"
12081ebf06SWludzik, Jozef #include "utils/time_utils.hpp"
13081ebf06SWludzik, Jozef 
144dbb8aeaSWludzik, Jozef #include <boost/container/flat_map.hpp>
15ef4c65b7SEd Tanous #include <boost/url/format.hpp>
1689474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
1789474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
184dbb8aeaSWludzik, Jozef 
197a1dbc48SGeorge Liu #include <array>
20fe04d49cSNan Zhou #include <map>
21f19ab44aSSzymon Dompke #include <optional>
22f19ab44aSSzymon Dompke #include <span>
23f19ab44aSSzymon Dompke #include <string>
247a1dbc48SGeorge Liu #include <string_view>
25081ebf06SWludzik, Jozef #include <tuple>
26f19ab44aSSzymon Dompke #include <utility>
27081ebf06SWludzik, Jozef #include <variant>
28f19ab44aSSzymon Dompke #include <vector>
29081ebf06SWludzik, Jozef 
30081ebf06SWludzik, Jozef namespace redfish
31081ebf06SWludzik, Jozef {
32081ebf06SWludzik, Jozef 
33081ebf06SWludzik, Jozef namespace telemetry
34081ebf06SWludzik, Jozef {
35081ebf06SWludzik, Jozef 
36479e899dSKrzysztof Grobelny using ReadingParameters = std::vector<std::tuple<
37479e899dSKrzysztof Grobelny     std::vector<std::tuple<sdbusplus::message::object_path, std::string>>,
38479e899dSKrzysztof Grobelny     std::string, std::string, uint64_t>>;
39479e899dSKrzysztof Grobelny 
409e6c388aSLukasz Kazmierczak inline bool verifyCommonErrors(crow::Response& res, const std::string& id,
419e6c388aSLukasz Kazmierczak                                const boost::system::error_code& ec)
429e6c388aSLukasz Kazmierczak {
439e6c388aSLukasz Kazmierczak     if (ec.value() == EBADR || ec == boost::system::errc::host_unreachable)
449e6c388aSLukasz Kazmierczak     {
459e6c388aSLukasz Kazmierczak         messages::resourceNotFound(res, "MetricReportDefinition", id);
469e6c388aSLukasz Kazmierczak         return false;
479e6c388aSLukasz Kazmierczak     }
489e6c388aSLukasz Kazmierczak 
499e6c388aSLukasz Kazmierczak     if (ec == boost::system::errc::file_exists)
509e6c388aSLukasz Kazmierczak     {
519e6c388aSLukasz Kazmierczak         messages::resourceAlreadyExists(res, "MetricReportDefinition", "Id",
529e6c388aSLukasz Kazmierczak                                         id);
539e6c388aSLukasz Kazmierczak         return false;
549e6c388aSLukasz Kazmierczak     }
559e6c388aSLukasz Kazmierczak 
569e6c388aSLukasz Kazmierczak     if (ec == boost::system::errc::too_many_files_open)
579e6c388aSLukasz Kazmierczak     {
589e6c388aSLukasz Kazmierczak         messages::createLimitReachedForResource(res);
599e6c388aSLukasz Kazmierczak         return false;
609e6c388aSLukasz Kazmierczak     }
619e6c388aSLukasz Kazmierczak 
629e6c388aSLukasz Kazmierczak     if (ec)
639e6c388aSLukasz Kazmierczak     {
649e6c388aSLukasz Kazmierczak         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
659e6c388aSLukasz Kazmierczak         messages::internalError(res);
669e6c388aSLukasz Kazmierczak         return false;
679e6c388aSLukasz Kazmierczak     }
689e6c388aSLukasz Kazmierczak 
699e6c388aSLukasz Kazmierczak     return true;
709e6c388aSLukasz Kazmierczak }
719e6c388aSLukasz Kazmierczak 
72479e899dSKrzysztof Grobelny inline metric_report_definition::ReportActionsEnum
73479e899dSKrzysztof Grobelny     toRedfishReportAction(std::string_view dbusValue)
74479e899dSKrzysztof Grobelny {
75479e899dSKrzysztof Grobelny     if (dbusValue ==
76479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportActions.EmitsReadingsUpdate")
77479e899dSKrzysztof Grobelny     {
78479e899dSKrzysztof Grobelny         return metric_report_definition::ReportActionsEnum::RedfishEvent;
79479e899dSKrzysztof Grobelny     }
80479e899dSKrzysztof Grobelny     if (dbusValue ==
81479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportActions.LogToMetricReportsCollection")
82479e899dSKrzysztof Grobelny     {
83479e899dSKrzysztof Grobelny         return metric_report_definition::ReportActionsEnum::
84479e899dSKrzysztof Grobelny             LogToMetricReportsCollection;
85479e899dSKrzysztof Grobelny     }
86479e899dSKrzysztof Grobelny     return metric_report_definition::ReportActionsEnum::Invalid;
87479e899dSKrzysztof Grobelny }
88479e899dSKrzysztof Grobelny 
89479e899dSKrzysztof Grobelny inline std::string toDbusReportAction(std::string_view redfishValue)
90479e899dSKrzysztof Grobelny {
91479e899dSKrzysztof Grobelny     if (redfishValue == "RedfishEvent")
92479e899dSKrzysztof Grobelny     {
93479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportActions.EmitsReadingsUpdate";
94479e899dSKrzysztof Grobelny     }
95479e899dSKrzysztof Grobelny     if (redfishValue == "LogToMetricReportsCollection")
96479e899dSKrzysztof Grobelny     {
97479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportActions.LogToMetricReportsCollection";
98479e899dSKrzysztof Grobelny     }
99479e899dSKrzysztof Grobelny     return "";
100479e899dSKrzysztof Grobelny }
101479e899dSKrzysztof Grobelny 
102479e899dSKrzysztof Grobelny inline metric_report_definition::MetricReportDefinitionType
103479e899dSKrzysztof Grobelny     toRedfishReportingType(std::string_view dbusValue)
104479e899dSKrzysztof Grobelny {
105479e899dSKrzysztof Grobelny     if (dbusValue ==
106479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportingType.OnChange")
107479e899dSKrzysztof Grobelny     {
108479e899dSKrzysztof Grobelny         return metric_report_definition::MetricReportDefinitionType::OnChange;
109479e899dSKrzysztof Grobelny     }
110479e899dSKrzysztof Grobelny     if (dbusValue ==
111479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportingType.OnRequest")
112479e899dSKrzysztof Grobelny     {
113479e899dSKrzysztof Grobelny         return metric_report_definition::MetricReportDefinitionType::OnRequest;
114479e899dSKrzysztof Grobelny     }
115479e899dSKrzysztof Grobelny     if (dbusValue ==
116479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportingType.Periodic")
117479e899dSKrzysztof Grobelny     {
118479e899dSKrzysztof Grobelny         return metric_report_definition::MetricReportDefinitionType::Periodic;
119479e899dSKrzysztof Grobelny     }
120479e899dSKrzysztof Grobelny     return metric_report_definition::MetricReportDefinitionType::Invalid;
121479e899dSKrzysztof Grobelny }
122479e899dSKrzysztof Grobelny 
123479e899dSKrzysztof Grobelny inline std::string toDbusReportingType(std::string_view redfishValue)
124479e899dSKrzysztof Grobelny {
125479e899dSKrzysztof Grobelny     if (redfishValue == "OnChange")
126479e899dSKrzysztof Grobelny     {
127479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportingType.OnChange";
128479e899dSKrzysztof Grobelny     }
129479e899dSKrzysztof Grobelny     if (redfishValue == "OnRequest")
130479e899dSKrzysztof Grobelny     {
131479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportingType.OnRequest";
132479e899dSKrzysztof Grobelny     }
133479e899dSKrzysztof Grobelny     if (redfishValue == "Periodic")
134479e899dSKrzysztof Grobelny     {
135479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportingType.Periodic";
136479e899dSKrzysztof Grobelny     }
137479e899dSKrzysztof Grobelny     return "";
138479e899dSKrzysztof Grobelny }
139479e899dSKrzysztof Grobelny 
140479e899dSKrzysztof Grobelny inline metric_report_definition::CollectionTimeScope
141479e899dSKrzysztof Grobelny     toRedfishCollectionTimeScope(std::string_view dbusValue)
142479e899dSKrzysztof Grobelny {
143479e899dSKrzysztof Grobelny     if (dbusValue ==
144479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Point")
145479e899dSKrzysztof Grobelny     {
146479e899dSKrzysztof Grobelny         return metric_report_definition::CollectionTimeScope::Point;
147479e899dSKrzysztof Grobelny     }
148479e899dSKrzysztof Grobelny     if (dbusValue ==
149479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Interval")
150479e899dSKrzysztof Grobelny     {
151479e899dSKrzysztof Grobelny         return metric_report_definition::CollectionTimeScope::Interval;
152479e899dSKrzysztof Grobelny     }
153479e899dSKrzysztof Grobelny     if (dbusValue ==
154479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.StartupInterval")
155479e899dSKrzysztof Grobelny     {
156479e899dSKrzysztof Grobelny         return metric_report_definition::CollectionTimeScope::StartupInterval;
157479e899dSKrzysztof Grobelny     }
158479e899dSKrzysztof Grobelny     return metric_report_definition::CollectionTimeScope::Invalid;
159479e899dSKrzysztof Grobelny }
160479e899dSKrzysztof Grobelny 
161479e899dSKrzysztof Grobelny inline std::string toDbusCollectionTimeScope(std::string_view redfishValue)
162479e899dSKrzysztof Grobelny {
163479e899dSKrzysztof Grobelny     if (redfishValue == "Point")
164479e899dSKrzysztof Grobelny     {
165479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Point";
166479e899dSKrzysztof Grobelny     }
167479e899dSKrzysztof Grobelny     if (redfishValue == "Interval")
168479e899dSKrzysztof Grobelny     {
169479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Interval";
170479e899dSKrzysztof Grobelny     }
171479e899dSKrzysztof Grobelny     if (redfishValue == "StartupInterval")
172479e899dSKrzysztof Grobelny     {
173479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.StartupInterval";
174479e899dSKrzysztof Grobelny     }
175479e899dSKrzysztof Grobelny     return "";
176479e899dSKrzysztof Grobelny }
177479e899dSKrzysztof Grobelny 
178479e899dSKrzysztof Grobelny inline metric_report_definition::ReportUpdatesEnum
179479e899dSKrzysztof Grobelny     toRedfishReportUpdates(std::string_view dbusValue)
180479e899dSKrzysztof Grobelny {
181479e899dSKrzysztof Grobelny     if (dbusValue ==
182479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportUpdates.Overwrite")
183479e899dSKrzysztof Grobelny     {
184479e899dSKrzysztof Grobelny         return metric_report_definition::ReportUpdatesEnum::Overwrite;
185479e899dSKrzysztof Grobelny     }
186479e899dSKrzysztof Grobelny     if (dbusValue ==
187479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendWrapsWhenFull")
188479e899dSKrzysztof Grobelny     {
189479e899dSKrzysztof Grobelny         return metric_report_definition::ReportUpdatesEnum::AppendWrapsWhenFull;
190479e899dSKrzysztof Grobelny     }
191479e899dSKrzysztof Grobelny     if (dbusValue ==
192479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendStopsWhenFull")
193479e899dSKrzysztof Grobelny     {
194479e899dSKrzysztof Grobelny         return metric_report_definition::ReportUpdatesEnum::AppendStopsWhenFull;
195479e899dSKrzysztof Grobelny     }
196479e899dSKrzysztof Grobelny     return metric_report_definition::ReportUpdatesEnum::Invalid;
197479e899dSKrzysztof Grobelny }
198479e899dSKrzysztof Grobelny 
199479e899dSKrzysztof Grobelny inline std::string toDbusReportUpdates(std::string_view redfishValue)
200479e899dSKrzysztof Grobelny {
201479e899dSKrzysztof Grobelny     if (redfishValue == "Overwrite")
202479e899dSKrzysztof Grobelny     {
203479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.Overwrite";
204479e899dSKrzysztof Grobelny     }
205479e899dSKrzysztof Grobelny     if (redfishValue == "AppendWrapsWhenFull")
206479e899dSKrzysztof Grobelny     {
207479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendWrapsWhenFull";
208479e899dSKrzysztof Grobelny     }
209479e899dSKrzysztof Grobelny     if (redfishValue == "AppendStopsWhenFull")
210479e899dSKrzysztof Grobelny     {
211479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendStopsWhenFull";
212479e899dSKrzysztof Grobelny     }
213479e899dSKrzysztof Grobelny     return "";
214479e899dSKrzysztof Grobelny }
215081ebf06SWludzik, Jozef 
216f19ab44aSSzymon Dompke inline std::optional<nlohmann::json::array_t> getLinkedTriggers(
217f19ab44aSSzymon Dompke     std::span<const sdbusplus::message::object_path> triggerPaths)
218f19ab44aSSzymon Dompke {
219f19ab44aSSzymon Dompke     nlohmann::json::array_t triggers;
220f19ab44aSSzymon Dompke 
221f19ab44aSSzymon Dompke     for (const sdbusplus::message::object_path& path : triggerPaths)
222f19ab44aSSzymon Dompke     {
223f19ab44aSSzymon Dompke         if (path.parent_path() !=
224f19ab44aSSzymon Dompke             "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService")
225f19ab44aSSzymon Dompke         {
22662598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Triggers contains invalid value: {}",
22762598e31SEd Tanous                              path.str);
228f19ab44aSSzymon Dompke             return std::nullopt;
229f19ab44aSSzymon Dompke         }
230f19ab44aSSzymon Dompke 
231f19ab44aSSzymon Dompke         std::string id = path.filename();
232f19ab44aSSzymon Dompke         if (id.empty())
233f19ab44aSSzymon Dompke         {
23462598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Triggers contains invalid value: {}",
23562598e31SEd Tanous                              path.str);
236f19ab44aSSzymon Dompke             return std::nullopt;
237f19ab44aSSzymon Dompke         }
238f19ab44aSSzymon Dompke         nlohmann::json::object_t trigger;
239f19ab44aSSzymon Dompke         trigger["@odata.id"] =
240f19ab44aSSzymon Dompke             boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
241f19ab44aSSzymon Dompke         triggers.emplace_back(std::move(trigger));
242f19ab44aSSzymon Dompke     }
243f19ab44aSSzymon Dompke 
244f19ab44aSSzymon Dompke     return triggers;
245f19ab44aSSzymon Dompke }
246f19ab44aSSzymon Dompke 
247b9d36b47SEd Tanous inline void
248b9d36b47SEd Tanous     fillReportDefinition(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
249b9d36b47SEd Tanous                          const std::string& id,
250479e899dSKrzysztof Grobelny                          const dbus::utility::DBusPropertiesMap& properties)
251081ebf06SWludzik, Jozef {
252479e899dSKrzysztof Grobelny     std::vector<std::string> reportActions;
253479e899dSKrzysztof Grobelny     ReadingParameters readingParams;
254479e899dSKrzysztof Grobelny     std::string reportingType;
255479e899dSKrzysztof Grobelny     std::string reportUpdates;
256479e899dSKrzysztof Grobelny     std::string name;
257479e899dSKrzysztof Grobelny     uint64_t appendLimit = 0;
258479e899dSKrzysztof Grobelny     uint64_t interval = 0;
259479e899dSKrzysztof Grobelny     bool enabled = false;
260f19ab44aSSzymon Dompke     std::vector<sdbusplus::message::object_path> triggers;
26189474494SKrzysztof Grobelny 
26289474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
263479e899dSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ReportingType",
264479e899dSKrzysztof Grobelny         reportingType, "Interval", interval, "ReportActions", reportActions,
265479e899dSKrzysztof Grobelny         "ReportUpdates", reportUpdates, "AppendLimit", appendLimit,
266f19ab44aSSzymon Dompke         "ReadingParameters", readingParams, "Name", name, "Enabled", enabled,
267f19ab44aSSzymon Dompke         "Triggers", triggers);
26889474494SKrzysztof Grobelny 
26989474494SKrzysztof Grobelny     if (!success)
270081ebf06SWludzik, Jozef     {
271081ebf06SWludzik, Jozef         messages::internalError(asyncResp->res);
272081ebf06SWludzik, Jozef         return;
273081ebf06SWludzik, Jozef     }
274081ebf06SWludzik, Jozef 
275479e899dSKrzysztof Grobelny     metric_report_definition::MetricReportDefinitionType redfishReportingType =
276479e899dSKrzysztof Grobelny         toRedfishReportingType(reportingType);
277479e899dSKrzysztof Grobelny     if (redfishReportingType ==
278479e899dSKrzysztof Grobelny         metric_report_definition::MetricReportDefinitionType::Invalid)
279081ebf06SWludzik, Jozef     {
280479e899dSKrzysztof Grobelny         messages::internalError(asyncResp->res);
281479e899dSKrzysztof Grobelny         return;
282081ebf06SWludzik, Jozef     }
28389474494SKrzysztof Grobelny 
284479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["MetricReportDefinitionType"] =
285479e899dSKrzysztof Grobelny         redfishReportingType;
286479e899dSKrzysztof Grobelny 
287f19ab44aSSzymon Dompke     std::optional<nlohmann::json::array_t> linkedTriggers =
288f19ab44aSSzymon Dompke         getLinkedTriggers(triggers);
289f19ab44aSSzymon Dompke     if (!linkedTriggers)
290f19ab44aSSzymon Dompke     {
291f19ab44aSSzymon Dompke         messages::internalError(asyncResp->res);
292f19ab44aSSzymon Dompke         return;
293f19ab44aSSzymon Dompke     }
294f19ab44aSSzymon Dompke 
295f19ab44aSSzymon Dompke     asyncResp->res.jsonValue["Links"]["Triggers"] = std::move(*linkedTriggers);
296f19ab44aSSzymon Dompke 
297479e899dSKrzysztof Grobelny     nlohmann::json::array_t redfishReportActions;
298479e899dSKrzysztof Grobelny     for (const std::string& action : reportActions)
299081ebf06SWludzik, Jozef     {
300479e899dSKrzysztof Grobelny         metric_report_definition::ReportActionsEnum redfishAction =
301479e899dSKrzysztof Grobelny             toRedfishReportAction(action);
302479e899dSKrzysztof Grobelny         if (redfishAction ==
303479e899dSKrzysztof Grobelny             metric_report_definition::ReportActionsEnum::Invalid)
304479e899dSKrzysztof Grobelny         {
305479e899dSKrzysztof Grobelny             messages::internalError(asyncResp->res);
306479e899dSKrzysztof Grobelny             return;
307081ebf06SWludzik, Jozef         }
308081ebf06SWludzik, Jozef 
309479e899dSKrzysztof Grobelny         redfishReportActions.emplace_back(redfishAction);
310479e899dSKrzysztof Grobelny     }
311479e899dSKrzysztof Grobelny 
312479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["ReportActions"] = std::move(redfishReportActions);
313479e899dSKrzysztof Grobelny 
314479e899dSKrzysztof Grobelny     nlohmann::json::array_t metrics = nlohmann::json::array();
315479e899dSKrzysztof Grobelny     for (const auto& [sensorData, collectionFunction, collectionTimeScope,
316479e899dSKrzysztof Grobelny                       collectionDuration] : readingParams)
31789474494SKrzysztof Grobelny     {
318479e899dSKrzysztof Grobelny         nlohmann::json::array_t metricProperties;
319479e899dSKrzysztof Grobelny 
320479e899dSKrzysztof Grobelny         for (const auto& [sensorPath, sensorMetadata] : sensorData)
321081ebf06SWludzik, Jozef         {
322479e899dSKrzysztof Grobelny             metricProperties.emplace_back(sensorMetadata);
323479e899dSKrzysztof Grobelny         }
324479e899dSKrzysztof Grobelny 
325613dabeaSEd Tanous         nlohmann::json::object_t metric;
326479e899dSKrzysztof Grobelny 
327479e899dSKrzysztof Grobelny         metric_report_definition::CalculationAlgorithmEnum
328479e899dSKrzysztof Grobelny             redfishCollectionFunction =
329479e899dSKrzysztof Grobelny                 telemetry::toRedfishCollectionFunction(collectionFunction);
330479e899dSKrzysztof Grobelny         if (redfishCollectionFunction ==
331479e899dSKrzysztof Grobelny             metric_report_definition::CalculationAlgorithmEnum::Invalid)
332479e899dSKrzysztof Grobelny         {
333479e899dSKrzysztof Grobelny             messages::internalError(asyncResp->res);
334479e899dSKrzysztof Grobelny             return;
335479e899dSKrzysztof Grobelny         }
336479e899dSKrzysztof Grobelny         metric["CollectionFunction"] = redfishCollectionFunction;
337479e899dSKrzysztof Grobelny 
338479e899dSKrzysztof Grobelny         metric_report_definition::CollectionTimeScope
339479e899dSKrzysztof Grobelny             redfishCollectionTimeScope =
340479e899dSKrzysztof Grobelny                 toRedfishCollectionTimeScope(collectionTimeScope);
341479e899dSKrzysztof Grobelny         if (redfishCollectionTimeScope ==
342479e899dSKrzysztof Grobelny             metric_report_definition::CollectionTimeScope::Invalid)
343479e899dSKrzysztof Grobelny         {
344479e899dSKrzysztof Grobelny             messages::internalError(asyncResp->res);
345479e899dSKrzysztof Grobelny             return;
346479e899dSKrzysztof Grobelny         }
347479e899dSKrzysztof Grobelny         metric["CollectionTimeScope"] = redfishCollectionTimeScope;
348479e899dSKrzysztof Grobelny 
349479e899dSKrzysztof Grobelny         metric["MetricProperties"] = std::move(metricProperties);
350479e899dSKrzysztof Grobelny         metric["CollectionDuration"] = time_utils::toDurationString(
351479e899dSKrzysztof Grobelny             std::chrono::milliseconds(collectionDuration));
352b2ba3072SPatrick Williams         metrics.emplace_back(std::move(metric));
353081ebf06SWludzik, Jozef     }
354479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["Metrics"] = std::move(metrics);
355479e899dSKrzysztof Grobelny 
356479e899dSKrzysztof Grobelny     if (enabled)
357479e899dSKrzysztof Grobelny     {
358479e899dSKrzysztof Grobelny         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
359479e899dSKrzysztof Grobelny     }
360479e899dSKrzysztof Grobelny     else
361479e899dSKrzysztof Grobelny     {
362479e899dSKrzysztof Grobelny         asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
36389474494SKrzysztof Grobelny     }
36489474494SKrzysztof Grobelny 
365479e899dSKrzysztof Grobelny     metric_report_definition::ReportUpdatesEnum redfishReportUpdates =
366479e899dSKrzysztof Grobelny         toRedfishReportUpdates(reportUpdates);
367479e899dSKrzysztof Grobelny     if (redfishReportUpdates ==
368479e899dSKrzysztof Grobelny         metric_report_definition::ReportUpdatesEnum::Invalid)
36989474494SKrzysztof Grobelny     {
370479e899dSKrzysztof Grobelny         messages::internalError(asyncResp->res);
371479e899dSKrzysztof Grobelny         return;
37289474494SKrzysztof Grobelny     }
373479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["ReportUpdates"] = redfishReportUpdates;
37489474494SKrzysztof Grobelny 
375479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["MetricReportDefinitionEnabled"] = enabled;
376479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["AppendLimit"] = appendLimit;
377479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["Name"] = name;
378081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] =
379479e899dSKrzysztof Grobelny         time_utils::toDurationString(std::chrono::milliseconds(interval));
380479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["@odata.type"] =
381479e899dSKrzysztof Grobelny         "#MetricReportDefinition.v1_3_0.MetricReportDefinition";
382479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
383479e899dSKrzysztof Grobelny         "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", id);
384479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["Id"] = id;
385479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = boost::urls::format(
386479e899dSKrzysztof Grobelny         "/redfish/v1/TelemetryService/MetricReports/{}", id);
38789474494SKrzysztof Grobelny }
38889474494SKrzysztof Grobelny 
3894dbb8aeaSWludzik, Jozef struct AddReportArgs
3904dbb8aeaSWludzik, Jozef {
391479e899dSKrzysztof Grobelny     struct MetricArgs
392479e899dSKrzysztof Grobelny     {
393479e899dSKrzysztof Grobelny         std::vector<std::string> uris;
394479e899dSKrzysztof Grobelny         std::string collectionFunction;
395479e899dSKrzysztof Grobelny         std::string collectionTimeScope;
396479e899dSKrzysztof Grobelny         uint64_t collectionDuration = 0;
397479e899dSKrzysztof Grobelny     };
398479e899dSKrzysztof Grobelny 
399479e899dSKrzysztof Grobelny     std::string id;
4004dbb8aeaSWludzik, Jozef     std::string name;
4014dbb8aeaSWludzik, Jozef     std::string reportingType;
402479e899dSKrzysztof Grobelny     std::string reportUpdates;
403479e899dSKrzysztof Grobelny     uint64_t appendLimit = std::numeric_limits<uint64_t>::max();
404479e899dSKrzysztof Grobelny     std::vector<std::string> reportActions;
405479e899dSKrzysztof Grobelny     uint64_t interval = std::numeric_limits<uint64_t>::max();
406479e899dSKrzysztof Grobelny     std::vector<MetricArgs> metrics;
407479e899dSKrzysztof Grobelny     bool metricReportDefinitionEnabled = true;
4084dbb8aeaSWludzik, Jozef };
4094dbb8aeaSWludzik, Jozef 
4104dbb8aeaSWludzik, Jozef inline bool toDbusReportActions(crow::Response& res,
411479e899dSKrzysztof Grobelny                                 const std::vector<std::string>& actions,
4129e6c388aSLukasz Kazmierczak                                 std::vector<std::string>& outReportActions)
4134dbb8aeaSWludzik, Jozef {
4144dbb8aeaSWludzik, Jozef     size_t index = 0;
415479e899dSKrzysztof Grobelny     for (const std::string& action : actions)
4164dbb8aeaSWludzik, Jozef     {
417479e899dSKrzysztof Grobelny         std::string dbusReportAction = toDbusReportAction(action);
418479e899dSKrzysztof Grobelny         if (dbusReportAction.empty())
4194dbb8aeaSWludzik, Jozef         {
4209e6c388aSLukasz Kazmierczak             messages::propertyValueNotInList(
4219e6c388aSLukasz Kazmierczak                 res, action, "ReportActions/" + std::to_string(index));
4224dbb8aeaSWludzik, Jozef             return false;
4234dbb8aeaSWludzik, Jozef         }
424479e899dSKrzysztof Grobelny 
4259e6c388aSLukasz Kazmierczak         outReportActions.emplace_back(std::move(dbusReportAction));
4264dbb8aeaSWludzik, Jozef         index++;
4274dbb8aeaSWludzik, Jozef     }
4284dbb8aeaSWludzik, Jozef     return true;
4294dbb8aeaSWludzik, Jozef }
4304dbb8aeaSWludzik, Jozef 
431479e899dSKrzysztof Grobelny inline bool getUserMetric(crow::Response& res, nlohmann::json& metric,
432479e899dSKrzysztof Grobelny                           AddReportArgs::MetricArgs& metricArgs)
433479e899dSKrzysztof Grobelny {
434479e899dSKrzysztof Grobelny     std::optional<std::vector<std::string>> uris;
435479e899dSKrzysztof Grobelny     std::optional<std::string> collectionDurationStr;
436479e899dSKrzysztof Grobelny     std::optional<std::string> collectionFunction;
437479e899dSKrzysztof Grobelny     std::optional<std::string> collectionTimeScopeStr;
438479e899dSKrzysztof Grobelny 
439479e899dSKrzysztof Grobelny     if (!json_util::readJson(metric, res, "MetricProperties", uris,
440479e899dSKrzysztof Grobelny                              "CollectionFunction", collectionFunction,
441479e899dSKrzysztof Grobelny                              "CollectionTimeScope", collectionTimeScopeStr,
442479e899dSKrzysztof Grobelny                              "CollectionDuration", collectionDurationStr))
443479e899dSKrzysztof Grobelny     {
444479e899dSKrzysztof Grobelny         return false;
445479e899dSKrzysztof Grobelny     }
446479e899dSKrzysztof Grobelny 
447479e899dSKrzysztof Grobelny     if (uris)
448479e899dSKrzysztof Grobelny     {
449479e899dSKrzysztof Grobelny         metricArgs.uris = std::move(*uris);
450479e899dSKrzysztof Grobelny     }
451479e899dSKrzysztof Grobelny 
452479e899dSKrzysztof Grobelny     if (collectionFunction)
453479e899dSKrzysztof Grobelny     {
454479e899dSKrzysztof Grobelny         std::string dbusCollectionFunction =
455479e899dSKrzysztof Grobelny             telemetry::toDbusCollectionFunction(*collectionFunction);
456479e899dSKrzysztof Grobelny         if (dbusCollectionFunction.empty())
457479e899dSKrzysztof Grobelny         {
458479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "CollectionFunction",
459479e899dSKrzysztof Grobelny                                              *collectionFunction);
460479e899dSKrzysztof Grobelny             return false;
461479e899dSKrzysztof Grobelny         }
462479e899dSKrzysztof Grobelny         metricArgs.collectionFunction = std::move(dbusCollectionFunction);
463479e899dSKrzysztof Grobelny     }
464479e899dSKrzysztof Grobelny 
465479e899dSKrzysztof Grobelny     if (collectionTimeScopeStr)
466479e899dSKrzysztof Grobelny     {
467479e899dSKrzysztof Grobelny         std::string dbusCollectionTimeScope =
468479e899dSKrzysztof Grobelny             toDbusCollectionTimeScope(*collectionTimeScopeStr);
469479e899dSKrzysztof Grobelny         if (dbusCollectionTimeScope.empty())
470479e899dSKrzysztof Grobelny         {
471479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "CollectionTimeScope",
472479e899dSKrzysztof Grobelny                                              *collectionTimeScopeStr);
473479e899dSKrzysztof Grobelny             return false;
474479e899dSKrzysztof Grobelny         }
475479e899dSKrzysztof Grobelny         metricArgs.collectionTimeScope = std::move(dbusCollectionTimeScope);
476479e899dSKrzysztof Grobelny     }
477479e899dSKrzysztof Grobelny 
478479e899dSKrzysztof Grobelny     if (collectionDurationStr)
479479e899dSKrzysztof Grobelny     {
480479e899dSKrzysztof Grobelny         std::optional<std::chrono::milliseconds> duration =
481479e899dSKrzysztof Grobelny             time_utils::fromDurationString(*collectionDurationStr);
482479e899dSKrzysztof Grobelny 
483479e899dSKrzysztof Grobelny         if (!duration || duration->count() < 0)
484479e899dSKrzysztof Grobelny         {
485479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "CollectionDuration",
486479e899dSKrzysztof Grobelny                                              *collectionDurationStr);
487479e899dSKrzysztof Grobelny             return false;
488479e899dSKrzysztof Grobelny         }
489479e899dSKrzysztof Grobelny 
490479e899dSKrzysztof Grobelny         metricArgs.collectionDuration =
491479e899dSKrzysztof Grobelny             static_cast<uint64_t>(duration->count());
492479e899dSKrzysztof Grobelny     }
493479e899dSKrzysztof Grobelny 
494479e899dSKrzysztof Grobelny     return true;
495479e899dSKrzysztof Grobelny }
496479e899dSKrzysztof Grobelny 
497479e899dSKrzysztof Grobelny inline bool getUserMetrics(crow::Response& res,
498479e899dSKrzysztof Grobelny                            std::span<nlohmann::json> metrics,
499479e899dSKrzysztof Grobelny                            std::vector<AddReportArgs::MetricArgs>& result)
500479e899dSKrzysztof Grobelny {
501479e899dSKrzysztof Grobelny     result.reserve(metrics.size());
502479e899dSKrzysztof Grobelny 
503479e899dSKrzysztof Grobelny     for (nlohmann::json& m : metrics)
504479e899dSKrzysztof Grobelny     {
505479e899dSKrzysztof Grobelny         AddReportArgs::MetricArgs metricArgs;
506479e899dSKrzysztof Grobelny 
507479e899dSKrzysztof Grobelny         if (!getUserMetric(res, m, metricArgs))
508479e899dSKrzysztof Grobelny         {
509479e899dSKrzysztof Grobelny             return false;
510479e899dSKrzysztof Grobelny         }
511479e899dSKrzysztof Grobelny 
512479e899dSKrzysztof Grobelny         result.emplace_back(std::move(metricArgs));
513479e899dSKrzysztof Grobelny     }
514479e899dSKrzysztof Grobelny 
515479e899dSKrzysztof Grobelny     return true;
516479e899dSKrzysztof Grobelny }
517479e899dSKrzysztof Grobelny 
5184dbb8aeaSWludzik, Jozef inline bool getUserParameters(crow::Response& res, const crow::Request& req,
5194dbb8aeaSWludzik, Jozef                               AddReportArgs& args)
5204dbb8aeaSWludzik, Jozef {
521479e899dSKrzysztof Grobelny     std::optional<std::string> id;
522479e899dSKrzysztof Grobelny     std::optional<std::string> name;
523479e899dSKrzysztof Grobelny     std::optional<std::string> reportingTypeStr;
524479e899dSKrzysztof Grobelny     std::optional<std::string> reportUpdatesStr;
525479e899dSKrzysztof Grobelny     std::optional<uint64_t> appendLimit;
526479e899dSKrzysztof Grobelny     std::optional<bool> metricReportDefinitionEnabled;
527479e899dSKrzysztof Grobelny     std::optional<std::vector<nlohmann::json>> metrics;
528479e899dSKrzysztof Grobelny     std::optional<std::vector<std::string>> reportActionsStr;
5294dbb8aeaSWludzik, Jozef     std::optional<nlohmann::json> schedule;
530479e899dSKrzysztof Grobelny 
531479e899dSKrzysztof Grobelny     if (!json_util::readJsonPatch(
532479e899dSKrzysztof Grobelny             req, res, "Id", id, "Name", name, "Metrics", metrics,
533479e899dSKrzysztof Grobelny             "MetricReportDefinitionType", reportingTypeStr, "ReportUpdates",
534479e899dSKrzysztof Grobelny             reportUpdatesStr, "AppendLimit", appendLimit, "ReportActions",
535479e899dSKrzysztof Grobelny             reportActionsStr, "Schedule", schedule,
536479e899dSKrzysztof Grobelny             "MetricReportDefinitionEnabled", metricReportDefinitionEnabled))
5374dbb8aeaSWludzik, Jozef     {
5384dbb8aeaSWludzik, Jozef         return false;
5394dbb8aeaSWludzik, Jozef     }
5404dbb8aeaSWludzik, Jozef 
541479e899dSKrzysztof Grobelny     if (id)
542479e899dSKrzysztof Grobelny     {
543479e899dSKrzysztof Grobelny         constexpr const char* allowedCharactersInId =
5444dbb8aeaSWludzik, Jozef             "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
545479e899dSKrzysztof Grobelny         if (id->empty() ||
546479e899dSKrzysztof Grobelny             id->find_first_not_of(allowedCharactersInId) != std::string::npos)
5474dbb8aeaSWludzik, Jozef         {
548479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "Id", *id);
5494dbb8aeaSWludzik, Jozef             return false;
5504dbb8aeaSWludzik, Jozef         }
551479e899dSKrzysztof Grobelny         args.id = *id;
552479e899dSKrzysztof Grobelny     }
5534dbb8aeaSWludzik, Jozef 
554479e899dSKrzysztof Grobelny     if (name)
5554dbb8aeaSWludzik, Jozef     {
556479e899dSKrzysztof Grobelny         args.name = *name;
557479e899dSKrzysztof Grobelny     }
558479e899dSKrzysztof Grobelny 
559479e899dSKrzysztof Grobelny     if (reportingTypeStr)
560479e899dSKrzysztof Grobelny     {
561479e899dSKrzysztof Grobelny         std::string dbusReportingType = toDbusReportingType(*reportingTypeStr);
562479e899dSKrzysztof Grobelny         if (dbusReportingType.empty())
563479e899dSKrzysztof Grobelny         {
564479e899dSKrzysztof Grobelny             messages::propertyValueNotInList(res, *reportingTypeStr,
5654dbb8aeaSWludzik, Jozef                                              "MetricReportDefinitionType");
5664dbb8aeaSWludzik, Jozef             return false;
5674dbb8aeaSWludzik, Jozef         }
568479e899dSKrzysztof Grobelny         args.reportingType = dbusReportingType;
569479e899dSKrzysztof Grobelny     }
5704dbb8aeaSWludzik, Jozef 
571479e899dSKrzysztof Grobelny     if (reportUpdatesStr)
572479e899dSKrzysztof Grobelny     {
573479e899dSKrzysztof Grobelny         std::string dbusReportUpdates = toDbusReportUpdates(*reportUpdatesStr);
574479e899dSKrzysztof Grobelny         if (dbusReportUpdates.empty())
575479e899dSKrzysztof Grobelny         {
576479e899dSKrzysztof Grobelny             messages::propertyValueNotInList(res, *reportUpdatesStr,
577479e899dSKrzysztof Grobelny                                              "ReportUpdates");
578479e899dSKrzysztof Grobelny             return false;
579479e899dSKrzysztof Grobelny         }
580479e899dSKrzysztof Grobelny         args.reportUpdates = dbusReportUpdates;
581479e899dSKrzysztof Grobelny     }
582479e899dSKrzysztof Grobelny 
583479e899dSKrzysztof Grobelny     if (appendLimit)
584479e899dSKrzysztof Grobelny     {
585479e899dSKrzysztof Grobelny         args.appendLimit = *appendLimit;
586479e899dSKrzysztof Grobelny     }
587479e899dSKrzysztof Grobelny 
588479e899dSKrzysztof Grobelny     if (metricReportDefinitionEnabled)
589479e899dSKrzysztof Grobelny     {
590479e899dSKrzysztof Grobelny         args.metricReportDefinitionEnabled = *metricReportDefinitionEnabled;
591479e899dSKrzysztof Grobelny     }
592479e899dSKrzysztof Grobelny 
593479e899dSKrzysztof Grobelny     if (reportActionsStr)
594479e899dSKrzysztof Grobelny     {
5959e6c388aSLukasz Kazmierczak         if (!toDbusReportActions(res, *reportActionsStr, args.reportActions))
5964dbb8aeaSWludzik, Jozef         {
5974dbb8aeaSWludzik, Jozef             return false;
5984dbb8aeaSWludzik, Jozef         }
599479e899dSKrzysztof Grobelny     }
6004dbb8aeaSWludzik, Jozef 
601479e899dSKrzysztof Grobelny     if (reportingTypeStr == "Periodic")
6024dbb8aeaSWludzik, Jozef     {
6034dbb8aeaSWludzik, Jozef         if (!schedule)
6044dbb8aeaSWludzik, Jozef         {
6054dbb8aeaSWludzik, Jozef             messages::createFailedMissingReqProperties(res, "Schedule");
6064dbb8aeaSWludzik, Jozef             return false;
6074dbb8aeaSWludzik, Jozef         }
6084dbb8aeaSWludzik, Jozef 
6094dbb8aeaSWludzik, Jozef         std::string durationStr;
6104dbb8aeaSWludzik, Jozef         if (!json_util::readJson(*schedule, res, "RecurrenceInterval",
6114dbb8aeaSWludzik, Jozef                                  durationStr))
6124dbb8aeaSWludzik, Jozef         {
6134dbb8aeaSWludzik, Jozef             return false;
6144dbb8aeaSWludzik, Jozef         }
6154dbb8aeaSWludzik, Jozef 
6164dbb8aeaSWludzik, Jozef         std::optional<std::chrono::milliseconds> durationNum =
6174dbb8aeaSWludzik, Jozef             time_utils::fromDurationString(durationStr);
618479e899dSKrzysztof Grobelny         if (!durationNum || durationNum->count() < 0)
6194dbb8aeaSWludzik, Jozef         {
6204dbb8aeaSWludzik, Jozef             messages::propertyValueIncorrect(res, "RecurrenceInterval",
6214dbb8aeaSWludzik, Jozef                                              durationStr);
6224dbb8aeaSWludzik, Jozef             return false;
6234dbb8aeaSWludzik, Jozef         }
6244dbb8aeaSWludzik, Jozef         args.interval = static_cast<uint64_t>(durationNum->count());
6254dbb8aeaSWludzik, Jozef     }
6264dbb8aeaSWludzik, Jozef 
627479e899dSKrzysztof Grobelny     if (metrics)
6284dbb8aeaSWludzik, Jozef     {
629479e899dSKrzysztof Grobelny         if (!getUserMetrics(res, *metrics, args.metrics))
6304dbb8aeaSWludzik, Jozef         {
6314dbb8aeaSWludzik, Jozef             return false;
6324dbb8aeaSWludzik, Jozef         }
6334dbb8aeaSWludzik, Jozef     }
6344dbb8aeaSWludzik, Jozef 
6354dbb8aeaSWludzik, Jozef     return true;
6364dbb8aeaSWludzik, Jozef }
6374dbb8aeaSWludzik, Jozef 
638ca1600c1SSzymon Dompke inline bool getChassisSensorNodeFromMetrics(
6398d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
640479e899dSKrzysztof Grobelny     std::span<const AddReportArgs::MetricArgs> metrics,
6414dbb8aeaSWludzik, Jozef     boost::container::flat_set<std::pair<std::string, std::string>>& matched)
6424dbb8aeaSWludzik, Jozef {
643ca1600c1SSzymon Dompke     for (const auto& metric : metrics)
6444dbb8aeaSWludzik, Jozef     {
645479e899dSKrzysztof Grobelny         std::optional<IncorrectMetricUri> error =
646479e899dSKrzysztof Grobelny             getChassisSensorNode(metric.uris, matched);
647ca1600c1SSzymon Dompke         if (error)
6484dbb8aeaSWludzik, Jozef         {
649ca1600c1SSzymon Dompke             messages::propertyValueIncorrect(asyncResp->res, error->uri,
6504dbb8aeaSWludzik, Jozef                                              "MetricProperties/" +
651ca1600c1SSzymon Dompke                                                  std::to_string(error->index));
6524dbb8aeaSWludzik, Jozef             return false;
6534dbb8aeaSWludzik, Jozef         }
6544dbb8aeaSWludzik, Jozef     }
6554dbb8aeaSWludzik, Jozef     return true;
6564dbb8aeaSWludzik, Jozef }
6574dbb8aeaSWludzik, Jozef 
6584dbb8aeaSWludzik, Jozef class AddReport
6594dbb8aeaSWludzik, Jozef {
6604dbb8aeaSWludzik, Jozef   public:
6618d1b46d7Szhanghch05     AddReport(AddReportArgs argsIn,
6628a592810SEd Tanous               const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
6638a592810SEd Tanous         asyncResp(asyncRespIn),
6649e6c388aSLukasz Kazmierczak         args(std::move(argsIn))
6654dbb8aeaSWludzik, Jozef     {}
666479e899dSKrzysztof Grobelny 
6674dbb8aeaSWludzik, Jozef     ~AddReport()
6684dbb8aeaSWludzik, Jozef     {
669479e899dSKrzysztof Grobelny         boost::asio::post(crow::connections::systemBus->get_io_context(),
670479e899dSKrzysztof Grobelny                           std::bind_front(&performAddReport, asyncResp, args,
671479e899dSKrzysztof Grobelny                                           std::move(uriToDbus)));
672479e899dSKrzysztof Grobelny     }
673479e899dSKrzysztof Grobelny 
674479e899dSKrzysztof Grobelny     static void performAddReport(
675479e899dSKrzysztof Grobelny         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
676479e899dSKrzysztof Grobelny         const AddReportArgs& args,
677479e899dSKrzysztof Grobelny         const boost::container::flat_map<std::string, std::string>& uriToDbus)
678479e899dSKrzysztof Grobelny     {
6794dbb8aeaSWludzik, Jozef         if (asyncResp->res.result() != boost::beast::http::status::ok)
6804dbb8aeaSWludzik, Jozef         {
6814dbb8aeaSWludzik, Jozef             return;
6824dbb8aeaSWludzik, Jozef         }
6834dbb8aeaSWludzik, Jozef 
6844dbb8aeaSWludzik, Jozef         telemetry::ReadingParameters readingParams;
6854dbb8aeaSWludzik, Jozef         readingParams.reserve(args.metrics.size());
6864dbb8aeaSWludzik, Jozef 
687479e899dSKrzysztof Grobelny         for (const auto& metric : args.metrics)
6884dbb8aeaSWludzik, Jozef         {
689479e899dSKrzysztof Grobelny             std::vector<
690479e899dSKrzysztof Grobelny                 std::tuple<sdbusplus::message::object_path, std::string>>
691479e899dSKrzysztof Grobelny                 sensorParams;
692479e899dSKrzysztof Grobelny             sensorParams.reserve(metric.uris.size());
693479e899dSKrzysztof Grobelny 
694479e899dSKrzysztof Grobelny             for (size_t i = 0; i < metric.uris.size(); i++)
6954dbb8aeaSWludzik, Jozef             {
696479e899dSKrzysztof Grobelny                 const std::string& uri = metric.uris[i];
6974dbb8aeaSWludzik, Jozef                 auto el = uriToDbus.find(uri);
6984dbb8aeaSWludzik, Jozef                 if (el == uriToDbus.end())
6994dbb8aeaSWludzik, Jozef                 {
70062598e31SEd Tanous                     BMCWEB_LOG_ERROR(
70162598e31SEd Tanous                         "Failed to find DBus sensor corresponding to URI {}",
70262598e31SEd Tanous                         uri);
7034dbb8aeaSWludzik, Jozef                     messages::propertyValueNotInList(asyncResp->res, uri,
7044dbb8aeaSWludzik, Jozef                                                      "MetricProperties/" +
7054dbb8aeaSWludzik, Jozef                                                          std::to_string(i));
7064dbb8aeaSWludzik, Jozef                     return;
7074dbb8aeaSWludzik, Jozef                 }
7084dbb8aeaSWludzik, Jozef 
7094dbb8aeaSWludzik, Jozef                 const std::string& dbusPath = el->second;
710479e899dSKrzysztof Grobelny                 sensorParams.emplace_back(dbusPath, uri);
7114dbb8aeaSWludzik, Jozef             }
712479e899dSKrzysztof Grobelny 
713479e899dSKrzysztof Grobelny             readingParams.emplace_back(
714479e899dSKrzysztof Grobelny                 std::move(sensorParams), metric.collectionFunction,
715479e899dSKrzysztof Grobelny                 metric.collectionTimeScope, metric.collectionDuration);
7164dbb8aeaSWludzik, Jozef         }
717479e899dSKrzysztof Grobelny 
7184dbb8aeaSWludzik, Jozef         crow::connections::systemBus->async_method_call(
719479e899dSKrzysztof Grobelny             [asyncResp, id = args.id, uriToDbus](
7205e7e2dc5SEd Tanous                 const boost::system::error_code& ec, const std::string&) {
7214dbb8aeaSWludzik, Jozef             if (ec == boost::system::errc::file_exists)
7224dbb8aeaSWludzik, Jozef             {
7234dbb8aeaSWludzik, Jozef                 messages::resourceAlreadyExists(
724479e899dSKrzysztof Grobelny                     asyncResp->res, "MetricReportDefinition", "Id", id);
7254dbb8aeaSWludzik, Jozef                 return;
7264dbb8aeaSWludzik, Jozef             }
7274dbb8aeaSWludzik, Jozef             if (ec == boost::system::errc::too_many_files_open)
7284dbb8aeaSWludzik, Jozef             {
729479e899dSKrzysztof Grobelny                 messages::createLimitReachedForResource(asyncResp->res);
7304dbb8aeaSWludzik, Jozef                 return;
7314dbb8aeaSWludzik, Jozef             }
7324dbb8aeaSWludzik, Jozef             if (ec == boost::system::errc::argument_list_too_long)
7334dbb8aeaSWludzik, Jozef             {
7344dbb8aeaSWludzik, Jozef                 nlohmann::json metricProperties = nlohmann::json::array();
7354dbb8aeaSWludzik, Jozef                 for (const auto& [uri, _] : uriToDbus)
7364dbb8aeaSWludzik, Jozef                 {
7374dbb8aeaSWludzik, Jozef                     metricProperties.emplace_back(uri);
7384dbb8aeaSWludzik, Jozef                 }
73914fbced6SEd Tanous                 messages::propertyValueIncorrect(
74014fbced6SEd Tanous                     asyncResp->res, metricProperties, "MetricProperties");
7414dbb8aeaSWludzik, Jozef                 return;
7424dbb8aeaSWludzik, Jozef             }
7434dbb8aeaSWludzik, Jozef             if (ec)
7444dbb8aeaSWludzik, Jozef             {
745479e899dSKrzysztof Grobelny                 messages::internalError(asyncResp->res);
74662598e31SEd Tanous                 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
7474dbb8aeaSWludzik, Jozef                 return;
7484dbb8aeaSWludzik, Jozef             }
7494dbb8aeaSWludzik, Jozef 
750479e899dSKrzysztof Grobelny             messages::created(asyncResp->res);
7514dbb8aeaSWludzik, Jozef         },
7524dbb8aeaSWludzik, Jozef             telemetry::service, "/xyz/openbmc_project/Telemetry/Reports",
7534dbb8aeaSWludzik, Jozef             "xyz.openbmc_project.Telemetry.ReportManager", "AddReport",
754479e899dSKrzysztof Grobelny             "TelemetryService/" + args.id, args.name, args.reportingType,
755479e899dSKrzysztof Grobelny             args.reportUpdates, args.appendLimit, args.reportActions,
756479e899dSKrzysztof Grobelny             args.interval, readingParams, args.metricReportDefinitionEnabled);
7574dbb8aeaSWludzik, Jozef     }
7584dbb8aeaSWludzik, Jozef 
759ecd6a3a2SEd Tanous     AddReport(const AddReport&) = delete;
760ecd6a3a2SEd Tanous     AddReport(AddReport&&) = delete;
761ecd6a3a2SEd Tanous     AddReport& operator=(const AddReport&) = delete;
762ecd6a3a2SEd Tanous     AddReport& operator=(AddReport&&) = delete;
763ecd6a3a2SEd Tanous 
764fe04d49cSNan Zhou     void insert(const std::map<std::string, std::string>& el)
7654dbb8aeaSWludzik, Jozef     {
7664dbb8aeaSWludzik, Jozef         uriToDbus.insert(el.begin(), el.end());
7674dbb8aeaSWludzik, Jozef     }
7684dbb8aeaSWludzik, Jozef 
7694dbb8aeaSWludzik, Jozef   private:
770479e899dSKrzysztof Grobelny     std::shared_ptr<bmcweb::AsyncResp> asyncResp;
7714dbb8aeaSWludzik, Jozef     AddReportArgs args;
7724dbb8aeaSWludzik, Jozef     boost::container::flat_map<std::string, std::string> uriToDbus{};
7734dbb8aeaSWludzik, Jozef };
7749e6c388aSLukasz Kazmierczak 
7759e6c388aSLukasz Kazmierczak class UpdateMetrics
7769e6c388aSLukasz Kazmierczak {
7779e6c388aSLukasz Kazmierczak   public:
7789e6c388aSLukasz Kazmierczak     UpdateMetrics(std::string_view idIn,
7799e6c388aSLukasz Kazmierczak                   const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
7809e6c388aSLukasz Kazmierczak         id(idIn),
7819e6c388aSLukasz Kazmierczak         asyncResp(asyncRespIn)
7829e6c388aSLukasz Kazmierczak     {}
7839e6c388aSLukasz Kazmierczak 
7849e6c388aSLukasz Kazmierczak     ~UpdateMetrics()
7859e6c388aSLukasz Kazmierczak     {
7869e6c388aSLukasz Kazmierczak         try
7879e6c388aSLukasz Kazmierczak         {
7889e6c388aSLukasz Kazmierczak             setReadingParams();
7899e6c388aSLukasz Kazmierczak         }
7909e6c388aSLukasz Kazmierczak         catch (const std::exception& e)
7919e6c388aSLukasz Kazmierczak         {
7929e6c388aSLukasz Kazmierczak             BMCWEB_LOG_ERROR("{}", e.what());
7939e6c388aSLukasz Kazmierczak         }
7949e6c388aSLukasz Kazmierczak         catch (...)
7959e6c388aSLukasz Kazmierczak         {
7969e6c388aSLukasz Kazmierczak             BMCWEB_LOG_ERROR("Unknown error");
7979e6c388aSLukasz Kazmierczak         }
7989e6c388aSLukasz Kazmierczak     }
7999e6c388aSLukasz Kazmierczak 
8009e6c388aSLukasz Kazmierczak     UpdateMetrics(const UpdateMetrics&) = delete;
8019e6c388aSLukasz Kazmierczak     UpdateMetrics(UpdateMetrics&&) = delete;
8029e6c388aSLukasz Kazmierczak     UpdateMetrics& operator=(const UpdateMetrics&) = delete;
8039e6c388aSLukasz Kazmierczak     UpdateMetrics& operator=(UpdateMetrics&&) = delete;
8049e6c388aSLukasz Kazmierczak 
8059e6c388aSLukasz Kazmierczak     std::string id;
8069e6c388aSLukasz Kazmierczak     std::map<std::string, std::string> metricPropertyToDbusPaths;
8079e6c388aSLukasz Kazmierczak 
8089e6c388aSLukasz Kazmierczak     void insert(const std::map<std::string, std::string>&
8099e6c388aSLukasz Kazmierczak                     additionalMetricPropertyToDbusPaths)
8109e6c388aSLukasz Kazmierczak     {
8119e6c388aSLukasz Kazmierczak         metricPropertyToDbusPaths.insert(
8129e6c388aSLukasz Kazmierczak             additionalMetricPropertyToDbusPaths.begin(),
8139e6c388aSLukasz Kazmierczak             additionalMetricPropertyToDbusPaths.end());
8149e6c388aSLukasz Kazmierczak     }
8159e6c388aSLukasz Kazmierczak 
8169e6c388aSLukasz Kazmierczak     void emplace(std::span<const std::tuple<sdbusplus::message::object_path,
8179e6c388aSLukasz Kazmierczak                                             std::string>>
8189e6c388aSLukasz Kazmierczak                      pathAndUri,
8199e6c388aSLukasz Kazmierczak                  const AddReportArgs::MetricArgs& metricArgs)
8209e6c388aSLukasz Kazmierczak     {
8219e6c388aSLukasz Kazmierczak         readingParamsUris.emplace_back(metricArgs.uris);
8229e6c388aSLukasz Kazmierczak         readingParams.emplace_back(
8239e6c388aSLukasz Kazmierczak             std::vector(pathAndUri.begin(), pathAndUri.end()),
8249e6c388aSLukasz Kazmierczak             metricArgs.collectionFunction, metricArgs.collectionTimeScope,
8259e6c388aSLukasz Kazmierczak             metricArgs.collectionDuration);
8269e6c388aSLukasz Kazmierczak     }
8279e6c388aSLukasz Kazmierczak 
8289e6c388aSLukasz Kazmierczak     void setReadingParams()
8299e6c388aSLukasz Kazmierczak     {
8309e6c388aSLukasz Kazmierczak         if (asyncResp->res.result() != boost::beast::http::status::ok)
8319e6c388aSLukasz Kazmierczak         {
8329e6c388aSLukasz Kazmierczak             return;
8339e6c388aSLukasz Kazmierczak         }
8349e6c388aSLukasz Kazmierczak 
8359e6c388aSLukasz Kazmierczak         for (size_t index = 0; index < readingParamsUris.size(); ++index)
8369e6c388aSLukasz Kazmierczak         {
8379e6c388aSLukasz Kazmierczak             std::span<const std::string> newUris = readingParamsUris[index];
8389e6c388aSLukasz Kazmierczak 
8399e6c388aSLukasz Kazmierczak             const std::optional<std::vector<
8409e6c388aSLukasz Kazmierczak                 std::tuple<sdbusplus::message::object_path, std::string>>>
8419e6c388aSLukasz Kazmierczak                 readingParam = sensorPathToUri(newUris);
8429e6c388aSLukasz Kazmierczak 
8439e6c388aSLukasz Kazmierczak             if (!readingParam)
8449e6c388aSLukasz Kazmierczak             {
8459e6c388aSLukasz Kazmierczak                 return;
8469e6c388aSLukasz Kazmierczak             }
8479e6c388aSLukasz Kazmierczak 
8489e6c388aSLukasz Kazmierczak             std::get<0>(readingParams[index]) = *readingParam;
8499e6c388aSLukasz Kazmierczak         }
8509e6c388aSLukasz Kazmierczak 
8519e6c388aSLukasz Kazmierczak         crow::connections::systemBus->async_method_call(
8529e6c388aSLukasz Kazmierczak             [asyncResp(this->asyncResp),
8539e6c388aSLukasz Kazmierczak              reportId = id](const boost::system::error_code& ec) {
8549e6c388aSLukasz Kazmierczak             if (!verifyCommonErrors(asyncResp->res, reportId, ec))
8559e6c388aSLukasz Kazmierczak             {
8569e6c388aSLukasz Kazmierczak                 return;
8579e6c388aSLukasz Kazmierczak             }
8589e6c388aSLukasz Kazmierczak         },
8599e6c388aSLukasz Kazmierczak             "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
8609e6c388aSLukasz Kazmierczak             "org.freedesktop.DBus.Properties", "Set",
8619e6c388aSLukasz Kazmierczak             "xyz.openbmc_project.Telemetry.Report", "ReadingParameters",
8629e6c388aSLukasz Kazmierczak             dbus::utility::DbusVariantType{readingParams});
8639e6c388aSLukasz Kazmierczak     }
8649e6c388aSLukasz Kazmierczak 
8659e6c388aSLukasz Kazmierczak   private:
8669e6c388aSLukasz Kazmierczak     std::optional<
8679e6c388aSLukasz Kazmierczak         std::vector<std::tuple<sdbusplus::message::object_path, std::string>>>
8689e6c388aSLukasz Kazmierczak         sensorPathToUri(std::span<const std::string> uris) const
8699e6c388aSLukasz Kazmierczak     {
8709e6c388aSLukasz Kazmierczak         std::vector<std::tuple<sdbusplus::message::object_path, std::string>>
8719e6c388aSLukasz Kazmierczak             result;
8729e6c388aSLukasz Kazmierczak 
8739e6c388aSLukasz Kazmierczak         for (const std::string& uri : uris)
8749e6c388aSLukasz Kazmierczak         {
8759e6c388aSLukasz Kazmierczak             auto it = metricPropertyToDbusPaths.find(uri);
8769e6c388aSLukasz Kazmierczak             if (it == metricPropertyToDbusPaths.end())
8779e6c388aSLukasz Kazmierczak             {
8789e6c388aSLukasz Kazmierczak                 messages::propertyValueNotInList(asyncResp->res, uri,
8799e6c388aSLukasz Kazmierczak                                                  "MetricProperties");
8809e6c388aSLukasz Kazmierczak                 return {};
8819e6c388aSLukasz Kazmierczak             }
8829e6c388aSLukasz Kazmierczak             result.emplace_back(it->second, uri);
8839e6c388aSLukasz Kazmierczak         }
8849e6c388aSLukasz Kazmierczak 
8859e6c388aSLukasz Kazmierczak         return result;
8869e6c388aSLukasz Kazmierczak     }
8879e6c388aSLukasz Kazmierczak 
8889e6c388aSLukasz Kazmierczak     const std::shared_ptr<bmcweb::AsyncResp> asyncResp;
8899e6c388aSLukasz Kazmierczak     std::vector<std::vector<std::string>> readingParamsUris;
8909e6c388aSLukasz Kazmierczak     ReadingParameters readingParams{};
8919e6c388aSLukasz Kazmierczak };
8929e6c388aSLukasz Kazmierczak 
8939e6c388aSLukasz Kazmierczak inline void
8949e6c388aSLukasz Kazmierczak     setReportEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8959e6c388aSLukasz Kazmierczak                      std::string_view id, bool enabled)
8969e6c388aSLukasz Kazmierczak {
8979e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
8989e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
8999e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
9009e6c388aSLukasz Kazmierczak         {
9019e6c388aSLukasz Kazmierczak             return;
9029e6c388aSLukasz Kazmierczak         }
9039e6c388aSLukasz Kazmierczak     },
9049e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9059e6c388aSLukasz Kazmierczak         "org.freedesktop.DBus.Properties", "Set",
9069e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "Enabled",
9079e6c388aSLukasz Kazmierczak         dbus::utility::DbusVariantType{enabled});
9089e6c388aSLukasz Kazmierczak }
9099e6c388aSLukasz Kazmierczak 
9109e6c388aSLukasz Kazmierczak inline void setReportTypeAndInterval(
9119e6c388aSLukasz Kazmierczak     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string_view id,
9129e6c388aSLukasz Kazmierczak     const std::string& reportingType, uint64_t recurrenceInterval)
9139e6c388aSLukasz Kazmierczak {
9149e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
9159e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
9169e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
9179e6c388aSLukasz Kazmierczak         {
9189e6c388aSLukasz Kazmierczak             return;
9199e6c388aSLukasz Kazmierczak         }
9209e6c388aSLukasz Kazmierczak     },
9219e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9229e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "SetReportingProperties",
9239e6c388aSLukasz Kazmierczak         reportingType, recurrenceInterval);
9249e6c388aSLukasz Kazmierczak }
9259e6c388aSLukasz Kazmierczak 
9269e6c388aSLukasz Kazmierczak inline void
9279e6c388aSLukasz Kazmierczak     setReportUpdates(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9289e6c388aSLukasz Kazmierczak                      std::string_view id, const std::string& reportUpdates)
9299e6c388aSLukasz Kazmierczak {
9309e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
9319e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
9329e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
9339e6c388aSLukasz Kazmierczak         {
9349e6c388aSLukasz Kazmierczak             return;
9359e6c388aSLukasz Kazmierczak         }
9369e6c388aSLukasz Kazmierczak     },
9379e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9389e6c388aSLukasz Kazmierczak         "org.freedesktop.DBus.Properties", "Set",
9399e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "ReportUpdates",
9409e6c388aSLukasz Kazmierczak         dbus::utility::DbusVariantType{reportUpdates});
9419e6c388aSLukasz Kazmierczak }
9429e6c388aSLukasz Kazmierczak 
9439e6c388aSLukasz Kazmierczak inline void
9449e6c388aSLukasz Kazmierczak     setReportActions(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9459e6c388aSLukasz Kazmierczak                      std::string_view id,
9469e6c388aSLukasz Kazmierczak                      const std::vector<std::string>& dbusReportActions)
9479e6c388aSLukasz Kazmierczak {
9489e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
9499e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
9509e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
9519e6c388aSLukasz Kazmierczak         {
9529e6c388aSLukasz Kazmierczak             return;
9539e6c388aSLukasz Kazmierczak         }
9549e6c388aSLukasz Kazmierczak     },
9559e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9569e6c388aSLukasz Kazmierczak         "org.freedesktop.DBus.Properties", "Set",
9579e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "ReportActions",
9589e6c388aSLukasz Kazmierczak         dbus::utility::DbusVariantType{dbusReportActions});
9599e6c388aSLukasz Kazmierczak }
9609e6c388aSLukasz Kazmierczak 
9619e6c388aSLukasz Kazmierczak inline void
9629e6c388aSLukasz Kazmierczak     setReportMetrics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9639e6c388aSLukasz Kazmierczak                      std::string_view id, std::span<nlohmann::json> metrics)
9649e6c388aSLukasz Kazmierczak {
9659e6c388aSLukasz Kazmierczak     sdbusplus::asio::getAllProperties(
9669e6c388aSLukasz Kazmierczak         *crow::connections::systemBus, telemetry::service,
9679e6c388aSLukasz Kazmierczak         telemetry::getDbusReportPath(id), telemetry::reportInterface,
9689e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id),
9699e6c388aSLukasz Kazmierczak          redfishMetrics = std::vector<nlohmann::json>(metrics.begin(),
9709e6c388aSLukasz Kazmierczak                                                       metrics.end())](
9719e6c388aSLukasz Kazmierczak             boost::system::error_code ec,
9729e6c388aSLukasz Kazmierczak             const dbus::utility::DBusPropertiesMap& properties) mutable {
9739e6c388aSLukasz Kazmierczak         if (!redfish::telemetry::verifyCommonErrors(asyncResp->res, id, ec))
9749e6c388aSLukasz Kazmierczak         {
9759e6c388aSLukasz Kazmierczak             return;
9769e6c388aSLukasz Kazmierczak         }
9779e6c388aSLukasz Kazmierczak 
9789e6c388aSLukasz Kazmierczak         ReadingParameters readingParams;
9799e6c388aSLukasz Kazmierczak 
9809e6c388aSLukasz Kazmierczak         const bool success = sdbusplus::unpackPropertiesNoThrow(
9819e6c388aSLukasz Kazmierczak             dbus_utils::UnpackErrorPrinter(), properties, "ReadingParameters",
9829e6c388aSLukasz Kazmierczak             readingParams);
9839e6c388aSLukasz Kazmierczak 
9849e6c388aSLukasz Kazmierczak         if (!success)
9859e6c388aSLukasz Kazmierczak         {
9869e6c388aSLukasz Kazmierczak             messages::internalError(asyncResp->res);
9879e6c388aSLukasz Kazmierczak             return;
9889e6c388aSLukasz Kazmierczak         }
9899e6c388aSLukasz Kazmierczak 
9909e6c388aSLukasz Kazmierczak         auto updateMetricsReq = std::make_shared<UpdateMetrics>(id, asyncResp);
9919e6c388aSLukasz Kazmierczak 
9929e6c388aSLukasz Kazmierczak         boost::container::flat_set<std::pair<std::string, std::string>>
9939e6c388aSLukasz Kazmierczak             chassisSensors;
9949e6c388aSLukasz Kazmierczak 
9959e6c388aSLukasz Kazmierczak         size_t index = 0;
9969e6c388aSLukasz Kazmierczak         for (nlohmann::json& metric : redfishMetrics)
9979e6c388aSLukasz Kazmierczak         {
9989e6c388aSLukasz Kazmierczak             if (metric.is_null())
9999e6c388aSLukasz Kazmierczak             {
10009e6c388aSLukasz Kazmierczak                 continue;
10019e6c388aSLukasz Kazmierczak             }
10029e6c388aSLukasz Kazmierczak 
10039e6c388aSLukasz Kazmierczak             AddReportArgs::MetricArgs metricArgs;
10049e6c388aSLukasz Kazmierczak             std::vector<
10059e6c388aSLukasz Kazmierczak                 std::tuple<sdbusplus::message::object_path, std::string>>
10069e6c388aSLukasz Kazmierczak                 pathAndUri;
10079e6c388aSLukasz Kazmierczak 
10089e6c388aSLukasz Kazmierczak             if (index < readingParams.size())
10099e6c388aSLukasz Kazmierczak             {
10109e6c388aSLukasz Kazmierczak                 const ReadingParameters::value_type& existing =
10119e6c388aSLukasz Kazmierczak                     readingParams[index];
10129e6c388aSLukasz Kazmierczak 
10139e6c388aSLukasz Kazmierczak                 pathAndUri = std::get<0>(existing);
10149e6c388aSLukasz Kazmierczak                 metricArgs.collectionFunction = std::get<1>(existing);
10159e6c388aSLukasz Kazmierczak                 metricArgs.collectionTimeScope = std::get<2>(existing);
10169e6c388aSLukasz Kazmierczak                 metricArgs.collectionDuration = std::get<3>(existing);
10179e6c388aSLukasz Kazmierczak             }
10189e6c388aSLukasz Kazmierczak 
10199e6c388aSLukasz Kazmierczak             if (!getUserMetric(asyncResp->res, metric, metricArgs))
10209e6c388aSLukasz Kazmierczak             {
10219e6c388aSLukasz Kazmierczak                 return;
10229e6c388aSLukasz Kazmierczak             }
10239e6c388aSLukasz Kazmierczak 
10249e6c388aSLukasz Kazmierczak             std::optional<IncorrectMetricUri> error =
10259e6c388aSLukasz Kazmierczak                 getChassisSensorNode(metricArgs.uris, chassisSensors);
10269e6c388aSLukasz Kazmierczak 
10279e6c388aSLukasz Kazmierczak             if (error)
10289e6c388aSLukasz Kazmierczak             {
10299e6c388aSLukasz Kazmierczak                 messages::propertyValueIncorrect(
10309e6c388aSLukasz Kazmierczak                     asyncResp->res, error->uri,
10319e6c388aSLukasz Kazmierczak                     "MetricProperties/" + std::to_string(error->index));
10329e6c388aSLukasz Kazmierczak                 return;
10339e6c388aSLukasz Kazmierczak             }
10349e6c388aSLukasz Kazmierczak 
10359e6c388aSLukasz Kazmierczak             updateMetricsReq->emplace(pathAndUri, metricArgs);
10369e6c388aSLukasz Kazmierczak             index++;
10379e6c388aSLukasz Kazmierczak         }
10389e6c388aSLukasz Kazmierczak 
10399e6c388aSLukasz Kazmierczak         for (const auto& [chassis, sensorType] : chassisSensors)
10409e6c388aSLukasz Kazmierczak         {
10419e6c388aSLukasz Kazmierczak             retrieveUriToDbusMap(
10429e6c388aSLukasz Kazmierczak                 chassis, sensorType,
10439e6c388aSLukasz Kazmierczak                 [asyncResp, updateMetricsReq](
10449e6c388aSLukasz Kazmierczak                     const boost::beast::http::status status,
10459e6c388aSLukasz Kazmierczak                     const std::map<std::string, std::string>& uriToDbus) {
10469e6c388aSLukasz Kazmierczak                 if (status != boost::beast::http::status::ok)
10479e6c388aSLukasz Kazmierczak                 {
10489e6c388aSLukasz Kazmierczak                     BMCWEB_LOG_ERROR(
10499e6c388aSLukasz Kazmierczak                         "Failed to retrieve URI to dbus sensors map with err {}",
10509e6c388aSLukasz Kazmierczak                         static_cast<unsigned>(status));
10519e6c388aSLukasz Kazmierczak                     return;
10529e6c388aSLukasz Kazmierczak                 }
10539e6c388aSLukasz Kazmierczak                 updateMetricsReq->insert(uriToDbus);
10549e6c388aSLukasz Kazmierczak             });
10559e6c388aSLukasz Kazmierczak         }
10569e6c388aSLukasz Kazmierczak     });
10579e6c388aSLukasz Kazmierczak }
1058081ebf06SWludzik, Jozef 
10594220be3bSEd Tanous inline void handleMetricReportDefinitionCollectionHead(
10604220be3bSEd Tanous     App& app, const crow::Request& req,
10614220be3bSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
10624220be3bSEd Tanous {
10634220be3bSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
10644220be3bSEd Tanous     {
10654220be3bSEd Tanous         return;
10664220be3bSEd Tanous     }
10674220be3bSEd Tanous     asyncResp->res.addHeader(
10684220be3bSEd Tanous         boost::beast::http::field::link,
10694220be3bSEd Tanous         "</redfish/v1/JsonSchemas/MetricReportDefinitionCollection/MetricReportDefinitionCollection.json>; rel=describedby");
10704220be3bSEd Tanous }
10714220be3bSEd Tanous 
10724220be3bSEd Tanous inline void handleMetricReportDefinitionCollectionGet(
1073fc0edbe3SEd Tanous     App& app, const crow::Request& req,
1074fc0edbe3SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1075fc0edbe3SEd Tanous {
1076fc0edbe3SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1077fc0edbe3SEd Tanous     {
1078fc0edbe3SEd Tanous         return;
1079fc0edbe3SEd Tanous     }
10809e6c388aSLukasz Kazmierczak     asyncResp->res.addHeader(
10819e6c388aSLukasz Kazmierczak         boost::beast::http::field::link,
10829e6c388aSLukasz Kazmierczak         "</redfish/v1/JsonSchemas/MetricReportDefinition/MetricReportDefinition.json>; rel=describedby");
1083fc0edbe3SEd Tanous 
1084fc0edbe3SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
1085fc0edbe3SEd Tanous         "#MetricReportDefinitionCollection."
1086fc0edbe3SEd Tanous         "MetricReportDefinitionCollection";
1087fc0edbe3SEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
1088fc0edbe3SEd Tanous         "/redfish/v1/TelemetryService/MetricReportDefinitions";
1089fc0edbe3SEd Tanous     asyncResp->res.jsonValue["Name"] = "Metric Definition Collection";
1090fc0edbe3SEd Tanous     constexpr std::array<std::string_view, 1> interfaces{
1091fc0edbe3SEd Tanous         telemetry::reportInterface};
1092fc0edbe3SEd Tanous     collection_util::getCollectionMembers(
1093fc0edbe3SEd Tanous         asyncResp,
1094fc0edbe3SEd Tanous         boost::urls::url(
1095fc0edbe3SEd Tanous             "/redfish/v1/TelemetryService/MetricReportDefinitions"),
1096fc0edbe3SEd Tanous         interfaces, "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
1097fc0edbe3SEd Tanous }
1098fc0edbe3SEd Tanous 
109986a5ac98SEd Tanous inline void
11009e6c388aSLukasz Kazmierczak     handleReportPatch(App& app, const crow::Request& req,
11019e6c388aSLukasz Kazmierczak                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11029e6c388aSLukasz Kazmierczak                       std::string_view id)
11039e6c388aSLukasz Kazmierczak {
11049e6c388aSLukasz Kazmierczak     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
11059e6c388aSLukasz Kazmierczak     {
11069e6c388aSLukasz Kazmierczak         return;
11079e6c388aSLukasz Kazmierczak     }
11089e6c388aSLukasz Kazmierczak 
11099e6c388aSLukasz Kazmierczak     std::optional<std::string> reportingTypeStr;
11109e6c388aSLukasz Kazmierczak     std::optional<std::string> reportUpdatesStr;
11119e6c388aSLukasz Kazmierczak     std::optional<bool> metricReportDefinitionEnabled;
11129e6c388aSLukasz Kazmierczak     std::optional<std::vector<nlohmann::json>> metrics;
11139e6c388aSLukasz Kazmierczak     std::optional<std::vector<std::string>> reportActionsStr;
11149e6c388aSLukasz Kazmierczak     std::optional<nlohmann::json> schedule;
11159e6c388aSLukasz Kazmierczak 
11169e6c388aSLukasz Kazmierczak     if (!json_util::readJsonPatch(
11179e6c388aSLukasz Kazmierczak             req, asyncResp->res, "Metrics", metrics,
11189e6c388aSLukasz Kazmierczak             "MetricReportDefinitionType", reportingTypeStr, "ReportUpdates",
11199e6c388aSLukasz Kazmierczak             reportUpdatesStr, "ReportActions", reportActionsStr, "Schedule",
11209e6c388aSLukasz Kazmierczak             schedule, "MetricReportDefinitionEnabled",
11219e6c388aSLukasz Kazmierczak             metricReportDefinitionEnabled))
11229e6c388aSLukasz Kazmierczak     {
11239e6c388aSLukasz Kazmierczak         return;
11249e6c388aSLukasz Kazmierczak     }
11259e6c388aSLukasz Kazmierczak 
11269e6c388aSLukasz Kazmierczak     if (metricReportDefinitionEnabled)
11279e6c388aSLukasz Kazmierczak     {
11289e6c388aSLukasz Kazmierczak         setReportEnabled(asyncResp, id, *metricReportDefinitionEnabled);
11299e6c388aSLukasz Kazmierczak     }
11309e6c388aSLukasz Kazmierczak 
11319e6c388aSLukasz Kazmierczak     if (reportUpdatesStr)
11329e6c388aSLukasz Kazmierczak     {
11339e6c388aSLukasz Kazmierczak         std::string dbusReportUpdates = toDbusReportUpdates(*reportUpdatesStr);
11349e6c388aSLukasz Kazmierczak         if (dbusReportUpdates.empty())
11359e6c388aSLukasz Kazmierczak         {
11369e6c388aSLukasz Kazmierczak             messages::propertyValueNotInList(asyncResp->res, *reportUpdatesStr,
11379e6c388aSLukasz Kazmierczak                                              "ReportUpdates");
11389e6c388aSLukasz Kazmierczak             return;
11399e6c388aSLukasz Kazmierczak         }
11409e6c388aSLukasz Kazmierczak         setReportUpdates(asyncResp, id, dbusReportUpdates);
11419e6c388aSLukasz Kazmierczak     }
11429e6c388aSLukasz Kazmierczak 
11439e6c388aSLukasz Kazmierczak     if (reportActionsStr)
11449e6c388aSLukasz Kazmierczak     {
11459e6c388aSLukasz Kazmierczak         std::vector<std::string> dbusReportActions;
11469e6c388aSLukasz Kazmierczak         if (!toDbusReportActions(asyncResp->res, *reportActionsStr,
11479e6c388aSLukasz Kazmierczak                                  dbusReportActions))
11489e6c388aSLukasz Kazmierczak         {
11499e6c388aSLukasz Kazmierczak             return;
11509e6c388aSLukasz Kazmierczak         }
11519e6c388aSLukasz Kazmierczak         setReportActions(asyncResp, id, dbusReportActions);
11529e6c388aSLukasz Kazmierczak     }
11539e6c388aSLukasz Kazmierczak 
11549e6c388aSLukasz Kazmierczak     if (reportingTypeStr || schedule)
11559e6c388aSLukasz Kazmierczak     {
11569e6c388aSLukasz Kazmierczak         std::string dbusReportingType;
11579e6c388aSLukasz Kazmierczak         if (reportingTypeStr)
11589e6c388aSLukasz Kazmierczak         {
11599e6c388aSLukasz Kazmierczak             dbusReportingType = toDbusReportingType(*reportingTypeStr);
11609e6c388aSLukasz Kazmierczak             if (dbusReportingType.empty())
11619e6c388aSLukasz Kazmierczak             {
11629e6c388aSLukasz Kazmierczak                 messages::propertyValueNotInList(asyncResp->res,
11639e6c388aSLukasz Kazmierczak                                                  *reportingTypeStr,
11649e6c388aSLukasz Kazmierczak                                                  "MetricReportDefinitionType");
11659e6c388aSLukasz Kazmierczak                 return;
11669e6c388aSLukasz Kazmierczak             }
11679e6c388aSLukasz Kazmierczak         }
11689e6c388aSLukasz Kazmierczak 
11699e6c388aSLukasz Kazmierczak         uint64_t recurrenceInterval = std::numeric_limits<uint64_t>::max();
11709e6c388aSLukasz Kazmierczak         if (schedule)
11719e6c388aSLukasz Kazmierczak         {
11729e6c388aSLukasz Kazmierczak             std::string durationStr;
11739e6c388aSLukasz Kazmierczak             if (!json_util::readJson(*schedule, asyncResp->res,
11749e6c388aSLukasz Kazmierczak                                      "RecurrenceInterval", durationStr))
11759e6c388aSLukasz Kazmierczak             {
11769e6c388aSLukasz Kazmierczak                 return;
11779e6c388aSLukasz Kazmierczak             }
11789e6c388aSLukasz Kazmierczak 
11799e6c388aSLukasz Kazmierczak             std::optional<std::chrono::milliseconds> durationNum =
11809e6c388aSLukasz Kazmierczak                 time_utils::fromDurationString(durationStr);
11819e6c388aSLukasz Kazmierczak             if (!durationNum || durationNum->count() < 0)
11829e6c388aSLukasz Kazmierczak             {
11839e6c388aSLukasz Kazmierczak                 messages::propertyValueIncorrect(
11849e6c388aSLukasz Kazmierczak                     asyncResp->res, "RecurrenceInterval", durationStr);
11859e6c388aSLukasz Kazmierczak                 return;
11869e6c388aSLukasz Kazmierczak             }
11879e6c388aSLukasz Kazmierczak 
11889e6c388aSLukasz Kazmierczak             recurrenceInterval = static_cast<uint64_t>(durationNum->count());
11899e6c388aSLukasz Kazmierczak         }
11909e6c388aSLukasz Kazmierczak 
11919e6c388aSLukasz Kazmierczak         setReportTypeAndInterval(asyncResp, id, dbusReportingType,
11929e6c388aSLukasz Kazmierczak                                  recurrenceInterval);
11939e6c388aSLukasz Kazmierczak     }
11949e6c388aSLukasz Kazmierczak 
11959e6c388aSLukasz Kazmierczak     if (metrics)
11969e6c388aSLukasz Kazmierczak     {
11979e6c388aSLukasz Kazmierczak         setReportMetrics(asyncResp, id, *metrics);
11989e6c388aSLukasz Kazmierczak     }
11999e6c388aSLukasz Kazmierczak }
12009e6c388aSLukasz Kazmierczak 
12019e6c388aSLukasz Kazmierczak inline void
12029e6c388aSLukasz Kazmierczak     handleReportDelete(App& app, const crow::Request& req,
12039e6c388aSLukasz Kazmierczak                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
12049e6c388aSLukasz Kazmierczak                        std::string_view id)
12059e6c388aSLukasz Kazmierczak {
12069e6c388aSLukasz Kazmierczak     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
12079e6c388aSLukasz Kazmierczak     {
12089e6c388aSLukasz Kazmierczak         return;
12099e6c388aSLukasz Kazmierczak     }
12109e6c388aSLukasz Kazmierczak 
12119e6c388aSLukasz Kazmierczak     const std::string reportPath = getDbusReportPath(id);
12129e6c388aSLukasz Kazmierczak 
12139e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
12149e6c388aSLukasz Kazmierczak         [asyncResp,
12159e6c388aSLukasz Kazmierczak          reportId = std::string(id)](const boost::system::error_code& ec) {
12169e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, reportId, ec))
12179e6c388aSLukasz Kazmierczak         {
12189e6c388aSLukasz Kazmierczak             return;
12199e6c388aSLukasz Kazmierczak         }
12209e6c388aSLukasz Kazmierczak         asyncResp->res.result(boost::beast::http::status::no_content);
12219e6c388aSLukasz Kazmierczak     },
12229e6c388aSLukasz Kazmierczak         service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete");
12239e6c388aSLukasz Kazmierczak }
12249e6c388aSLukasz Kazmierczak } // namespace telemetry
12259e6c388aSLukasz Kazmierczak 
1226*95bdb5f0SEd Tanous inline void afterRetrieveUriToDbusMap(
1227*95bdb5f0SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
1228*95bdb5f0SEd Tanous     const std::shared_ptr<telemetry::AddReport>& addReportReq,
1229*95bdb5f0SEd Tanous     const boost::beast::http::status status,
1230*95bdb5f0SEd Tanous     const std::map<std::string, std::string>& uriToDbus)
1231*95bdb5f0SEd Tanous {
1232*95bdb5f0SEd Tanous     if (status != boost::beast::http::status::ok)
1233*95bdb5f0SEd Tanous     {
1234*95bdb5f0SEd Tanous         BMCWEB_LOG_ERROR(
1235*95bdb5f0SEd Tanous             "Failed to retrieve URI to dbus sensors map with err {}",
1236*95bdb5f0SEd Tanous             static_cast<unsigned>(status));
1237*95bdb5f0SEd Tanous         return;
1238*95bdb5f0SEd Tanous     }
1239*95bdb5f0SEd Tanous     addReportReq->insert(uriToDbus);
1240*95bdb5f0SEd Tanous }
1241*95bdb5f0SEd Tanous 
12429e6c388aSLukasz Kazmierczak inline void handleMetricReportDefinitionsPost(
12439e6c388aSLukasz Kazmierczak     App& app, const crow::Request& req,
12449e6c388aSLukasz Kazmierczak     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12459e6c388aSLukasz Kazmierczak {
12469e6c388aSLukasz Kazmierczak     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
12479e6c388aSLukasz Kazmierczak     {
12489e6c388aSLukasz Kazmierczak         return;
12499e6c388aSLukasz Kazmierczak     }
12509e6c388aSLukasz Kazmierczak 
12519e6c388aSLukasz Kazmierczak     telemetry::AddReportArgs args;
12529e6c388aSLukasz Kazmierczak     if (!telemetry::getUserParameters(asyncResp->res, req, args))
12539e6c388aSLukasz Kazmierczak     {
12549e6c388aSLukasz Kazmierczak         return;
12559e6c388aSLukasz Kazmierczak     }
12569e6c388aSLukasz Kazmierczak 
12579e6c388aSLukasz Kazmierczak     boost::container::flat_set<std::pair<std::string, std::string>>
12589e6c388aSLukasz Kazmierczak         chassisSensors;
12599e6c388aSLukasz Kazmierczak     if (!telemetry::getChassisSensorNodeFromMetrics(asyncResp, args.metrics,
12609e6c388aSLukasz Kazmierczak                                                     chassisSensors))
12619e6c388aSLukasz Kazmierczak     {
12629e6c388aSLukasz Kazmierczak         return;
12639e6c388aSLukasz Kazmierczak     }
12649e6c388aSLukasz Kazmierczak 
12659e6c388aSLukasz Kazmierczak     auto addReportReq = std::make_shared<telemetry::AddReport>(std::move(args),
12669e6c388aSLukasz Kazmierczak                                                                asyncResp);
12679e6c388aSLukasz Kazmierczak     for (const auto& [chassis, sensorType] : chassisSensors)
12689e6c388aSLukasz Kazmierczak     {
1269*95bdb5f0SEd Tanous         retrieveUriToDbusMap(chassis, sensorType,
1270*95bdb5f0SEd Tanous                              std::bind_front(afterRetrieveUriToDbusMap,
1271*95bdb5f0SEd Tanous                                              asyncResp, addReportReq));
12729e6c388aSLukasz Kazmierczak     }
12739e6c388aSLukasz Kazmierczak }
12749e6c388aSLukasz Kazmierczak 
12759e6c388aSLukasz Kazmierczak inline void
12764220be3bSEd Tanous     handleMetricReportHead(App& app, const crow::Request& req,
12774220be3bSEd Tanous                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
12784220be3bSEd Tanous                            const std::string& /*id*/)
12794220be3bSEd Tanous {
12804220be3bSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
12814220be3bSEd Tanous     {
12824220be3bSEd Tanous         return;
12834220be3bSEd Tanous     }
12844220be3bSEd Tanous     asyncResp->res.addHeader(
12854220be3bSEd Tanous         boost::beast::http::field::link,
12864220be3bSEd Tanous         "</redfish/v1/JsonSchemas/MetricReport/MetricReport.json>; rel=describedby");
12874220be3bSEd Tanous }
12884220be3bSEd Tanous 
12894220be3bSEd Tanous inline void
129086a5ac98SEd Tanous     handleMetricReportGet(App& app, const crow::Request& req,
129186a5ac98SEd Tanous                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
129286a5ac98SEd Tanous                           const std::string& id)
129386a5ac98SEd Tanous {
129486a5ac98SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
129586a5ac98SEd Tanous     {
129686a5ac98SEd Tanous         return;
129786a5ac98SEd Tanous     }
12984220be3bSEd Tanous     asyncResp->res.addHeader(
12994220be3bSEd Tanous         boost::beast::http::field::link,
13004220be3bSEd Tanous         "</redfish/v1/JsonSchemas/MetricReport/MetricReport.json>; rel=describedby");
130186a5ac98SEd Tanous 
130286a5ac98SEd Tanous     sdbusplus::asio::getAllProperties(
130386a5ac98SEd Tanous         *crow::connections::systemBus, telemetry::service,
130486a5ac98SEd Tanous         telemetry::getDbusReportPath(id), telemetry::reportInterface,
130586a5ac98SEd Tanous         [asyncResp, id](const boost::system::error_code& ec,
130686a5ac98SEd Tanous                         const dbus::utility::DBusPropertiesMap& properties) {
13079e6c388aSLukasz Kazmierczak         if (!redfish::telemetry::verifyCommonErrors(asyncResp->res, id, ec))
130886a5ac98SEd Tanous         {
130986a5ac98SEd Tanous             return;
131086a5ac98SEd Tanous         }
131186a5ac98SEd Tanous 
131286a5ac98SEd Tanous         telemetry::fillReportDefinition(asyncResp, id, properties);
131386a5ac98SEd Tanous     });
131486a5ac98SEd Tanous }
131586a5ac98SEd Tanous 
1316dd1c4a9cSSzymon Dompke inline void handleMetricReportDelete(
1317dd1c4a9cSSzymon Dompke     App& app, const crow::Request& req,
1318dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1319dd1c4a9cSSzymon Dompke 
1320dd1c4a9cSSzymon Dompke {
1321dd1c4a9cSSzymon Dompke     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1322dd1c4a9cSSzymon Dompke     {
1323dd1c4a9cSSzymon Dompke         return;
1324dd1c4a9cSSzymon Dompke     }
1325dd1c4a9cSSzymon Dompke 
1326dd1c4a9cSSzymon Dompke     const std::string reportPath = telemetry::getDbusReportPath(id);
1327dd1c4a9cSSzymon Dompke 
1328dd1c4a9cSSzymon Dompke     crow::connections::systemBus->async_method_call(
1329dd1c4a9cSSzymon Dompke         [asyncResp, id](const boost::system::error_code& ec) {
1330dd1c4a9cSSzymon Dompke         /*
1331dd1c4a9cSSzymon Dompke          * boost::system::errc and std::errc are missing value
1332dd1c4a9cSSzymon Dompke          * for EBADR error that is defined in Linux.
1333dd1c4a9cSSzymon Dompke          */
1334dd1c4a9cSSzymon Dompke         if (ec.value() == EBADR)
1335dd1c4a9cSSzymon Dompke         {
1336dd1c4a9cSSzymon Dompke             messages::resourceNotFound(asyncResp->res, "MetricReportDefinition",
1337dd1c4a9cSSzymon Dompke                                        id);
1338dd1c4a9cSSzymon Dompke             return;
1339dd1c4a9cSSzymon Dompke         }
1340dd1c4a9cSSzymon Dompke 
1341dd1c4a9cSSzymon Dompke         if (ec)
1342dd1c4a9cSSzymon Dompke         {
134362598e31SEd Tanous             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1344dd1c4a9cSSzymon Dompke             messages::internalError(asyncResp->res);
1345dd1c4a9cSSzymon Dompke             return;
1346dd1c4a9cSSzymon Dompke         }
1347dd1c4a9cSSzymon Dompke 
1348dd1c4a9cSSzymon Dompke         asyncResp->res.result(boost::beast::http::status::no_content);
1349dd1c4a9cSSzymon Dompke     },
1350dd1c4a9cSSzymon Dompke         telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete",
1351dd1c4a9cSSzymon Dompke         "Delete");
1352dd1c4a9cSSzymon Dompke }
1353dd1c4a9cSSzymon Dompke 
13547e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinitionCollection(App& app)
1355081ebf06SWludzik, Jozef {
13567e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
13574220be3bSEd Tanous         .privileges(redfish::privileges::headMetricReportDefinitionCollection)
13584220be3bSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
13599e6c388aSLukasz Kazmierczak             telemetry::handleMetricReportDefinitionCollectionHead,
13609e6c388aSLukasz Kazmierczak             std::ref(app)));
13614220be3bSEd Tanous 
13624220be3bSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
1363ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReportDefinitionCollection)
13644220be3bSEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
13659e6c388aSLukasz Kazmierczak             telemetry::handleMetricReportDefinitionCollectionGet,
13669e6c388aSLukasz Kazmierczak             std::ref(app)));
13674dbb8aeaSWludzik, Jozef 
13687e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
1369ed398213SEd Tanous         .privileges(redfish::privileges::postMetricReportDefinitionCollection)
1370002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
13719e6c388aSLukasz Kazmierczak             std::bind_front(handleMetricReportDefinitionsPost, std::ref(app)));
1372081ebf06SWludzik, Jozef }
1373081ebf06SWludzik, Jozef 
13747e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinition(App& app)
1375081ebf06SWludzik, Jozef {
13767e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
13777e860f15SJohn Edward Broadbent                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
1378ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReportDefinition)
13794220be3bSEd Tanous         .methods(boost::beast::http::verb::head)(
13804220be3bSEd Tanous             std::bind_front(handleMetricReportHead, std::ref(app)));
13814220be3bSEd Tanous 
13824220be3bSEd Tanous     BMCWEB_ROUTE(app,
13834220be3bSEd Tanous                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
13844220be3bSEd Tanous         .privileges(redfish::privileges::getMetricReportDefinition)
13857e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
138686a5ac98SEd Tanous             std::bind_front(handleMetricReportGet, std::ref(app)));
1387479e899dSKrzysztof Grobelny 
13887e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
13897e860f15SJohn Edward Broadbent                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
13909e6c388aSLukasz Kazmierczak         .privileges(redfish::privileges::deleteMetricReportDefinition)
13917e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::delete_)(
1392dd1c4a9cSSzymon Dompke             std::bind_front(handleMetricReportDelete, std::ref(app)));
13939e6c388aSLukasz Kazmierczak 
13949e6c388aSLukasz Kazmierczak     BMCWEB_ROUTE(app,
13959e6c388aSLukasz Kazmierczak                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
13969e6c388aSLukasz Kazmierczak         .privileges(redfish::privileges::patchMetricReportDefinition)
13979e6c388aSLukasz Kazmierczak         .methods(boost::beast::http::verb::patch)(
13989e6c388aSLukasz Kazmierczak             std::bind_front(telemetry::handleReportPatch, std::ref(app)));
13994dbb8aeaSWludzik, Jozef }
1400081ebf06SWludzik, Jozef } // namespace redfish
1401