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