xref: /openbmc/bmcweb/features/redfish/lib/metric_report_definition.hpp (revision 539d8c6bc399e516d39bcaa18262cf206f4c1035)
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"
6*539d8c6bSEd Tanous #include "generated/enums/resource.hpp"
73ccb3adbSEd Tanous #include "query.hpp"
83ccb3adbSEd Tanous #include "registries/privilege_registry.hpp"
94dbb8aeaSWludzik, Jozef #include "sensors.hpp"
103ccb3adbSEd Tanous #include "utils/collection.hpp"
113ccb3adbSEd Tanous #include "utils/dbus_utils.hpp"
125b90429aSEd Tanous #include "utils/json_utils.hpp"
13081ebf06SWludzik, Jozef #include "utils/telemetry_utils.hpp"
14081ebf06SWludzik, Jozef #include "utils/time_utils.hpp"
15081ebf06SWludzik, Jozef 
164dbb8aeaSWludzik, Jozef #include <boost/container/flat_map.hpp>
17ef4c65b7SEd Tanous #include <boost/url/format.hpp>
1889474494SKrzysztof Grobelny #include <sdbusplus/asio/property.hpp>
1989474494SKrzysztof Grobelny #include <sdbusplus/unpack_properties.hpp>
204dbb8aeaSWludzik, Jozef 
217a1dbc48SGeorge Liu #include <array>
22fe04d49cSNan Zhou #include <map>
23f19ab44aSSzymon Dompke #include <optional>
24f19ab44aSSzymon Dompke #include <span>
25f19ab44aSSzymon Dompke #include <string>
267a1dbc48SGeorge Liu #include <string_view>
27081ebf06SWludzik, Jozef #include <tuple>
28f19ab44aSSzymon Dompke #include <utility>
29081ebf06SWludzik, Jozef #include <variant>
30f19ab44aSSzymon Dompke #include <vector>
31081ebf06SWludzik, Jozef 
32081ebf06SWludzik, Jozef namespace redfish
33081ebf06SWludzik, Jozef {
34081ebf06SWludzik, Jozef 
35081ebf06SWludzik, Jozef namespace telemetry
36081ebf06SWludzik, Jozef {
37081ebf06SWludzik, Jozef 
38479e899dSKrzysztof Grobelny using ReadingParameters = std::vector<std::tuple<
39479e899dSKrzysztof Grobelny     std::vector<std::tuple<sdbusplus::message::object_path, std::string>>,
40479e899dSKrzysztof Grobelny     std::string, std::string, uint64_t>>;
41479e899dSKrzysztof Grobelny 
429e6c388aSLukasz Kazmierczak inline bool verifyCommonErrors(crow::Response& res, const std::string& id,
439e6c388aSLukasz Kazmierczak                                const boost::system::error_code& ec)
449e6c388aSLukasz Kazmierczak {
459e6c388aSLukasz Kazmierczak     if (ec.value() == EBADR || ec == boost::system::errc::host_unreachable)
469e6c388aSLukasz Kazmierczak     {
479e6c388aSLukasz Kazmierczak         messages::resourceNotFound(res, "MetricReportDefinition", id);
489e6c388aSLukasz Kazmierczak         return false;
499e6c388aSLukasz Kazmierczak     }
509e6c388aSLukasz Kazmierczak 
519e6c388aSLukasz Kazmierczak     if (ec == boost::system::errc::file_exists)
529e6c388aSLukasz Kazmierczak     {
539e6c388aSLukasz Kazmierczak         messages::resourceAlreadyExists(res, "MetricReportDefinition", "Id",
549e6c388aSLukasz Kazmierczak                                         id);
559e6c388aSLukasz Kazmierczak         return false;
569e6c388aSLukasz Kazmierczak     }
579e6c388aSLukasz Kazmierczak 
589e6c388aSLukasz Kazmierczak     if (ec == boost::system::errc::too_many_files_open)
599e6c388aSLukasz Kazmierczak     {
609e6c388aSLukasz Kazmierczak         messages::createLimitReachedForResource(res);
619e6c388aSLukasz Kazmierczak         return false;
629e6c388aSLukasz Kazmierczak     }
639e6c388aSLukasz Kazmierczak 
649e6c388aSLukasz Kazmierczak     if (ec)
659e6c388aSLukasz Kazmierczak     {
669e6c388aSLukasz Kazmierczak         BMCWEB_LOG_ERROR("DBUS response error {}", ec);
679e6c388aSLukasz Kazmierczak         messages::internalError(res);
689e6c388aSLukasz Kazmierczak         return false;
699e6c388aSLukasz Kazmierczak     }
709e6c388aSLukasz Kazmierczak 
719e6c388aSLukasz Kazmierczak     return true;
729e6c388aSLukasz Kazmierczak }
739e6c388aSLukasz Kazmierczak 
74479e899dSKrzysztof Grobelny inline metric_report_definition::ReportActionsEnum
75479e899dSKrzysztof Grobelny     toRedfishReportAction(std::string_view dbusValue)
76479e899dSKrzysztof Grobelny {
77479e899dSKrzysztof Grobelny     if (dbusValue ==
78479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportActions.EmitsReadingsUpdate")
79479e899dSKrzysztof Grobelny     {
80479e899dSKrzysztof Grobelny         return metric_report_definition::ReportActionsEnum::RedfishEvent;
81479e899dSKrzysztof Grobelny     }
82479e899dSKrzysztof Grobelny     if (dbusValue ==
83479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportActions.LogToMetricReportsCollection")
84479e899dSKrzysztof Grobelny     {
85479e899dSKrzysztof Grobelny         return metric_report_definition::ReportActionsEnum::
86479e899dSKrzysztof Grobelny             LogToMetricReportsCollection;
87479e899dSKrzysztof Grobelny     }
88479e899dSKrzysztof Grobelny     return metric_report_definition::ReportActionsEnum::Invalid;
89479e899dSKrzysztof Grobelny }
90479e899dSKrzysztof Grobelny 
91479e899dSKrzysztof Grobelny inline std::string toDbusReportAction(std::string_view redfishValue)
92479e899dSKrzysztof Grobelny {
93479e899dSKrzysztof Grobelny     if (redfishValue == "RedfishEvent")
94479e899dSKrzysztof Grobelny     {
95479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportActions.EmitsReadingsUpdate";
96479e899dSKrzysztof Grobelny     }
97479e899dSKrzysztof Grobelny     if (redfishValue == "LogToMetricReportsCollection")
98479e899dSKrzysztof Grobelny     {
99479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportActions.LogToMetricReportsCollection";
100479e899dSKrzysztof Grobelny     }
101479e899dSKrzysztof Grobelny     return "";
102479e899dSKrzysztof Grobelny }
103479e899dSKrzysztof Grobelny 
104479e899dSKrzysztof Grobelny inline metric_report_definition::MetricReportDefinitionType
105479e899dSKrzysztof Grobelny     toRedfishReportingType(std::string_view dbusValue)
106479e899dSKrzysztof Grobelny {
107479e899dSKrzysztof Grobelny     if (dbusValue ==
108479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportingType.OnChange")
109479e899dSKrzysztof Grobelny     {
110479e899dSKrzysztof Grobelny         return metric_report_definition::MetricReportDefinitionType::OnChange;
111479e899dSKrzysztof Grobelny     }
112479e899dSKrzysztof Grobelny     if (dbusValue ==
113479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportingType.OnRequest")
114479e899dSKrzysztof Grobelny     {
115479e899dSKrzysztof Grobelny         return metric_report_definition::MetricReportDefinitionType::OnRequest;
116479e899dSKrzysztof Grobelny     }
117479e899dSKrzysztof Grobelny     if (dbusValue ==
118479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportingType.Periodic")
119479e899dSKrzysztof Grobelny     {
120479e899dSKrzysztof Grobelny         return metric_report_definition::MetricReportDefinitionType::Periodic;
121479e899dSKrzysztof Grobelny     }
122479e899dSKrzysztof Grobelny     return metric_report_definition::MetricReportDefinitionType::Invalid;
123479e899dSKrzysztof Grobelny }
124479e899dSKrzysztof Grobelny 
125479e899dSKrzysztof Grobelny inline std::string toDbusReportingType(std::string_view redfishValue)
126479e899dSKrzysztof Grobelny {
127479e899dSKrzysztof Grobelny     if (redfishValue == "OnChange")
128479e899dSKrzysztof Grobelny     {
129479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportingType.OnChange";
130479e899dSKrzysztof Grobelny     }
131479e899dSKrzysztof Grobelny     if (redfishValue == "OnRequest")
132479e899dSKrzysztof Grobelny     {
133479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportingType.OnRequest";
134479e899dSKrzysztof Grobelny     }
135479e899dSKrzysztof Grobelny     if (redfishValue == "Periodic")
136479e899dSKrzysztof Grobelny     {
137479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportingType.Periodic";
138479e899dSKrzysztof Grobelny     }
139479e899dSKrzysztof Grobelny     return "";
140479e899dSKrzysztof Grobelny }
141479e899dSKrzysztof Grobelny 
142479e899dSKrzysztof Grobelny inline metric_report_definition::CollectionTimeScope
143479e899dSKrzysztof Grobelny     toRedfishCollectionTimeScope(std::string_view dbusValue)
144479e899dSKrzysztof Grobelny {
145479e899dSKrzysztof Grobelny     if (dbusValue ==
146479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Point")
147479e899dSKrzysztof Grobelny     {
148479e899dSKrzysztof Grobelny         return metric_report_definition::CollectionTimeScope::Point;
149479e899dSKrzysztof Grobelny     }
150479e899dSKrzysztof Grobelny     if (dbusValue ==
151479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Interval")
152479e899dSKrzysztof Grobelny     {
153479e899dSKrzysztof Grobelny         return metric_report_definition::CollectionTimeScope::Interval;
154479e899dSKrzysztof Grobelny     }
155479e899dSKrzysztof Grobelny     if (dbusValue ==
156479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.StartupInterval")
157479e899dSKrzysztof Grobelny     {
158479e899dSKrzysztof Grobelny         return metric_report_definition::CollectionTimeScope::StartupInterval;
159479e899dSKrzysztof Grobelny     }
160479e899dSKrzysztof Grobelny     return metric_report_definition::CollectionTimeScope::Invalid;
161479e899dSKrzysztof Grobelny }
162479e899dSKrzysztof Grobelny 
163479e899dSKrzysztof Grobelny inline std::string toDbusCollectionTimeScope(std::string_view redfishValue)
164479e899dSKrzysztof Grobelny {
165479e899dSKrzysztof Grobelny     if (redfishValue == "Point")
166479e899dSKrzysztof Grobelny     {
167479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Point";
168479e899dSKrzysztof Grobelny     }
169479e899dSKrzysztof Grobelny     if (redfishValue == "Interval")
170479e899dSKrzysztof Grobelny     {
171479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.Interval";
172479e899dSKrzysztof Grobelny     }
173479e899dSKrzysztof Grobelny     if (redfishValue == "StartupInterval")
174479e899dSKrzysztof Grobelny     {
175479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.CollectionTimescope.StartupInterval";
176479e899dSKrzysztof Grobelny     }
177479e899dSKrzysztof Grobelny     return "";
178479e899dSKrzysztof Grobelny }
179479e899dSKrzysztof Grobelny 
180479e899dSKrzysztof Grobelny inline metric_report_definition::ReportUpdatesEnum
181479e899dSKrzysztof Grobelny     toRedfishReportUpdates(std::string_view dbusValue)
182479e899dSKrzysztof Grobelny {
183479e899dSKrzysztof Grobelny     if (dbusValue ==
184479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportUpdates.Overwrite")
185479e899dSKrzysztof Grobelny     {
186479e899dSKrzysztof Grobelny         return metric_report_definition::ReportUpdatesEnum::Overwrite;
187479e899dSKrzysztof Grobelny     }
188479e899dSKrzysztof Grobelny     if (dbusValue ==
189479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendWrapsWhenFull")
190479e899dSKrzysztof Grobelny     {
191479e899dSKrzysztof Grobelny         return metric_report_definition::ReportUpdatesEnum::AppendWrapsWhenFull;
192479e899dSKrzysztof Grobelny     }
193479e899dSKrzysztof Grobelny     if (dbusValue ==
194479e899dSKrzysztof Grobelny         "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendStopsWhenFull")
195479e899dSKrzysztof Grobelny     {
196479e899dSKrzysztof Grobelny         return metric_report_definition::ReportUpdatesEnum::AppendStopsWhenFull;
197479e899dSKrzysztof Grobelny     }
198479e899dSKrzysztof Grobelny     return metric_report_definition::ReportUpdatesEnum::Invalid;
199479e899dSKrzysztof Grobelny }
200479e899dSKrzysztof Grobelny 
201479e899dSKrzysztof Grobelny inline std::string toDbusReportUpdates(std::string_view redfishValue)
202479e899dSKrzysztof Grobelny {
203479e899dSKrzysztof Grobelny     if (redfishValue == "Overwrite")
204479e899dSKrzysztof Grobelny     {
205479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.Overwrite";
206479e899dSKrzysztof Grobelny     }
207479e899dSKrzysztof Grobelny     if (redfishValue == "AppendWrapsWhenFull")
208479e899dSKrzysztof Grobelny     {
209479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendWrapsWhenFull";
210479e899dSKrzysztof Grobelny     }
211479e899dSKrzysztof Grobelny     if (redfishValue == "AppendStopsWhenFull")
212479e899dSKrzysztof Grobelny     {
213479e899dSKrzysztof Grobelny         return "xyz.openbmc_project.Telemetry.Report.ReportUpdates.AppendStopsWhenFull";
214479e899dSKrzysztof Grobelny     }
215479e899dSKrzysztof Grobelny     return "";
216479e899dSKrzysztof Grobelny }
217081ebf06SWludzik, Jozef 
218f19ab44aSSzymon Dompke inline std::optional<nlohmann::json::array_t> getLinkedTriggers(
219f19ab44aSSzymon Dompke     std::span<const sdbusplus::message::object_path> triggerPaths)
220f19ab44aSSzymon Dompke {
221f19ab44aSSzymon Dompke     nlohmann::json::array_t triggers;
222f19ab44aSSzymon Dompke 
223f19ab44aSSzymon Dompke     for (const sdbusplus::message::object_path& path : triggerPaths)
224f19ab44aSSzymon Dompke     {
225f19ab44aSSzymon Dompke         if (path.parent_path() !=
226f19ab44aSSzymon Dompke             "/xyz/openbmc_project/Telemetry/Triggers/TelemetryService")
227f19ab44aSSzymon Dompke         {
22862598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Triggers contains invalid value: {}",
22962598e31SEd Tanous                              path.str);
230f19ab44aSSzymon Dompke             return std::nullopt;
231f19ab44aSSzymon Dompke         }
232f19ab44aSSzymon Dompke 
233f19ab44aSSzymon Dompke         std::string id = path.filename();
234f19ab44aSSzymon Dompke         if (id.empty())
235f19ab44aSSzymon Dompke         {
23662598e31SEd Tanous             BMCWEB_LOG_ERROR("Property Triggers contains invalid value: {}",
23762598e31SEd Tanous                              path.str);
238f19ab44aSSzymon Dompke             return std::nullopt;
239f19ab44aSSzymon Dompke         }
240f19ab44aSSzymon Dompke         nlohmann::json::object_t trigger;
241f19ab44aSSzymon Dompke         trigger["@odata.id"] =
242f19ab44aSSzymon Dompke             boost::urls::format("/redfish/v1/TelemetryService/Triggers/{}", id);
243f19ab44aSSzymon Dompke         triggers.emplace_back(std::move(trigger));
244f19ab44aSSzymon Dompke     }
245f19ab44aSSzymon Dompke 
246f19ab44aSSzymon Dompke     return triggers;
247f19ab44aSSzymon Dompke }
248f19ab44aSSzymon Dompke 
249b9d36b47SEd Tanous inline void
250b9d36b47SEd Tanous     fillReportDefinition(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
251b9d36b47SEd Tanous                          const std::string& id,
252479e899dSKrzysztof Grobelny                          const dbus::utility::DBusPropertiesMap& properties)
253081ebf06SWludzik, Jozef {
254479e899dSKrzysztof Grobelny     std::vector<std::string> reportActions;
255479e899dSKrzysztof Grobelny     ReadingParameters readingParams;
256479e899dSKrzysztof Grobelny     std::string reportingType;
257479e899dSKrzysztof Grobelny     std::string reportUpdates;
258479e899dSKrzysztof Grobelny     std::string name;
259479e899dSKrzysztof Grobelny     uint64_t appendLimit = 0;
260479e899dSKrzysztof Grobelny     uint64_t interval = 0;
261479e899dSKrzysztof Grobelny     bool enabled = false;
262f19ab44aSSzymon Dompke     std::vector<sdbusplus::message::object_path> triggers;
26389474494SKrzysztof Grobelny 
26489474494SKrzysztof Grobelny     const bool success = sdbusplus::unpackPropertiesNoThrow(
265479e899dSKrzysztof Grobelny         dbus_utils::UnpackErrorPrinter(), properties, "ReportingType",
266479e899dSKrzysztof Grobelny         reportingType, "Interval", interval, "ReportActions", reportActions,
267479e899dSKrzysztof Grobelny         "ReportUpdates", reportUpdates, "AppendLimit", appendLimit,
268f19ab44aSSzymon Dompke         "ReadingParameters", readingParams, "Name", name, "Enabled", enabled,
269f19ab44aSSzymon Dompke         "Triggers", triggers);
27089474494SKrzysztof Grobelny 
27189474494SKrzysztof Grobelny     if (!success)
272081ebf06SWludzik, Jozef     {
273081ebf06SWludzik, Jozef         messages::internalError(asyncResp->res);
274081ebf06SWludzik, Jozef         return;
275081ebf06SWludzik, Jozef     }
276081ebf06SWludzik, Jozef 
277479e899dSKrzysztof Grobelny     metric_report_definition::MetricReportDefinitionType redfishReportingType =
278479e899dSKrzysztof Grobelny         toRedfishReportingType(reportingType);
279479e899dSKrzysztof Grobelny     if (redfishReportingType ==
280479e899dSKrzysztof Grobelny         metric_report_definition::MetricReportDefinitionType::Invalid)
281081ebf06SWludzik, Jozef     {
282479e899dSKrzysztof Grobelny         messages::internalError(asyncResp->res);
283479e899dSKrzysztof Grobelny         return;
284081ebf06SWludzik, Jozef     }
28589474494SKrzysztof Grobelny 
286479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["MetricReportDefinitionType"] =
287479e899dSKrzysztof Grobelny         redfishReportingType;
288479e899dSKrzysztof Grobelny 
289f19ab44aSSzymon Dompke     std::optional<nlohmann::json::array_t> linkedTriggers =
290f19ab44aSSzymon Dompke         getLinkedTriggers(triggers);
291f19ab44aSSzymon Dompke     if (!linkedTriggers)
292f19ab44aSSzymon Dompke     {
293f19ab44aSSzymon Dompke         messages::internalError(asyncResp->res);
294f19ab44aSSzymon Dompke         return;
295f19ab44aSSzymon Dompke     }
296f19ab44aSSzymon Dompke 
297f19ab44aSSzymon Dompke     asyncResp->res.jsonValue["Links"]["Triggers"] = std::move(*linkedTriggers);
298f19ab44aSSzymon Dompke 
299479e899dSKrzysztof Grobelny     nlohmann::json::array_t redfishReportActions;
300479e899dSKrzysztof Grobelny     for (const std::string& action : reportActions)
301081ebf06SWludzik, Jozef     {
302479e899dSKrzysztof Grobelny         metric_report_definition::ReportActionsEnum redfishAction =
303479e899dSKrzysztof Grobelny             toRedfishReportAction(action);
304479e899dSKrzysztof Grobelny         if (redfishAction ==
305479e899dSKrzysztof Grobelny             metric_report_definition::ReportActionsEnum::Invalid)
306479e899dSKrzysztof Grobelny         {
307479e899dSKrzysztof Grobelny             messages::internalError(asyncResp->res);
308479e899dSKrzysztof Grobelny             return;
309081ebf06SWludzik, Jozef         }
310081ebf06SWludzik, Jozef 
311479e899dSKrzysztof Grobelny         redfishReportActions.emplace_back(redfishAction);
312479e899dSKrzysztof Grobelny     }
313479e899dSKrzysztof Grobelny 
314479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["ReportActions"] = std::move(redfishReportActions);
315479e899dSKrzysztof Grobelny 
316479e899dSKrzysztof Grobelny     nlohmann::json::array_t metrics = nlohmann::json::array();
317479e899dSKrzysztof Grobelny     for (const auto& [sensorData, collectionFunction, collectionTimeScope,
318479e899dSKrzysztof Grobelny                       collectionDuration] : readingParams)
31989474494SKrzysztof Grobelny     {
320479e899dSKrzysztof Grobelny         nlohmann::json::array_t metricProperties;
321479e899dSKrzysztof Grobelny 
322479e899dSKrzysztof Grobelny         for (const auto& [sensorPath, sensorMetadata] : sensorData)
323081ebf06SWludzik, Jozef         {
324479e899dSKrzysztof Grobelny             metricProperties.emplace_back(sensorMetadata);
325479e899dSKrzysztof Grobelny         }
326479e899dSKrzysztof Grobelny 
327613dabeaSEd Tanous         nlohmann::json::object_t metric;
328479e899dSKrzysztof Grobelny 
329479e899dSKrzysztof Grobelny         metric_report_definition::CalculationAlgorithmEnum
330479e899dSKrzysztof Grobelny             redfishCollectionFunction =
331479e899dSKrzysztof Grobelny                 telemetry::toRedfishCollectionFunction(collectionFunction);
332479e899dSKrzysztof Grobelny         if (redfishCollectionFunction ==
333479e899dSKrzysztof Grobelny             metric_report_definition::CalculationAlgorithmEnum::Invalid)
334479e899dSKrzysztof Grobelny         {
335479e899dSKrzysztof Grobelny             messages::internalError(asyncResp->res);
336479e899dSKrzysztof Grobelny             return;
337479e899dSKrzysztof Grobelny         }
338479e899dSKrzysztof Grobelny         metric["CollectionFunction"] = redfishCollectionFunction;
339479e899dSKrzysztof Grobelny 
340479e899dSKrzysztof Grobelny         metric_report_definition::CollectionTimeScope
341479e899dSKrzysztof Grobelny             redfishCollectionTimeScope =
342479e899dSKrzysztof Grobelny                 toRedfishCollectionTimeScope(collectionTimeScope);
343479e899dSKrzysztof Grobelny         if (redfishCollectionTimeScope ==
344479e899dSKrzysztof Grobelny             metric_report_definition::CollectionTimeScope::Invalid)
345479e899dSKrzysztof Grobelny         {
346479e899dSKrzysztof Grobelny             messages::internalError(asyncResp->res);
347479e899dSKrzysztof Grobelny             return;
348479e899dSKrzysztof Grobelny         }
349479e899dSKrzysztof Grobelny         metric["CollectionTimeScope"] = redfishCollectionTimeScope;
350479e899dSKrzysztof Grobelny 
351479e899dSKrzysztof Grobelny         metric["MetricProperties"] = std::move(metricProperties);
352479e899dSKrzysztof Grobelny         metric["CollectionDuration"] = time_utils::toDurationString(
353479e899dSKrzysztof Grobelny             std::chrono::milliseconds(collectionDuration));
354b2ba3072SPatrick Williams         metrics.emplace_back(std::move(metric));
355081ebf06SWludzik, Jozef     }
356479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["Metrics"] = std::move(metrics);
357479e899dSKrzysztof Grobelny 
358479e899dSKrzysztof Grobelny     if (enabled)
359479e899dSKrzysztof Grobelny     {
360*539d8c6bSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
361479e899dSKrzysztof Grobelny     }
362479e899dSKrzysztof Grobelny     else
363479e899dSKrzysztof Grobelny     {
364*539d8c6bSEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = resource::State::Disabled;
36589474494SKrzysztof Grobelny     }
36689474494SKrzysztof Grobelny 
367479e899dSKrzysztof Grobelny     metric_report_definition::ReportUpdatesEnum redfishReportUpdates =
368479e899dSKrzysztof Grobelny         toRedfishReportUpdates(reportUpdates);
369479e899dSKrzysztof Grobelny     if (redfishReportUpdates ==
370479e899dSKrzysztof Grobelny         metric_report_definition::ReportUpdatesEnum::Invalid)
37189474494SKrzysztof Grobelny     {
372479e899dSKrzysztof Grobelny         messages::internalError(asyncResp->res);
373479e899dSKrzysztof Grobelny         return;
37489474494SKrzysztof Grobelny     }
375479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["ReportUpdates"] = redfishReportUpdates;
37689474494SKrzysztof Grobelny 
377479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["MetricReportDefinitionEnabled"] = enabled;
378479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["AppendLimit"] = appendLimit;
379479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["Name"] = name;
380081ebf06SWludzik, Jozef     asyncResp->res.jsonValue["Schedule"]["RecurrenceInterval"] =
381479e899dSKrzysztof Grobelny         time_utils::toDurationString(std::chrono::milliseconds(interval));
382479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["@odata.type"] =
383479e899dSKrzysztof Grobelny         "#MetricReportDefinition.v1_3_0.MetricReportDefinition";
384479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
385479e899dSKrzysztof Grobelny         "/redfish/v1/TelemetryService/MetricReportDefinitions/{}", id);
386479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["Id"] = id;
387479e899dSKrzysztof Grobelny     asyncResp->res.jsonValue["MetricReport"]["@odata.id"] = boost::urls::format(
388479e899dSKrzysztof Grobelny         "/redfish/v1/TelemetryService/MetricReports/{}", id);
38989474494SKrzysztof Grobelny }
39089474494SKrzysztof Grobelny 
3914dbb8aeaSWludzik, Jozef struct AddReportArgs
3924dbb8aeaSWludzik, Jozef {
393479e899dSKrzysztof Grobelny     struct MetricArgs
394479e899dSKrzysztof Grobelny     {
395479e899dSKrzysztof Grobelny         std::vector<std::string> uris;
396479e899dSKrzysztof Grobelny         std::string collectionFunction;
397479e899dSKrzysztof Grobelny         std::string collectionTimeScope;
398479e899dSKrzysztof Grobelny         uint64_t collectionDuration = 0;
399479e899dSKrzysztof Grobelny     };
400479e899dSKrzysztof Grobelny 
401479e899dSKrzysztof Grobelny     std::string id;
4024dbb8aeaSWludzik, Jozef     std::string name;
4034dbb8aeaSWludzik, Jozef     std::string reportingType;
404479e899dSKrzysztof Grobelny     std::string reportUpdates;
405479e899dSKrzysztof Grobelny     uint64_t appendLimit = std::numeric_limits<uint64_t>::max();
406479e899dSKrzysztof Grobelny     std::vector<std::string> reportActions;
407479e899dSKrzysztof Grobelny     uint64_t interval = std::numeric_limits<uint64_t>::max();
408479e899dSKrzysztof Grobelny     std::vector<MetricArgs> metrics;
409479e899dSKrzysztof Grobelny     bool metricReportDefinitionEnabled = true;
4104dbb8aeaSWludzik, Jozef };
4114dbb8aeaSWludzik, Jozef 
4124dbb8aeaSWludzik, Jozef inline bool toDbusReportActions(crow::Response& res,
413479e899dSKrzysztof Grobelny                                 const std::vector<std::string>& actions,
4149e6c388aSLukasz Kazmierczak                                 std::vector<std::string>& outReportActions)
4154dbb8aeaSWludzik, Jozef {
4164dbb8aeaSWludzik, Jozef     size_t index = 0;
417479e899dSKrzysztof Grobelny     for (const std::string& action : actions)
4184dbb8aeaSWludzik, Jozef     {
419479e899dSKrzysztof Grobelny         std::string dbusReportAction = toDbusReportAction(action);
420479e899dSKrzysztof Grobelny         if (dbusReportAction.empty())
4214dbb8aeaSWludzik, Jozef         {
4229e6c388aSLukasz Kazmierczak             messages::propertyValueNotInList(
4239e6c388aSLukasz Kazmierczak                 res, action, "ReportActions/" + std::to_string(index));
4244dbb8aeaSWludzik, Jozef             return false;
4254dbb8aeaSWludzik, Jozef         }
426479e899dSKrzysztof Grobelny 
4279e6c388aSLukasz Kazmierczak         outReportActions.emplace_back(std::move(dbusReportAction));
4284dbb8aeaSWludzik, Jozef         index++;
4294dbb8aeaSWludzik, Jozef     }
4304dbb8aeaSWludzik, Jozef     return true;
4314dbb8aeaSWludzik, Jozef }
4324dbb8aeaSWludzik, Jozef 
433b14f357fSEd Tanous inline bool getUserMetric(crow::Response& res, nlohmann::json::object_t& metric,
434479e899dSKrzysztof Grobelny                           AddReportArgs::MetricArgs& metricArgs)
435479e899dSKrzysztof Grobelny {
436479e899dSKrzysztof Grobelny     std::optional<std::vector<std::string>> uris;
437479e899dSKrzysztof Grobelny     std::optional<std::string> collectionDurationStr;
438479e899dSKrzysztof Grobelny     std::optional<std::string> collectionFunction;
439479e899dSKrzysztof Grobelny     std::optional<std::string> collectionTimeScopeStr;
440479e899dSKrzysztof Grobelny 
441b14f357fSEd Tanous     if (!json_util::readJsonObject(
442b14f357fSEd Tanous             metric, res, "MetricProperties", uris, "CollectionFunction",
443b14f357fSEd Tanous             collectionFunction, "CollectionTimeScope", collectionTimeScopeStr,
444479e899dSKrzysztof Grobelny             "CollectionDuration", collectionDurationStr))
445479e899dSKrzysztof Grobelny     {
446479e899dSKrzysztof Grobelny         return false;
447479e899dSKrzysztof Grobelny     }
448479e899dSKrzysztof Grobelny 
449479e899dSKrzysztof Grobelny     if (uris)
450479e899dSKrzysztof Grobelny     {
451479e899dSKrzysztof Grobelny         metricArgs.uris = std::move(*uris);
452479e899dSKrzysztof Grobelny     }
453479e899dSKrzysztof Grobelny 
454479e899dSKrzysztof Grobelny     if (collectionFunction)
455479e899dSKrzysztof Grobelny     {
456479e899dSKrzysztof Grobelny         std::string dbusCollectionFunction =
457479e899dSKrzysztof Grobelny             telemetry::toDbusCollectionFunction(*collectionFunction);
458479e899dSKrzysztof Grobelny         if (dbusCollectionFunction.empty())
459479e899dSKrzysztof Grobelny         {
460479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "CollectionFunction",
461479e899dSKrzysztof Grobelny                                              *collectionFunction);
462479e899dSKrzysztof Grobelny             return false;
463479e899dSKrzysztof Grobelny         }
464479e899dSKrzysztof Grobelny         metricArgs.collectionFunction = std::move(dbusCollectionFunction);
465479e899dSKrzysztof Grobelny     }
466479e899dSKrzysztof Grobelny 
467479e899dSKrzysztof Grobelny     if (collectionTimeScopeStr)
468479e899dSKrzysztof Grobelny     {
469479e899dSKrzysztof Grobelny         std::string dbusCollectionTimeScope =
470479e899dSKrzysztof Grobelny             toDbusCollectionTimeScope(*collectionTimeScopeStr);
471479e899dSKrzysztof Grobelny         if (dbusCollectionTimeScope.empty())
472479e899dSKrzysztof Grobelny         {
473479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "CollectionTimeScope",
474479e899dSKrzysztof Grobelny                                              *collectionTimeScopeStr);
475479e899dSKrzysztof Grobelny             return false;
476479e899dSKrzysztof Grobelny         }
477479e899dSKrzysztof Grobelny         metricArgs.collectionTimeScope = std::move(dbusCollectionTimeScope);
478479e899dSKrzysztof Grobelny     }
479479e899dSKrzysztof Grobelny 
480479e899dSKrzysztof Grobelny     if (collectionDurationStr)
481479e899dSKrzysztof Grobelny     {
482479e899dSKrzysztof Grobelny         std::optional<std::chrono::milliseconds> duration =
483479e899dSKrzysztof Grobelny             time_utils::fromDurationString(*collectionDurationStr);
484479e899dSKrzysztof Grobelny 
485479e899dSKrzysztof Grobelny         if (!duration || duration->count() < 0)
486479e899dSKrzysztof Grobelny         {
487479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "CollectionDuration",
488479e899dSKrzysztof Grobelny                                              *collectionDurationStr);
489479e899dSKrzysztof Grobelny             return false;
490479e899dSKrzysztof Grobelny         }
491479e899dSKrzysztof Grobelny 
492479e899dSKrzysztof Grobelny         metricArgs.collectionDuration =
493479e899dSKrzysztof Grobelny             static_cast<uint64_t>(duration->count());
494479e899dSKrzysztof Grobelny     }
495479e899dSKrzysztof Grobelny 
496479e899dSKrzysztof Grobelny     return true;
497479e899dSKrzysztof Grobelny }
498479e899dSKrzysztof Grobelny 
499479e899dSKrzysztof Grobelny inline bool getUserMetrics(crow::Response& res,
500b14f357fSEd Tanous                            std::span<nlohmann::json::object_t> metrics,
501479e899dSKrzysztof Grobelny                            std::vector<AddReportArgs::MetricArgs>& result)
502479e899dSKrzysztof Grobelny {
503479e899dSKrzysztof Grobelny     result.reserve(metrics.size());
504479e899dSKrzysztof Grobelny 
505b14f357fSEd Tanous     for (nlohmann::json::object_t& m : metrics)
506479e899dSKrzysztof Grobelny     {
507479e899dSKrzysztof Grobelny         AddReportArgs::MetricArgs metricArgs;
508479e899dSKrzysztof Grobelny 
509479e899dSKrzysztof Grobelny         if (!getUserMetric(res, m, metricArgs))
510479e899dSKrzysztof Grobelny         {
511479e899dSKrzysztof Grobelny             return false;
512479e899dSKrzysztof Grobelny         }
513479e899dSKrzysztof Grobelny 
514479e899dSKrzysztof Grobelny         result.emplace_back(std::move(metricArgs));
515479e899dSKrzysztof Grobelny     }
516479e899dSKrzysztof Grobelny 
517479e899dSKrzysztof Grobelny     return true;
518479e899dSKrzysztof Grobelny }
519479e899dSKrzysztof Grobelny 
5204dbb8aeaSWludzik, Jozef inline bool getUserParameters(crow::Response& res, const crow::Request& req,
5214dbb8aeaSWludzik, Jozef                               AddReportArgs& args)
5224dbb8aeaSWludzik, Jozef {
523479e899dSKrzysztof Grobelny     std::optional<std::string> id;
524479e899dSKrzysztof Grobelny     std::optional<std::string> name;
525479e899dSKrzysztof Grobelny     std::optional<std::string> reportingTypeStr;
526479e899dSKrzysztof Grobelny     std::optional<std::string> reportUpdatesStr;
527479e899dSKrzysztof Grobelny     std::optional<uint64_t> appendLimit;
528479e899dSKrzysztof Grobelny     std::optional<bool> metricReportDefinitionEnabled;
529b14f357fSEd Tanous     std::optional<std::vector<nlohmann::json::object_t>> metrics;
530479e899dSKrzysztof Grobelny     std::optional<std::vector<std::string>> reportActionsStr;
531b14f357fSEd Tanous     std::optional<std::string> scheduleDurationStr;
532479e899dSKrzysztof Grobelny 
533479e899dSKrzysztof Grobelny     if (!json_util::readJsonPatch(
534479e899dSKrzysztof Grobelny             req, res, "Id", id, "Name", name, "Metrics", metrics,
535479e899dSKrzysztof Grobelny             "MetricReportDefinitionType", reportingTypeStr, "ReportUpdates",
536479e899dSKrzysztof Grobelny             reportUpdatesStr, "AppendLimit", appendLimit, "ReportActions",
537b14f357fSEd Tanous             reportActionsStr, "Schedule/RecurrenceInterval",
538b14f357fSEd Tanous             scheduleDurationStr, "MetricReportDefinitionEnabled",
539b14f357fSEd Tanous             metricReportDefinitionEnabled))
5404dbb8aeaSWludzik, Jozef     {
5414dbb8aeaSWludzik, Jozef         return false;
5424dbb8aeaSWludzik, Jozef     }
5434dbb8aeaSWludzik, Jozef 
544479e899dSKrzysztof Grobelny     if (id)
545479e899dSKrzysztof Grobelny     {
546479e899dSKrzysztof Grobelny         constexpr const char* allowedCharactersInId =
5474dbb8aeaSWludzik, Jozef             "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
548479e899dSKrzysztof Grobelny         if (id->empty() ||
549479e899dSKrzysztof Grobelny             id->find_first_not_of(allowedCharactersInId) != std::string::npos)
5504dbb8aeaSWludzik, Jozef         {
551479e899dSKrzysztof Grobelny             messages::propertyValueIncorrect(res, "Id", *id);
5524dbb8aeaSWludzik, Jozef             return false;
5534dbb8aeaSWludzik, Jozef         }
554479e899dSKrzysztof Grobelny         args.id = *id;
555479e899dSKrzysztof Grobelny     }
5564dbb8aeaSWludzik, Jozef 
557479e899dSKrzysztof Grobelny     if (name)
5584dbb8aeaSWludzik, Jozef     {
559479e899dSKrzysztof Grobelny         args.name = *name;
560479e899dSKrzysztof Grobelny     }
561479e899dSKrzysztof Grobelny 
562479e899dSKrzysztof Grobelny     if (reportingTypeStr)
563479e899dSKrzysztof Grobelny     {
564479e899dSKrzysztof Grobelny         std::string dbusReportingType = toDbusReportingType(*reportingTypeStr);
565479e899dSKrzysztof Grobelny         if (dbusReportingType.empty())
566479e899dSKrzysztof Grobelny         {
567479e899dSKrzysztof Grobelny             messages::propertyValueNotInList(res, *reportingTypeStr,
5684dbb8aeaSWludzik, Jozef                                              "MetricReportDefinitionType");
5694dbb8aeaSWludzik, Jozef             return false;
5704dbb8aeaSWludzik, Jozef         }
571479e899dSKrzysztof Grobelny         args.reportingType = dbusReportingType;
572479e899dSKrzysztof Grobelny     }
5734dbb8aeaSWludzik, Jozef 
574479e899dSKrzysztof Grobelny     if (reportUpdatesStr)
575479e899dSKrzysztof Grobelny     {
576479e899dSKrzysztof Grobelny         std::string dbusReportUpdates = toDbusReportUpdates(*reportUpdatesStr);
577479e899dSKrzysztof Grobelny         if (dbusReportUpdates.empty())
578479e899dSKrzysztof Grobelny         {
579479e899dSKrzysztof Grobelny             messages::propertyValueNotInList(res, *reportUpdatesStr,
580479e899dSKrzysztof Grobelny                                              "ReportUpdates");
581479e899dSKrzysztof Grobelny             return false;
582479e899dSKrzysztof Grobelny         }
583479e899dSKrzysztof Grobelny         args.reportUpdates = dbusReportUpdates;
584479e899dSKrzysztof Grobelny     }
585479e899dSKrzysztof Grobelny 
586479e899dSKrzysztof Grobelny     if (appendLimit)
587479e899dSKrzysztof Grobelny     {
588479e899dSKrzysztof Grobelny         args.appendLimit = *appendLimit;
589479e899dSKrzysztof Grobelny     }
590479e899dSKrzysztof Grobelny 
591479e899dSKrzysztof Grobelny     if (metricReportDefinitionEnabled)
592479e899dSKrzysztof Grobelny     {
593479e899dSKrzysztof Grobelny         args.metricReportDefinitionEnabled = *metricReportDefinitionEnabled;
594479e899dSKrzysztof Grobelny     }
595479e899dSKrzysztof Grobelny 
596479e899dSKrzysztof Grobelny     if (reportActionsStr)
597479e899dSKrzysztof Grobelny     {
5989e6c388aSLukasz Kazmierczak         if (!toDbusReportActions(res, *reportActionsStr, args.reportActions))
5994dbb8aeaSWludzik, Jozef         {
6004dbb8aeaSWludzik, Jozef             return false;
6014dbb8aeaSWludzik, Jozef         }
602479e899dSKrzysztof Grobelny     }
6034dbb8aeaSWludzik, Jozef 
604479e899dSKrzysztof Grobelny     if (reportingTypeStr == "Periodic")
6054dbb8aeaSWludzik, Jozef     {
606b14f357fSEd Tanous         if (!scheduleDurationStr)
6074dbb8aeaSWludzik, Jozef         {
6084dbb8aeaSWludzik, Jozef             messages::createFailedMissingReqProperties(res, "Schedule");
6094dbb8aeaSWludzik, Jozef             return false;
6104dbb8aeaSWludzik, Jozef         }
6114dbb8aeaSWludzik, Jozef 
6124dbb8aeaSWludzik, Jozef         std::optional<std::chrono::milliseconds> durationNum =
613b14f357fSEd Tanous             time_utils::fromDurationString(*scheduleDurationStr);
614479e899dSKrzysztof Grobelny         if (!durationNum || durationNum->count() < 0)
6154dbb8aeaSWludzik, Jozef         {
6164dbb8aeaSWludzik, Jozef             messages::propertyValueIncorrect(res, "RecurrenceInterval",
617b14f357fSEd Tanous                                              *scheduleDurationStr);
6184dbb8aeaSWludzik, Jozef             return false;
6194dbb8aeaSWludzik, Jozef         }
6204dbb8aeaSWludzik, Jozef         args.interval = static_cast<uint64_t>(durationNum->count());
6214dbb8aeaSWludzik, Jozef     }
6224dbb8aeaSWludzik, Jozef 
623479e899dSKrzysztof Grobelny     if (metrics)
6244dbb8aeaSWludzik, Jozef     {
625479e899dSKrzysztof Grobelny         if (!getUserMetrics(res, *metrics, args.metrics))
6264dbb8aeaSWludzik, Jozef         {
6274dbb8aeaSWludzik, Jozef             return false;
6284dbb8aeaSWludzik, Jozef         }
6294dbb8aeaSWludzik, Jozef     }
6304dbb8aeaSWludzik, Jozef 
6314dbb8aeaSWludzik, Jozef     return true;
6324dbb8aeaSWludzik, Jozef }
6334dbb8aeaSWludzik, Jozef 
634ca1600c1SSzymon Dompke inline bool getChassisSensorNodeFromMetrics(
6358d1b46d7Szhanghch05     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
636479e899dSKrzysztof Grobelny     std::span<const AddReportArgs::MetricArgs> metrics,
6374dbb8aeaSWludzik, Jozef     boost::container::flat_set<std::pair<std::string, std::string>>& matched)
6384dbb8aeaSWludzik, Jozef {
639ca1600c1SSzymon Dompke     for (const auto& metric : metrics)
6404dbb8aeaSWludzik, Jozef     {
641479e899dSKrzysztof Grobelny         std::optional<IncorrectMetricUri> error =
642479e899dSKrzysztof Grobelny             getChassisSensorNode(metric.uris, matched);
643ca1600c1SSzymon Dompke         if (error)
6444dbb8aeaSWludzik, Jozef         {
645ca1600c1SSzymon Dompke             messages::propertyValueIncorrect(asyncResp->res, error->uri,
6464dbb8aeaSWludzik, Jozef                                              "MetricProperties/" +
647ca1600c1SSzymon Dompke                                                  std::to_string(error->index));
6484dbb8aeaSWludzik, Jozef             return false;
6494dbb8aeaSWludzik, Jozef         }
6504dbb8aeaSWludzik, Jozef     }
6514dbb8aeaSWludzik, Jozef     return true;
6524dbb8aeaSWludzik, Jozef }
6534dbb8aeaSWludzik, Jozef 
6544dbb8aeaSWludzik, Jozef class AddReport
6554dbb8aeaSWludzik, Jozef {
6564dbb8aeaSWludzik, Jozef   public:
657891eaa7cSEd Tanous     AddReport(AddReportArgs&& argsIn,
6588a592810SEd Tanous               const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
6598a592810SEd Tanous         asyncResp(asyncRespIn),
6609e6c388aSLukasz Kazmierczak         args(std::move(argsIn))
6614dbb8aeaSWludzik, Jozef     {}
662479e899dSKrzysztof Grobelny 
6634dbb8aeaSWludzik, Jozef     ~AddReport()
6644dbb8aeaSWludzik, Jozef     {
665479e899dSKrzysztof Grobelny         boost::asio::post(crow::connections::systemBus->get_io_context(),
666479e899dSKrzysztof Grobelny                           std::bind_front(&performAddReport, asyncResp, args,
667479e899dSKrzysztof Grobelny                                           std::move(uriToDbus)));
668479e899dSKrzysztof Grobelny     }
669479e899dSKrzysztof Grobelny 
670479e899dSKrzysztof Grobelny     static void performAddReport(
671479e899dSKrzysztof Grobelny         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
672479e899dSKrzysztof Grobelny         const AddReportArgs& args,
673479e899dSKrzysztof Grobelny         const boost::container::flat_map<std::string, std::string>& uriToDbus)
674479e899dSKrzysztof Grobelny     {
6754dbb8aeaSWludzik, Jozef         if (asyncResp->res.result() != boost::beast::http::status::ok)
6764dbb8aeaSWludzik, Jozef         {
6774dbb8aeaSWludzik, Jozef             return;
6784dbb8aeaSWludzik, Jozef         }
6794dbb8aeaSWludzik, Jozef 
6804dbb8aeaSWludzik, Jozef         telemetry::ReadingParameters readingParams;
6814dbb8aeaSWludzik, Jozef         readingParams.reserve(args.metrics.size());
6824dbb8aeaSWludzik, Jozef 
683479e899dSKrzysztof Grobelny         for (const auto& metric : args.metrics)
6844dbb8aeaSWludzik, Jozef         {
685479e899dSKrzysztof Grobelny             std::vector<
686479e899dSKrzysztof Grobelny                 std::tuple<sdbusplus::message::object_path, std::string>>
687479e899dSKrzysztof Grobelny                 sensorParams;
688479e899dSKrzysztof Grobelny             sensorParams.reserve(metric.uris.size());
689479e899dSKrzysztof Grobelny 
690479e899dSKrzysztof Grobelny             for (size_t i = 0; i < metric.uris.size(); i++)
6914dbb8aeaSWludzik, Jozef             {
692479e899dSKrzysztof Grobelny                 const std::string& uri = metric.uris[i];
6934dbb8aeaSWludzik, Jozef                 auto el = uriToDbus.find(uri);
6944dbb8aeaSWludzik, Jozef                 if (el == uriToDbus.end())
6954dbb8aeaSWludzik, Jozef                 {
69662598e31SEd Tanous                     BMCWEB_LOG_ERROR(
69762598e31SEd Tanous                         "Failed to find DBus sensor corresponding to URI {}",
69862598e31SEd Tanous                         uri);
6994dbb8aeaSWludzik, Jozef                     messages::propertyValueNotInList(asyncResp->res, uri,
7004dbb8aeaSWludzik, Jozef                                                      "MetricProperties/" +
7014dbb8aeaSWludzik, Jozef                                                          std::to_string(i));
7024dbb8aeaSWludzik, Jozef                     return;
7034dbb8aeaSWludzik, Jozef                 }
7044dbb8aeaSWludzik, Jozef 
7054dbb8aeaSWludzik, Jozef                 const std::string& dbusPath = el->second;
706479e899dSKrzysztof Grobelny                 sensorParams.emplace_back(dbusPath, uri);
7074dbb8aeaSWludzik, Jozef             }
708479e899dSKrzysztof Grobelny 
709479e899dSKrzysztof Grobelny             readingParams.emplace_back(
710479e899dSKrzysztof Grobelny                 std::move(sensorParams), metric.collectionFunction,
711479e899dSKrzysztof Grobelny                 metric.collectionTimeScope, metric.collectionDuration);
7124dbb8aeaSWludzik, Jozef         }
713479e899dSKrzysztof Grobelny 
7144dbb8aeaSWludzik, Jozef         crow::connections::systemBus->async_method_call(
715479e899dSKrzysztof Grobelny             [asyncResp, id = args.id, uriToDbus](
7165e7e2dc5SEd Tanous                 const boost::system::error_code& ec, const std::string&) {
7174dbb8aeaSWludzik, Jozef             if (ec == boost::system::errc::file_exists)
7184dbb8aeaSWludzik, Jozef             {
7194dbb8aeaSWludzik, Jozef                 messages::resourceAlreadyExists(
720479e899dSKrzysztof Grobelny                     asyncResp->res, "MetricReportDefinition", "Id", id);
7214dbb8aeaSWludzik, Jozef                 return;
7224dbb8aeaSWludzik, Jozef             }
7234dbb8aeaSWludzik, Jozef             if (ec == boost::system::errc::too_many_files_open)
7244dbb8aeaSWludzik, Jozef             {
725479e899dSKrzysztof Grobelny                 messages::createLimitReachedForResource(asyncResp->res);
7264dbb8aeaSWludzik, Jozef                 return;
7274dbb8aeaSWludzik, Jozef             }
7284dbb8aeaSWludzik, Jozef             if (ec == boost::system::errc::argument_list_too_long)
7294dbb8aeaSWludzik, Jozef             {
7304dbb8aeaSWludzik, Jozef                 nlohmann::json metricProperties = nlohmann::json::array();
7314dbb8aeaSWludzik, Jozef                 for (const auto& [uri, _] : uriToDbus)
7324dbb8aeaSWludzik, Jozef                 {
7334dbb8aeaSWludzik, Jozef                     metricProperties.emplace_back(uri);
7344dbb8aeaSWludzik, Jozef                 }
73514fbced6SEd Tanous                 messages::propertyValueIncorrect(
736367b3dceSGinu George                     asyncResp->res, "MetricProperties", metricProperties);
7374dbb8aeaSWludzik, Jozef                 return;
7384dbb8aeaSWludzik, Jozef             }
7394dbb8aeaSWludzik, Jozef             if (ec)
7404dbb8aeaSWludzik, Jozef             {
741479e899dSKrzysztof Grobelny                 messages::internalError(asyncResp->res);
74262598e31SEd Tanous                 BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
7434dbb8aeaSWludzik, Jozef                 return;
7444dbb8aeaSWludzik, Jozef             }
7454dbb8aeaSWludzik, Jozef 
746479e899dSKrzysztof Grobelny             messages::created(asyncResp->res);
7474dbb8aeaSWludzik, Jozef         },
7484dbb8aeaSWludzik, Jozef             telemetry::service, "/xyz/openbmc_project/Telemetry/Reports",
7494dbb8aeaSWludzik, Jozef             "xyz.openbmc_project.Telemetry.ReportManager", "AddReport",
750479e899dSKrzysztof Grobelny             "TelemetryService/" + args.id, args.name, args.reportingType,
751479e899dSKrzysztof Grobelny             args.reportUpdates, args.appendLimit, args.reportActions,
752479e899dSKrzysztof Grobelny             args.interval, readingParams, args.metricReportDefinitionEnabled);
7534dbb8aeaSWludzik, Jozef     }
7544dbb8aeaSWludzik, Jozef 
755ecd6a3a2SEd Tanous     AddReport(const AddReport&) = delete;
756ecd6a3a2SEd Tanous     AddReport(AddReport&&) = delete;
757ecd6a3a2SEd Tanous     AddReport& operator=(const AddReport&) = delete;
758ecd6a3a2SEd Tanous     AddReport& operator=(AddReport&&) = delete;
759ecd6a3a2SEd Tanous 
760fe04d49cSNan Zhou     void insert(const std::map<std::string, std::string>& el)
7614dbb8aeaSWludzik, Jozef     {
7624dbb8aeaSWludzik, Jozef         uriToDbus.insert(el.begin(), el.end());
7634dbb8aeaSWludzik, Jozef     }
7644dbb8aeaSWludzik, Jozef 
7654dbb8aeaSWludzik, Jozef   private:
766479e899dSKrzysztof Grobelny     std::shared_ptr<bmcweb::AsyncResp> asyncResp;
7674dbb8aeaSWludzik, Jozef     AddReportArgs args;
76847f2934cSEd Tanous     boost::container::flat_map<std::string, std::string> uriToDbus;
7694dbb8aeaSWludzik, Jozef };
7709e6c388aSLukasz Kazmierczak 
7719e6c388aSLukasz Kazmierczak class UpdateMetrics
7729e6c388aSLukasz Kazmierczak {
7739e6c388aSLukasz Kazmierczak   public:
7749e6c388aSLukasz Kazmierczak     UpdateMetrics(std::string_view idIn,
7759e6c388aSLukasz Kazmierczak                   const std::shared_ptr<bmcweb::AsyncResp>& asyncRespIn) :
7769e6c388aSLukasz Kazmierczak         id(idIn),
7779e6c388aSLukasz Kazmierczak         asyncResp(asyncRespIn)
7789e6c388aSLukasz Kazmierczak     {}
7799e6c388aSLukasz Kazmierczak 
7809e6c388aSLukasz Kazmierczak     ~UpdateMetrics()
7819e6c388aSLukasz Kazmierczak     {
7829e6c388aSLukasz Kazmierczak         try
7839e6c388aSLukasz Kazmierczak         {
7849e6c388aSLukasz Kazmierczak             setReadingParams();
7859e6c388aSLukasz Kazmierczak         }
7869e6c388aSLukasz Kazmierczak         catch (const std::exception& e)
7879e6c388aSLukasz Kazmierczak         {
7889e6c388aSLukasz Kazmierczak             BMCWEB_LOG_ERROR("{}", e.what());
7899e6c388aSLukasz Kazmierczak         }
7909e6c388aSLukasz Kazmierczak         catch (...)
7919e6c388aSLukasz Kazmierczak         {
7929e6c388aSLukasz Kazmierczak             BMCWEB_LOG_ERROR("Unknown error");
7939e6c388aSLukasz Kazmierczak         }
7949e6c388aSLukasz Kazmierczak     }
7959e6c388aSLukasz Kazmierczak 
7969e6c388aSLukasz Kazmierczak     UpdateMetrics(const UpdateMetrics&) = delete;
7979e6c388aSLukasz Kazmierczak     UpdateMetrics(UpdateMetrics&&) = delete;
7989e6c388aSLukasz Kazmierczak     UpdateMetrics& operator=(const UpdateMetrics&) = delete;
7999e6c388aSLukasz Kazmierczak     UpdateMetrics& operator=(UpdateMetrics&&) = delete;
8009e6c388aSLukasz Kazmierczak 
8019e6c388aSLukasz Kazmierczak     std::string id;
8029e6c388aSLukasz Kazmierczak     std::map<std::string, std::string> metricPropertyToDbusPaths;
8039e6c388aSLukasz Kazmierczak 
8049e6c388aSLukasz Kazmierczak     void insert(const std::map<std::string, std::string>&
8059e6c388aSLukasz Kazmierczak                     additionalMetricPropertyToDbusPaths)
8069e6c388aSLukasz Kazmierczak     {
8079e6c388aSLukasz Kazmierczak         metricPropertyToDbusPaths.insert(
8089e6c388aSLukasz Kazmierczak             additionalMetricPropertyToDbusPaths.begin(),
8099e6c388aSLukasz Kazmierczak             additionalMetricPropertyToDbusPaths.end());
8109e6c388aSLukasz Kazmierczak     }
8119e6c388aSLukasz Kazmierczak 
8129e6c388aSLukasz Kazmierczak     void emplace(std::span<const std::tuple<sdbusplus::message::object_path,
8139e6c388aSLukasz Kazmierczak                                             std::string>>
8149e6c388aSLukasz Kazmierczak                      pathAndUri,
8159e6c388aSLukasz Kazmierczak                  const AddReportArgs::MetricArgs& metricArgs)
8169e6c388aSLukasz Kazmierczak     {
8179e6c388aSLukasz Kazmierczak         readingParamsUris.emplace_back(metricArgs.uris);
8189e6c388aSLukasz Kazmierczak         readingParams.emplace_back(
8199e6c388aSLukasz Kazmierczak             std::vector(pathAndUri.begin(), pathAndUri.end()),
8209e6c388aSLukasz Kazmierczak             metricArgs.collectionFunction, metricArgs.collectionTimeScope,
8219e6c388aSLukasz Kazmierczak             metricArgs.collectionDuration);
8229e6c388aSLukasz Kazmierczak     }
8239e6c388aSLukasz Kazmierczak 
8249e6c388aSLukasz Kazmierczak     void setReadingParams()
8259e6c388aSLukasz Kazmierczak     {
8269e6c388aSLukasz Kazmierczak         if (asyncResp->res.result() != boost::beast::http::status::ok)
8279e6c388aSLukasz Kazmierczak         {
8289e6c388aSLukasz Kazmierczak             return;
8299e6c388aSLukasz Kazmierczak         }
8309e6c388aSLukasz Kazmierczak 
8319e6c388aSLukasz Kazmierczak         for (size_t index = 0; index < readingParamsUris.size(); ++index)
8329e6c388aSLukasz Kazmierczak         {
8339e6c388aSLukasz Kazmierczak             std::span<const std::string> newUris = readingParamsUris[index];
8349e6c388aSLukasz Kazmierczak 
8359e6c388aSLukasz Kazmierczak             const std::optional<std::vector<
8369e6c388aSLukasz Kazmierczak                 std::tuple<sdbusplus::message::object_path, std::string>>>
8379e6c388aSLukasz Kazmierczak                 readingParam = sensorPathToUri(newUris);
8389e6c388aSLukasz Kazmierczak 
8399e6c388aSLukasz Kazmierczak             if (!readingParam)
8409e6c388aSLukasz Kazmierczak             {
8419e6c388aSLukasz Kazmierczak                 return;
8429e6c388aSLukasz Kazmierczak             }
8439e6c388aSLukasz Kazmierczak 
8449e6c388aSLukasz Kazmierczak             std::get<0>(readingParams[index]) = *readingParam;
8459e6c388aSLukasz Kazmierczak         }
8469e6c388aSLukasz Kazmierczak 
8479e6c388aSLukasz Kazmierczak         crow::connections::systemBus->async_method_call(
8489e6c388aSLukasz Kazmierczak             [asyncResp(this->asyncResp),
8499e6c388aSLukasz Kazmierczak              reportId = id](const boost::system::error_code& ec) {
8509e6c388aSLukasz Kazmierczak             if (!verifyCommonErrors(asyncResp->res, reportId, ec))
8519e6c388aSLukasz Kazmierczak             {
8529e6c388aSLukasz Kazmierczak                 return;
8539e6c388aSLukasz Kazmierczak             }
8549e6c388aSLukasz Kazmierczak         },
8559e6c388aSLukasz Kazmierczak             "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
8569e6c388aSLukasz Kazmierczak             "org.freedesktop.DBus.Properties", "Set",
8579e6c388aSLukasz Kazmierczak             "xyz.openbmc_project.Telemetry.Report", "ReadingParameters",
8589e6c388aSLukasz Kazmierczak             dbus::utility::DbusVariantType{readingParams});
8599e6c388aSLukasz Kazmierczak     }
8609e6c388aSLukasz Kazmierczak 
8619e6c388aSLukasz Kazmierczak   private:
8629e6c388aSLukasz Kazmierczak     std::optional<
8639e6c388aSLukasz Kazmierczak         std::vector<std::tuple<sdbusplus::message::object_path, std::string>>>
8649e6c388aSLukasz Kazmierczak         sensorPathToUri(std::span<const std::string> uris) const
8659e6c388aSLukasz Kazmierczak     {
8669e6c388aSLukasz Kazmierczak         std::vector<std::tuple<sdbusplus::message::object_path, std::string>>
8679e6c388aSLukasz Kazmierczak             result;
8689e6c388aSLukasz Kazmierczak 
8699e6c388aSLukasz Kazmierczak         for (const std::string& uri : uris)
8709e6c388aSLukasz Kazmierczak         {
8719e6c388aSLukasz Kazmierczak             auto it = metricPropertyToDbusPaths.find(uri);
8729e6c388aSLukasz Kazmierczak             if (it == metricPropertyToDbusPaths.end())
8739e6c388aSLukasz Kazmierczak             {
8749e6c388aSLukasz Kazmierczak                 messages::propertyValueNotInList(asyncResp->res, uri,
8759e6c388aSLukasz Kazmierczak                                                  "MetricProperties");
8769e6c388aSLukasz Kazmierczak                 return {};
8779e6c388aSLukasz Kazmierczak             }
8789e6c388aSLukasz Kazmierczak             result.emplace_back(it->second, uri);
8799e6c388aSLukasz Kazmierczak         }
8809e6c388aSLukasz Kazmierczak 
8819e6c388aSLukasz Kazmierczak         return result;
8829e6c388aSLukasz Kazmierczak     }
8839e6c388aSLukasz Kazmierczak 
8849e6c388aSLukasz Kazmierczak     const std::shared_ptr<bmcweb::AsyncResp> asyncResp;
8859e6c388aSLukasz Kazmierczak     std::vector<std::vector<std::string>> readingParamsUris;
88647f2934cSEd Tanous     ReadingParameters readingParams;
8879e6c388aSLukasz Kazmierczak };
8889e6c388aSLukasz Kazmierczak 
8899e6c388aSLukasz Kazmierczak inline void
8909e6c388aSLukasz Kazmierczak     setReportEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
8919e6c388aSLukasz Kazmierczak                      std::string_view id, bool enabled)
8929e6c388aSLukasz Kazmierczak {
8939e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
8949e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
8959e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
8969e6c388aSLukasz Kazmierczak         {
8979e6c388aSLukasz Kazmierczak             return;
8989e6c388aSLukasz Kazmierczak         }
8999e6c388aSLukasz Kazmierczak     },
9009e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9019e6c388aSLukasz Kazmierczak         "org.freedesktop.DBus.Properties", "Set",
9029e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "Enabled",
9039e6c388aSLukasz Kazmierczak         dbus::utility::DbusVariantType{enabled});
9049e6c388aSLukasz Kazmierczak }
9059e6c388aSLukasz Kazmierczak 
9069e6c388aSLukasz Kazmierczak inline void setReportTypeAndInterval(
9079e6c388aSLukasz Kazmierczak     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string_view id,
9089e6c388aSLukasz Kazmierczak     const std::string& reportingType, uint64_t recurrenceInterval)
9099e6c388aSLukasz Kazmierczak {
9109e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
9119e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
9129e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
9139e6c388aSLukasz Kazmierczak         {
9149e6c388aSLukasz Kazmierczak             return;
9159e6c388aSLukasz Kazmierczak         }
9169e6c388aSLukasz Kazmierczak     },
9179e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9189e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "SetReportingProperties",
9199e6c388aSLukasz Kazmierczak         reportingType, recurrenceInterval);
9209e6c388aSLukasz Kazmierczak }
9219e6c388aSLukasz Kazmierczak 
9229e6c388aSLukasz Kazmierczak inline void
9239e6c388aSLukasz Kazmierczak     setReportUpdates(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9249e6c388aSLukasz Kazmierczak                      std::string_view id, const std::string& reportUpdates)
9259e6c388aSLukasz Kazmierczak {
9269e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
9279e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
9289e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
9299e6c388aSLukasz Kazmierczak         {
9309e6c388aSLukasz Kazmierczak             return;
9319e6c388aSLukasz Kazmierczak         }
9329e6c388aSLukasz Kazmierczak     },
9339e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9349e6c388aSLukasz Kazmierczak         "org.freedesktop.DBus.Properties", "Set",
9359e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "ReportUpdates",
9369e6c388aSLukasz Kazmierczak         dbus::utility::DbusVariantType{reportUpdates});
9379e6c388aSLukasz Kazmierczak }
9389e6c388aSLukasz Kazmierczak 
9399e6c388aSLukasz Kazmierczak inline void
9409e6c388aSLukasz Kazmierczak     setReportActions(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
9419e6c388aSLukasz Kazmierczak                      std::string_view id,
9429e6c388aSLukasz Kazmierczak                      const std::vector<std::string>& dbusReportActions)
9439e6c388aSLukasz Kazmierczak {
9449e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
9459e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id)](const boost::system::error_code& ec) {
9469e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, id, ec))
9479e6c388aSLukasz Kazmierczak         {
9489e6c388aSLukasz Kazmierczak             return;
9499e6c388aSLukasz Kazmierczak         }
9509e6c388aSLukasz Kazmierczak     },
9519e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry", getDbusReportPath(id),
9529e6c388aSLukasz Kazmierczak         "org.freedesktop.DBus.Properties", "Set",
9539e6c388aSLukasz Kazmierczak         "xyz.openbmc_project.Telemetry.Report", "ReportActions",
9549e6c388aSLukasz Kazmierczak         dbus::utility::DbusVariantType{dbusReportActions});
9559e6c388aSLukasz Kazmierczak }
9569e6c388aSLukasz Kazmierczak 
9579e6c388aSLukasz Kazmierczak inline void
9589e6c388aSLukasz Kazmierczak     setReportMetrics(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
959b14f357fSEd Tanous                      std::string_view id,
960b14f357fSEd Tanous                      std::span<nlohmann::json::object_t> metrics)
9619e6c388aSLukasz Kazmierczak {
9629e6c388aSLukasz Kazmierczak     sdbusplus::asio::getAllProperties(
9639e6c388aSLukasz Kazmierczak         *crow::connections::systemBus, telemetry::service,
9649e6c388aSLukasz Kazmierczak         telemetry::getDbusReportPath(id), telemetry::reportInterface,
9659e6c388aSLukasz Kazmierczak         [asyncResp, id = std::string(id),
966b14f357fSEd Tanous          redfishMetrics = std::vector<nlohmann::json::object_t>(metrics.begin(),
9679e6c388aSLukasz Kazmierczak                                                                 metrics.end())](
9689e6c388aSLukasz Kazmierczak             boost::system::error_code ec,
9699e6c388aSLukasz Kazmierczak             const dbus::utility::DBusPropertiesMap& properties) mutable {
9709e6c388aSLukasz Kazmierczak         if (!redfish::telemetry::verifyCommonErrors(asyncResp->res, id, ec))
9719e6c388aSLukasz Kazmierczak         {
9729e6c388aSLukasz Kazmierczak             return;
9739e6c388aSLukasz Kazmierczak         }
9749e6c388aSLukasz Kazmierczak 
9759e6c388aSLukasz Kazmierczak         ReadingParameters readingParams;
9769e6c388aSLukasz Kazmierczak 
9779e6c388aSLukasz Kazmierczak         const bool success = sdbusplus::unpackPropertiesNoThrow(
9789e6c388aSLukasz Kazmierczak             dbus_utils::UnpackErrorPrinter(), properties, "ReadingParameters",
9799e6c388aSLukasz Kazmierczak             readingParams);
9809e6c388aSLukasz Kazmierczak 
9819e6c388aSLukasz Kazmierczak         if (!success)
9829e6c388aSLukasz Kazmierczak         {
9839e6c388aSLukasz Kazmierczak             messages::internalError(asyncResp->res);
9849e6c388aSLukasz Kazmierczak             return;
9859e6c388aSLukasz Kazmierczak         }
9869e6c388aSLukasz Kazmierczak 
9879e6c388aSLukasz Kazmierczak         auto updateMetricsReq = std::make_shared<UpdateMetrics>(id, asyncResp);
9889e6c388aSLukasz Kazmierczak 
9899e6c388aSLukasz Kazmierczak         boost::container::flat_set<std::pair<std::string, std::string>>
9909e6c388aSLukasz Kazmierczak             chassisSensors;
9919e6c388aSLukasz Kazmierczak 
9929e6c388aSLukasz Kazmierczak         size_t index = 0;
993b14f357fSEd Tanous         for (nlohmann::json::object_t& metric : redfishMetrics)
9949e6c388aSLukasz Kazmierczak         {
9959e6c388aSLukasz Kazmierczak             AddReportArgs::MetricArgs metricArgs;
9969e6c388aSLukasz Kazmierczak             std::vector<
9979e6c388aSLukasz Kazmierczak                 std::tuple<sdbusplus::message::object_path, std::string>>
9989e6c388aSLukasz Kazmierczak                 pathAndUri;
9999e6c388aSLukasz Kazmierczak 
10009e6c388aSLukasz Kazmierczak             if (index < readingParams.size())
10019e6c388aSLukasz Kazmierczak             {
10029e6c388aSLukasz Kazmierczak                 const ReadingParameters::value_type& existing =
10039e6c388aSLukasz Kazmierczak                     readingParams[index];
10049e6c388aSLukasz Kazmierczak 
10059e6c388aSLukasz Kazmierczak                 pathAndUri = std::get<0>(existing);
10069e6c388aSLukasz Kazmierczak                 metricArgs.collectionFunction = std::get<1>(existing);
10079e6c388aSLukasz Kazmierczak                 metricArgs.collectionTimeScope = std::get<2>(existing);
10089e6c388aSLukasz Kazmierczak                 metricArgs.collectionDuration = std::get<3>(existing);
10099e6c388aSLukasz Kazmierczak             }
10109e6c388aSLukasz Kazmierczak 
10119e6c388aSLukasz Kazmierczak             if (!getUserMetric(asyncResp->res, metric, metricArgs))
10129e6c388aSLukasz Kazmierczak             {
10139e6c388aSLukasz Kazmierczak                 return;
10149e6c388aSLukasz Kazmierczak             }
10159e6c388aSLukasz Kazmierczak 
10169e6c388aSLukasz Kazmierczak             std::optional<IncorrectMetricUri> error =
10179e6c388aSLukasz Kazmierczak                 getChassisSensorNode(metricArgs.uris, chassisSensors);
10189e6c388aSLukasz Kazmierczak 
10199e6c388aSLukasz Kazmierczak             if (error)
10209e6c388aSLukasz Kazmierczak             {
10219e6c388aSLukasz Kazmierczak                 messages::propertyValueIncorrect(
10229e6c388aSLukasz Kazmierczak                     asyncResp->res, error->uri,
10239e6c388aSLukasz Kazmierczak                     "MetricProperties/" + std::to_string(error->index));
10249e6c388aSLukasz Kazmierczak                 return;
10259e6c388aSLukasz Kazmierczak             }
10269e6c388aSLukasz Kazmierczak 
10279e6c388aSLukasz Kazmierczak             updateMetricsReq->emplace(pathAndUri, metricArgs);
10289e6c388aSLukasz Kazmierczak             index++;
10299e6c388aSLukasz Kazmierczak         }
10309e6c388aSLukasz Kazmierczak 
10319e6c388aSLukasz Kazmierczak         for (const auto& [chassis, sensorType] : chassisSensors)
10329e6c388aSLukasz Kazmierczak         {
10339e6c388aSLukasz Kazmierczak             retrieveUriToDbusMap(
10349e6c388aSLukasz Kazmierczak                 chassis, sensorType,
10359e6c388aSLukasz Kazmierczak                 [asyncResp, updateMetricsReq](
10369e6c388aSLukasz Kazmierczak                     const boost::beast::http::status status,
10379e6c388aSLukasz Kazmierczak                     const std::map<std::string, std::string>& uriToDbus) {
10389e6c388aSLukasz Kazmierczak                 if (status != boost::beast::http::status::ok)
10399e6c388aSLukasz Kazmierczak                 {
10409e6c388aSLukasz Kazmierczak                     BMCWEB_LOG_ERROR(
10419e6c388aSLukasz Kazmierczak                         "Failed to retrieve URI to dbus sensors map with err {}",
10429e6c388aSLukasz Kazmierczak                         static_cast<unsigned>(status));
10439e6c388aSLukasz Kazmierczak                     return;
10449e6c388aSLukasz Kazmierczak                 }
10459e6c388aSLukasz Kazmierczak                 updateMetricsReq->insert(uriToDbus);
10469e6c388aSLukasz Kazmierczak             });
10479e6c388aSLukasz Kazmierczak         }
10489e6c388aSLukasz Kazmierczak     });
10499e6c388aSLukasz Kazmierczak }
1050081ebf06SWludzik, Jozef 
10514220be3bSEd Tanous inline void handleMetricReportDefinitionCollectionHead(
10524220be3bSEd Tanous     App& app, const crow::Request& req,
10534220be3bSEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
10544220be3bSEd Tanous {
10554220be3bSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
10564220be3bSEd Tanous     {
10574220be3bSEd Tanous         return;
10584220be3bSEd Tanous     }
10594220be3bSEd Tanous     asyncResp->res.addHeader(
10604220be3bSEd Tanous         boost::beast::http::field::link,
10614220be3bSEd Tanous         "</redfish/v1/JsonSchemas/MetricReportDefinitionCollection/MetricReportDefinitionCollection.json>; rel=describedby");
10624220be3bSEd Tanous }
10634220be3bSEd Tanous 
10644220be3bSEd Tanous inline void handleMetricReportDefinitionCollectionGet(
1065fc0edbe3SEd Tanous     App& app, const crow::Request& req,
1066fc0edbe3SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1067fc0edbe3SEd Tanous {
1068fc0edbe3SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1069fc0edbe3SEd Tanous     {
1070fc0edbe3SEd Tanous         return;
1071fc0edbe3SEd Tanous     }
10729e6c388aSLukasz Kazmierczak     asyncResp->res.addHeader(
10739e6c388aSLukasz Kazmierczak         boost::beast::http::field::link,
10749e6c388aSLukasz Kazmierczak         "</redfish/v1/JsonSchemas/MetricReportDefinition/MetricReportDefinition.json>; rel=describedby");
1075fc0edbe3SEd Tanous 
1076fc0edbe3SEd Tanous     asyncResp->res.jsonValue["@odata.type"] =
1077fc0edbe3SEd Tanous         "#MetricReportDefinitionCollection."
1078fc0edbe3SEd Tanous         "MetricReportDefinitionCollection";
1079fc0edbe3SEd Tanous     asyncResp->res.jsonValue["@odata.id"] =
1080fc0edbe3SEd Tanous         "/redfish/v1/TelemetryService/MetricReportDefinitions";
1081fc0edbe3SEd Tanous     asyncResp->res.jsonValue["Name"] = "Metric Definition Collection";
1082fc0edbe3SEd Tanous     constexpr std::array<std::string_view, 1> interfaces{
1083fc0edbe3SEd Tanous         telemetry::reportInterface};
1084fc0edbe3SEd Tanous     collection_util::getCollectionMembers(
1085fc0edbe3SEd Tanous         asyncResp,
1086fc0edbe3SEd Tanous         boost::urls::url(
1087fc0edbe3SEd Tanous             "/redfish/v1/TelemetryService/MetricReportDefinitions"),
1088fc0edbe3SEd Tanous         interfaces, "/xyz/openbmc_project/Telemetry/Reports/TelemetryService");
1089fc0edbe3SEd Tanous }
1090fc0edbe3SEd Tanous 
109186a5ac98SEd Tanous inline void
10929e6c388aSLukasz Kazmierczak     handleReportPatch(App& app, const crow::Request& req,
10939e6c388aSLukasz Kazmierczak                       const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
10949e6c388aSLukasz Kazmierczak                       std::string_view id)
10959e6c388aSLukasz Kazmierczak {
10969e6c388aSLukasz Kazmierczak     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
10979e6c388aSLukasz Kazmierczak     {
10989e6c388aSLukasz Kazmierczak         return;
10999e6c388aSLukasz Kazmierczak     }
11009e6c388aSLukasz Kazmierczak 
11019e6c388aSLukasz Kazmierczak     std::optional<std::string> reportingTypeStr;
11029e6c388aSLukasz Kazmierczak     std::optional<std::string> reportUpdatesStr;
11039e6c388aSLukasz Kazmierczak     std::optional<bool> metricReportDefinitionEnabled;
1104b14f357fSEd Tanous     std::optional<std::vector<nlohmann::json::object_t>> metrics;
11059e6c388aSLukasz Kazmierczak     std::optional<std::vector<std::string>> reportActionsStr;
1106b14f357fSEd Tanous     std::optional<std::string> scheduleDurationStr;
11079e6c388aSLukasz Kazmierczak 
11089e6c388aSLukasz Kazmierczak     if (!json_util::readJsonPatch(
11099e6c388aSLukasz Kazmierczak             req, asyncResp->res, "Metrics", metrics,
11109e6c388aSLukasz Kazmierczak             "MetricReportDefinitionType", reportingTypeStr, "ReportUpdates",
1111b14f357fSEd Tanous             reportUpdatesStr, "ReportActions", reportActionsStr,
1112b14f357fSEd Tanous             "Schedule/RecurrenceInterval", scheduleDurationStr,
1113b14f357fSEd Tanous             "MetricReportDefinitionEnabled", metricReportDefinitionEnabled))
11149e6c388aSLukasz Kazmierczak     {
11159e6c388aSLukasz Kazmierczak         return;
11169e6c388aSLukasz Kazmierczak     }
11179e6c388aSLukasz Kazmierczak 
11189e6c388aSLukasz Kazmierczak     if (metricReportDefinitionEnabled)
11199e6c388aSLukasz Kazmierczak     {
11209e6c388aSLukasz Kazmierczak         setReportEnabled(asyncResp, id, *metricReportDefinitionEnabled);
11219e6c388aSLukasz Kazmierczak     }
11229e6c388aSLukasz Kazmierczak 
11239e6c388aSLukasz Kazmierczak     if (reportUpdatesStr)
11249e6c388aSLukasz Kazmierczak     {
11259e6c388aSLukasz Kazmierczak         std::string dbusReportUpdates = toDbusReportUpdates(*reportUpdatesStr);
11269e6c388aSLukasz Kazmierczak         if (dbusReportUpdates.empty())
11279e6c388aSLukasz Kazmierczak         {
11289e6c388aSLukasz Kazmierczak             messages::propertyValueNotInList(asyncResp->res, *reportUpdatesStr,
11299e6c388aSLukasz Kazmierczak                                              "ReportUpdates");
11309e6c388aSLukasz Kazmierczak             return;
11319e6c388aSLukasz Kazmierczak         }
11329e6c388aSLukasz Kazmierczak         setReportUpdates(asyncResp, id, dbusReportUpdates);
11339e6c388aSLukasz Kazmierczak     }
11349e6c388aSLukasz Kazmierczak 
11359e6c388aSLukasz Kazmierczak     if (reportActionsStr)
11369e6c388aSLukasz Kazmierczak     {
11379e6c388aSLukasz Kazmierczak         std::vector<std::string> dbusReportActions;
11389e6c388aSLukasz Kazmierczak         if (!toDbusReportActions(asyncResp->res, *reportActionsStr,
11399e6c388aSLukasz Kazmierczak                                  dbusReportActions))
11409e6c388aSLukasz Kazmierczak         {
11419e6c388aSLukasz Kazmierczak             return;
11429e6c388aSLukasz Kazmierczak         }
11439e6c388aSLukasz Kazmierczak         setReportActions(asyncResp, id, dbusReportActions);
11449e6c388aSLukasz Kazmierczak     }
11459e6c388aSLukasz Kazmierczak 
1146b14f357fSEd Tanous     if (reportingTypeStr || scheduleDurationStr)
11479e6c388aSLukasz Kazmierczak     {
11489e6c388aSLukasz Kazmierczak         std::string dbusReportingType;
11499e6c388aSLukasz Kazmierczak         if (reportingTypeStr)
11509e6c388aSLukasz Kazmierczak         {
11519e6c388aSLukasz Kazmierczak             dbusReportingType = toDbusReportingType(*reportingTypeStr);
11529e6c388aSLukasz Kazmierczak             if (dbusReportingType.empty())
11539e6c388aSLukasz Kazmierczak             {
11549e6c388aSLukasz Kazmierczak                 messages::propertyValueNotInList(asyncResp->res,
11559e6c388aSLukasz Kazmierczak                                                  *reportingTypeStr,
11569e6c388aSLukasz Kazmierczak                                                  "MetricReportDefinitionType");
11579e6c388aSLukasz Kazmierczak                 return;
11589e6c388aSLukasz Kazmierczak             }
11599e6c388aSLukasz Kazmierczak         }
11609e6c388aSLukasz Kazmierczak 
11619e6c388aSLukasz Kazmierczak         uint64_t recurrenceInterval = std::numeric_limits<uint64_t>::max();
1162b14f357fSEd Tanous         if (scheduleDurationStr)
11639e6c388aSLukasz Kazmierczak         {
11649e6c388aSLukasz Kazmierczak             std::optional<std::chrono::milliseconds> durationNum =
1165b14f357fSEd Tanous                 time_utils::fromDurationString(*scheduleDurationStr);
11669e6c388aSLukasz Kazmierczak             if (!durationNum || durationNum->count() < 0)
11679e6c388aSLukasz Kazmierczak             {
11689e6c388aSLukasz Kazmierczak                 messages::propertyValueIncorrect(
1169b14f357fSEd Tanous                     asyncResp->res, "RecurrenceInterval", *scheduleDurationStr);
11709e6c388aSLukasz Kazmierczak                 return;
11719e6c388aSLukasz Kazmierczak             }
11729e6c388aSLukasz Kazmierczak 
11739e6c388aSLukasz Kazmierczak             recurrenceInterval = static_cast<uint64_t>(durationNum->count());
11749e6c388aSLukasz Kazmierczak         }
11759e6c388aSLukasz Kazmierczak 
11769e6c388aSLukasz Kazmierczak         setReportTypeAndInterval(asyncResp, id, dbusReportingType,
11779e6c388aSLukasz Kazmierczak                                  recurrenceInterval);
11789e6c388aSLukasz Kazmierczak     }
11799e6c388aSLukasz Kazmierczak 
11809e6c388aSLukasz Kazmierczak     if (metrics)
11819e6c388aSLukasz Kazmierczak     {
11829e6c388aSLukasz Kazmierczak         setReportMetrics(asyncResp, id, *metrics);
11839e6c388aSLukasz Kazmierczak     }
11849e6c388aSLukasz Kazmierczak }
11859e6c388aSLukasz Kazmierczak 
11869e6c388aSLukasz Kazmierczak inline void
11879e6c388aSLukasz Kazmierczak     handleReportDelete(App& app, const crow::Request& req,
11889e6c388aSLukasz Kazmierczak                        const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
11899e6c388aSLukasz Kazmierczak                        std::string_view id)
11909e6c388aSLukasz Kazmierczak {
11919e6c388aSLukasz Kazmierczak     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
11929e6c388aSLukasz Kazmierczak     {
11939e6c388aSLukasz Kazmierczak         return;
11949e6c388aSLukasz Kazmierczak     }
11959e6c388aSLukasz Kazmierczak 
11969e6c388aSLukasz Kazmierczak     const std::string reportPath = getDbusReportPath(id);
11979e6c388aSLukasz Kazmierczak 
11989e6c388aSLukasz Kazmierczak     crow::connections::systemBus->async_method_call(
11999e6c388aSLukasz Kazmierczak         [asyncResp,
12009e6c388aSLukasz Kazmierczak          reportId = std::string(id)](const boost::system::error_code& ec) {
12019e6c388aSLukasz Kazmierczak         if (!verifyCommonErrors(asyncResp->res, reportId, ec))
12029e6c388aSLukasz Kazmierczak         {
12039e6c388aSLukasz Kazmierczak             return;
12049e6c388aSLukasz Kazmierczak         }
12059e6c388aSLukasz Kazmierczak         asyncResp->res.result(boost::beast::http::status::no_content);
12069e6c388aSLukasz Kazmierczak     },
12079e6c388aSLukasz Kazmierczak         service, reportPath, "xyz.openbmc_project.Object.Delete", "Delete");
12089e6c388aSLukasz Kazmierczak }
12099e6c388aSLukasz Kazmierczak } // namespace telemetry
12109e6c388aSLukasz Kazmierczak 
121195bdb5f0SEd Tanous inline void afterRetrieveUriToDbusMap(
121295bdb5f0SEd Tanous     const std::shared_ptr<bmcweb::AsyncResp>& /*asyncResp*/,
121395bdb5f0SEd Tanous     const std::shared_ptr<telemetry::AddReport>& addReportReq,
121495bdb5f0SEd Tanous     const boost::beast::http::status status,
121595bdb5f0SEd Tanous     const std::map<std::string, std::string>& uriToDbus)
121695bdb5f0SEd Tanous {
121795bdb5f0SEd Tanous     if (status != boost::beast::http::status::ok)
121895bdb5f0SEd Tanous     {
121995bdb5f0SEd Tanous         BMCWEB_LOG_ERROR(
122095bdb5f0SEd Tanous             "Failed to retrieve URI to dbus sensors map with err {}",
122195bdb5f0SEd Tanous             static_cast<unsigned>(status));
122295bdb5f0SEd Tanous         return;
122395bdb5f0SEd Tanous     }
122495bdb5f0SEd Tanous     addReportReq->insert(uriToDbus);
122595bdb5f0SEd Tanous }
122695bdb5f0SEd Tanous 
12279e6c388aSLukasz Kazmierczak inline void handleMetricReportDefinitionsPost(
12289e6c388aSLukasz Kazmierczak     App& app, const crow::Request& req,
12299e6c388aSLukasz Kazmierczak     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
12309e6c388aSLukasz Kazmierczak {
12319e6c388aSLukasz Kazmierczak     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
12329e6c388aSLukasz Kazmierczak     {
12339e6c388aSLukasz Kazmierczak         return;
12349e6c388aSLukasz Kazmierczak     }
12359e6c388aSLukasz Kazmierczak 
12369e6c388aSLukasz Kazmierczak     telemetry::AddReportArgs args;
12379e6c388aSLukasz Kazmierczak     if (!telemetry::getUserParameters(asyncResp->res, req, args))
12389e6c388aSLukasz Kazmierczak     {
12399e6c388aSLukasz Kazmierczak         return;
12409e6c388aSLukasz Kazmierczak     }
12419e6c388aSLukasz Kazmierczak 
12429e6c388aSLukasz Kazmierczak     boost::container::flat_set<std::pair<std::string, std::string>>
12439e6c388aSLukasz Kazmierczak         chassisSensors;
12449e6c388aSLukasz Kazmierczak     if (!telemetry::getChassisSensorNodeFromMetrics(asyncResp, args.metrics,
12459e6c388aSLukasz Kazmierczak                                                     chassisSensors))
12469e6c388aSLukasz Kazmierczak     {
12479e6c388aSLukasz Kazmierczak         return;
12489e6c388aSLukasz Kazmierczak     }
12499e6c388aSLukasz Kazmierczak 
12509e6c388aSLukasz Kazmierczak     auto addReportReq = std::make_shared<telemetry::AddReport>(std::move(args),
12519e6c388aSLukasz Kazmierczak                                                                asyncResp);
12529e6c388aSLukasz Kazmierczak     for (const auto& [chassis, sensorType] : chassisSensors)
12539e6c388aSLukasz Kazmierczak     {
125495bdb5f0SEd Tanous         retrieveUriToDbusMap(chassis, sensorType,
125595bdb5f0SEd Tanous                              std::bind_front(afterRetrieveUriToDbusMap,
125695bdb5f0SEd Tanous                                              asyncResp, addReportReq));
12579e6c388aSLukasz Kazmierczak     }
12589e6c388aSLukasz Kazmierczak }
12599e6c388aSLukasz Kazmierczak 
12609e6c388aSLukasz Kazmierczak inline void
12614220be3bSEd Tanous     handleMetricReportHead(App& app, const crow::Request& req,
12624220be3bSEd Tanous                            const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
12634220be3bSEd Tanous                            const std::string& /*id*/)
12644220be3bSEd Tanous {
12654220be3bSEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
12664220be3bSEd Tanous     {
12674220be3bSEd Tanous         return;
12684220be3bSEd Tanous     }
12694220be3bSEd Tanous     asyncResp->res.addHeader(
12704220be3bSEd Tanous         boost::beast::http::field::link,
12714220be3bSEd Tanous         "</redfish/v1/JsonSchemas/MetricReport/MetricReport.json>; rel=describedby");
12724220be3bSEd Tanous }
12734220be3bSEd Tanous 
12744220be3bSEd Tanous inline void
127586a5ac98SEd Tanous     handleMetricReportGet(App& app, const crow::Request& req,
127686a5ac98SEd Tanous                           const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
127786a5ac98SEd Tanous                           const std::string& id)
127886a5ac98SEd Tanous {
127986a5ac98SEd Tanous     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
128086a5ac98SEd Tanous     {
128186a5ac98SEd Tanous         return;
128286a5ac98SEd Tanous     }
12834220be3bSEd Tanous     asyncResp->res.addHeader(
12844220be3bSEd Tanous         boost::beast::http::field::link,
12854220be3bSEd Tanous         "</redfish/v1/JsonSchemas/MetricReport/MetricReport.json>; rel=describedby");
128686a5ac98SEd Tanous 
128786a5ac98SEd Tanous     sdbusplus::asio::getAllProperties(
128886a5ac98SEd Tanous         *crow::connections::systemBus, telemetry::service,
128986a5ac98SEd Tanous         telemetry::getDbusReportPath(id), telemetry::reportInterface,
129086a5ac98SEd Tanous         [asyncResp, id](const boost::system::error_code& ec,
129186a5ac98SEd Tanous                         const dbus::utility::DBusPropertiesMap& properties) {
12929e6c388aSLukasz Kazmierczak         if (!redfish::telemetry::verifyCommonErrors(asyncResp->res, id, ec))
129386a5ac98SEd Tanous         {
129486a5ac98SEd Tanous             return;
129586a5ac98SEd Tanous         }
129686a5ac98SEd Tanous 
129786a5ac98SEd Tanous         telemetry::fillReportDefinition(asyncResp, id, properties);
129886a5ac98SEd Tanous     });
129986a5ac98SEd Tanous }
130086a5ac98SEd Tanous 
1301dd1c4a9cSSzymon Dompke inline void handleMetricReportDelete(
1302dd1c4a9cSSzymon Dompke     App& app, const crow::Request& req,
1303dd1c4a9cSSzymon Dompke     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id)
1304dd1c4a9cSSzymon Dompke 
1305dd1c4a9cSSzymon Dompke {
1306dd1c4a9cSSzymon Dompke     if (!redfish::setUpRedfishRoute(app, req, asyncResp))
1307dd1c4a9cSSzymon Dompke     {
1308dd1c4a9cSSzymon Dompke         return;
1309dd1c4a9cSSzymon Dompke     }
1310dd1c4a9cSSzymon Dompke 
1311dd1c4a9cSSzymon Dompke     const std::string reportPath = telemetry::getDbusReportPath(id);
1312dd1c4a9cSSzymon Dompke 
1313dd1c4a9cSSzymon Dompke     crow::connections::systemBus->async_method_call(
1314dd1c4a9cSSzymon Dompke         [asyncResp, id](const boost::system::error_code& ec) {
1315dd1c4a9cSSzymon Dompke         /*
1316dd1c4a9cSSzymon Dompke          * boost::system::errc and std::errc are missing value
1317dd1c4a9cSSzymon Dompke          * for EBADR error that is defined in Linux.
1318dd1c4a9cSSzymon Dompke          */
1319dd1c4a9cSSzymon Dompke         if (ec.value() == EBADR)
1320dd1c4a9cSSzymon Dompke         {
1321dd1c4a9cSSzymon Dompke             messages::resourceNotFound(asyncResp->res, "MetricReportDefinition",
1322dd1c4a9cSSzymon Dompke                                        id);
1323dd1c4a9cSSzymon Dompke             return;
1324dd1c4a9cSSzymon Dompke         }
1325dd1c4a9cSSzymon Dompke 
1326dd1c4a9cSSzymon Dompke         if (ec)
1327dd1c4a9cSSzymon Dompke         {
132862598e31SEd Tanous             BMCWEB_LOG_ERROR("respHandler DBus error {}", ec);
1329dd1c4a9cSSzymon Dompke             messages::internalError(asyncResp->res);
1330dd1c4a9cSSzymon Dompke             return;
1331dd1c4a9cSSzymon Dompke         }
1332dd1c4a9cSSzymon Dompke 
1333dd1c4a9cSSzymon Dompke         asyncResp->res.result(boost::beast::http::status::no_content);
1334dd1c4a9cSSzymon Dompke     },
1335dd1c4a9cSSzymon Dompke         telemetry::service, reportPath, "xyz.openbmc_project.Object.Delete",
1336dd1c4a9cSSzymon Dompke         "Delete");
1337dd1c4a9cSSzymon Dompke }
1338dd1c4a9cSSzymon Dompke 
13397e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinitionCollection(App& app)
1340081ebf06SWludzik, Jozef {
13417e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
13424220be3bSEd Tanous         .privileges(redfish::privileges::headMetricReportDefinitionCollection)
13434220be3bSEd Tanous         .methods(boost::beast::http::verb::head)(std::bind_front(
13449e6c388aSLukasz Kazmierczak             telemetry::handleMetricReportDefinitionCollectionHead,
13459e6c388aSLukasz Kazmierczak             std::ref(app)));
13464220be3bSEd Tanous 
13474220be3bSEd Tanous     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
1348ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReportDefinitionCollection)
13494220be3bSEd Tanous         .methods(boost::beast::http::verb::get)(std::bind_front(
13509e6c388aSLukasz Kazmierczak             telemetry::handleMetricReportDefinitionCollectionGet,
13519e6c388aSLukasz Kazmierczak             std::ref(app)));
13524dbb8aeaSWludzik, Jozef 
13537e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app, "/redfish/v1/TelemetryService/MetricReportDefinitions/")
1354ed398213SEd Tanous         .privileges(redfish::privileges::postMetricReportDefinitionCollection)
1355002d39b4SEd Tanous         .methods(boost::beast::http::verb::post)(
13569e6c388aSLukasz Kazmierczak             std::bind_front(handleMetricReportDefinitionsPost, std::ref(app)));
1357081ebf06SWludzik, Jozef }
1358081ebf06SWludzik, Jozef 
13597e860f15SJohn Edward Broadbent inline void requestRoutesMetricReportDefinition(App& app)
1360081ebf06SWludzik, Jozef {
13617e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
13627e860f15SJohn Edward Broadbent                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
1363ed398213SEd Tanous         .privileges(redfish::privileges::getMetricReportDefinition)
13644220be3bSEd Tanous         .methods(boost::beast::http::verb::head)(
13654220be3bSEd Tanous             std::bind_front(handleMetricReportHead, std::ref(app)));
13664220be3bSEd Tanous 
13674220be3bSEd Tanous     BMCWEB_ROUTE(app,
13684220be3bSEd Tanous                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
13694220be3bSEd Tanous         .privileges(redfish::privileges::getMetricReportDefinition)
13707e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::get)(
137186a5ac98SEd Tanous             std::bind_front(handleMetricReportGet, std::ref(app)));
1372479e899dSKrzysztof Grobelny 
13737e860f15SJohn Edward Broadbent     BMCWEB_ROUTE(app,
13747e860f15SJohn Edward Broadbent                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
13759e6c388aSLukasz Kazmierczak         .privileges(redfish::privileges::deleteMetricReportDefinition)
13767e860f15SJohn Edward Broadbent         .methods(boost::beast::http::verb::delete_)(
1377dd1c4a9cSSzymon Dompke             std::bind_front(handleMetricReportDelete, std::ref(app)));
13789e6c388aSLukasz Kazmierczak 
13799e6c388aSLukasz Kazmierczak     BMCWEB_ROUTE(app,
13809e6c388aSLukasz Kazmierczak                  "/redfish/v1/TelemetryService/MetricReportDefinitions/<str>/")
13819e6c388aSLukasz Kazmierczak         .privileges(redfish::privileges::patchMetricReportDefinition)
13829e6c388aSLukasz Kazmierczak         .methods(boost::beast::http::verb::patch)(
13839e6c388aSLukasz Kazmierczak             std::bind_front(telemetry::handleReportPatch, std::ref(app)));
13844dbb8aeaSWludzik, Jozef }
1385081ebf06SWludzik, Jozef } // namespace redfish
1386