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